【问题标题】:StackOverflowError using joda-time new Period(long)StackOverflowError 使用 joda-time new Period(long)
【发布时间】:2010-09-11 13:27:00
【问题描述】:

首先,抱歉这么长。我可能不需要所有代码,但想确定一下。

其次,我的实际问题是,我做错了什么,还是这是 joda-time 库中的错误?

我正在尝试使用 joda-time (1.6.1) 来计算,然后格式化持续时间。

我目前正在使用Period,这可能是错误的选择。如果是,请告诉我。 但是,即使这是错误的选择,我也很确定这不应该发生。

我正在使用毫秒初始化Period(将持续时间(以秒为单位)乘以 1000)。我正在使用Period,所以我可以格式化并打印它:

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());

我得到了下面的异常,并查看了源代码以确认循环。

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

期间(长):

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

super(long, PeriodType, Chronology):

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) 调用 getDefault(),它创建了循环:

 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);
}

【问题讨论】:

    标签: java stack-overflow jodatime


    【解决方案1】:

    由于循环部分仅在 joda 代码中,我会说这是一个错误。


    它已在trunk 上得到更正,并将在 V2.0 中提供。


    资源:

    【讨论】:

    • 为您提供了主干链接和错误报告的答案 - 我也找不到!
    【解决方案2】:

    看起来这是一个错误,因为它假定 user.timezone 属性已被设置。

    这就是在这种情况下绕过它的方法 - 只需确保正确设置 user.timezone 即可。可惜你不得不这样做。

    Joda Time 在很多地方都使用“null 表示默认值”——不幸的是,在我看来。我通常更喜欢“null 无效”。在Noda Time(Joda Time 到 .NET 的一个端口)中,我们试图摆脱很多此类事情 - 并首先防止默认时区如此普遍。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-06
      • 1970-01-01
      • 2021-03-18
      • 1970-01-01
      • 2014-01-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多