2010-09-11 4 views
2

D'abord, désolé, c'est trop long. Je n'ai probablement pas besoin de tout le code, mais je voulais être sûr. Deuxièmement, ma vraie question est la suivante: suis-je en train de faire quelque chose de mal, ou est-ce un bug dans la bibliothèque de joda-time? J'essaie d'utiliser joda-time (1.6.1) pour calculer, puis formater les durées. J'utilise actuellement Period, ce qui peut être le mauvais choix. S'il vous plaît laissez-moi savoir si c'est le cas. Cependant, même si c'est le mauvais choix, je suis sûr que cela ne devrait pas arriver.StackOverflowError utilisant joda-time new Period (long)

J'initialise un Period en utilisant des millisecondes (en multipliant une durée en secondes par 1000). J'utilise le Period donc je peux formater puis et l'imprimer:

long durationLong = durationSec * 1000; 
Period duration = new Period(durationLong); 

PeriodFormatter daysHoursMinutes = new PeriodFormatterBuilder() 
    .appendHours() 
    .appendSeparator(":") 
    .appendMinutes() 
    .appendSeparator(":") 
    .appendSeconds() 
    .toFormatter(); 

String formattedString = daysHoursMinutes.print(callDuration.normalizedStandard()); 

je reçois l'exception ci-dessous, et ont regardé à travers la source pour confirmer la boucle.

Caused by: java.lang.StackOverflowError 
    at java.util.Hashtable.get(Hashtable.java:274) 
    at java.util.Properties.getProperty(Properties.java:177) 
    at java.lang.System.getProperty(System.java:440) 
    at java.lang.System.getProperty(System.java:412) 
    at org.joda.time.DateTimeZone.getDefault(DateTimeZone.java:132) 
    at org.joda.time.DateTimeZone.forID(DateTimeZone.java:190) 
    at org.joda.time.DateTimeZone.getDefault(DateTimeZone.java:132) 
    at org.joda.time.DateTimeZone.forID(DateTimeZone.java:190) 

...snip (all the same)... 

    at org.joda.time.DateTimeZone.getDefault(DateTimeZone.java:132) 
    at org.joda.time.DateTimeZone.forID(DateTimeZone.java:190) 
    at org.joda.time.DateTimeZone.getDefault(DateTimeZone.java:132) 
    at org.joda.time.DateTimeZone.forID(Dat 

période (longue):

public Period(long duration) { 
    super(duration, null, null); 
} 

super (long, PeriodType, Chronologie):

protected BasePeriod(long duration, PeriodType type, Chronology chrono) { 
    super(); 
    type = checkPeriodType(type); 
    chrono = DateTimeUtils.getChronology(chrono); 
    iType = type; 
    iValues = chrono.get(this, duration); 
} 

DateTimeUtils.getChronology (chrono):

public static final Chronology getChronology(Chronology chrono) { 
    if (chrono == null) { 
     return ISOChronology.getInstance(); 
    } 
    return chrono; 
} 

ISOChronology .getInstance():

public static ISOChronology getInstance() { 
    return getInstance(DateTimeZone.getDefault()); 
} 

DateTimeZone.getDefault():

public static DateTimeZone getDefault() { 
    DateTimeZone zone = cDefault; 
    if (zone == null) { 
     synchronized(DateTimeZone.class) { 
      zone = cDefault; 
      if (zone == null) { 
       DateTimeZone temp = null; 
       try { 
        try { 
         temp = forID(System.getProperty("user.timezone")); 
        } catch (RuntimeException ex) { 
         // ignored 
        } 
        if (temp == null) { 
         temp = forTimeZone(TimeZone.getDefault()); 
        } 
       } catch (IllegalArgumentException ex) { 
        // ignored 
       } 
       if (temp == null) { 
        temp = UTC; 
       } 
       cDefault = zone = temp; 
      } 
     } 
    } 
    return zone; 
} 

FORID (String) appelle getDefault(), qui crée la boucle:

public static DateTimeZone forID(String id) { 
    if (id == null) { 
     return getDefault(); 
    } 
    if (id.equals("UTC")) { 
     return DateTimeZone.UTC; 
    } 
    DateTimeZone zone = cProvider.getZone(id); 
    if (zone != null) { 
     return zone; 
    } 
    if (id.startsWith("+") || id.startsWith("-")) { 
     int offset = parseOffset(id); 
     if (offset == 0L) { 
      return DateTimeZone.UTC; 
     } else { 
      id = printOffset(offset); 
      return fixedOffsetZone(id, offset); 
     } 
    } 
    throw new IllegalArgumentException("The datetime zone id is not recognised: " + id); 
} 

Répondre

5

Comme la partie en boucle est que dans le joda code, je dirais que c'est un bug.


Il a été corrigé sur le trunk et sera disponible en V2.0.


Ressources:

+0

Vous donne la réponse pour le lien au rapport de tronc et de bogue - je n'ai pas pu trouver non plus! – cofiem

+0

Voir la version v1.6.2 – JodaStephen

3

On dirait que c'est un bug en ce qu'elle suppose la propriété user.timezone aura été fixée.

C'est le moyen de contourner le problème dans ce cas - assurez-vous simplement que user.timezone est correctement défini. C'est dommage que vous ayez à le faire.

Joda Time utilise "null signifie par défaut" dans beaucoup d'endroits - malheureusement, à mon avis. Je préfère "null est invalide" habituellement.Dans Noda Time (un port de Joda Time vers .NET), nous essayons de nous débarrasser de beaucoup de ce genre de chose - tout en empêchant le fuseau horaire par défaut d'être aussi répandu en premier lieu.

+0

+ 1 pour la suggestion de la façon de le contourner. – cofiem

Questions connexes