【问题标题】:Calculating a time duration with Joda-Time使用 Joda-Time 计算持续时间
【发布时间】:2011-06-26 09:53:42
【问题描述】:

我正在尝试使用 Joda-Time 来了解两个时间点之间的持续时间,其中每个时间点都在其自己的本地时区中给出。

例如:

DateTime ny = new DateTime(2011, 2, 2, 7, 0, 0, 0, DateTimeZone.forID("America/New_York"));
DateTime la = new DateTime(2011, 2, 3, 10, 15, 0, 0, DateTimeZone.forID("America/Los_Angeles"));
DateTime utc1 = ny.withZone(DateTimeZone.UTC);
DateTime utc2 = la.withZone(DateTimeZone.UTC);        
Period period = new Period(utc1, utc2);

现在,我想知道这是否考虑到夏令时和闰年... 此外,使用“时期”是实现这一目标的正确 Joda-Time 方式吗? 谢谢;)

【问题讨论】:

    标签: java timezone jodatime dst leap-year


    【解决方案1】:

    您提供的代码可以工作并考虑时区,但您无需转换为 UTC。这段代码更简单并且做同样的事情(使用 Duration 而不是 Period):

    DateTime ny = new DateTime(2011, 2, 2, 7, 0, 0, 0, DateTimeZone.forID("America/New_York"));
    DateTime la = new DateTime(2011, 2, 3, 10, 15, 0, 0, DateTimeZone.forID("America/Los_Angeles"));
    Duration duration = new Interval(ny, la).toDuration();
    

    【讨论】:

      【解决方案2】:

      根据您的使用方式,上面的代码可能不是一个好主意。

      所有采用 int 表示年/月/日/小时等的 DateTime 构造函数都容易受到夏令时 (DST) 过渡期的影响,在这种情况下,Joda-time 将引发异常。因此,如果转换期间的时间可能是您的应用程序中的输入,它将失败:

      DateTime ny = new DateTime(2011, 3, 13, 2, 0, 0, 0, DateTimeZone.forID("America/New_York"));
      
      Exception in thread "main" java.lang.IllegalArgumentException: Illegal instant due to time zone offset transition: 2011-03-13T07:00:00.000
      at org.joda.time.chrono.ZonedChronology.localToUTC(ZonedChronology.java:143)
      at org.joda.time.chrono.ZonedChronology.getDateTimeMillis(ZonedChronology.java:119)
      at org.joda.time.chrono.AssembledChronology.getDateTimeMillis(AssembledChronology.java:133)
      at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:254)
      at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:223)
      at org.joda.time.DateTime.<init>(DateTime.java:264)
      

      同样,您将在秋季遇到另一个问题,因为在给定的时区中将有 2 * 2 点,因此无法确定参考哪个小时。 DateTime 方法 withHourOfday 和 withTime 容易受到相同问题的影响,并且会将日期时间解析为带有受 DST 影响的时区的字符串。

      可能的解决方法包括

      • 改为使用任何固定偏移时区(例如 UTC)实例化
      • 解析与具有 UTC 时区的字符串相同
      • 在本地时区(例如午夜)中实例化一个有效时间并使用 plusHours 向前移动直到所需时间
      • 有一个守卫(if 语句)来防止过渡日期的第二个小时
      • 捕获异常并检查下一次转换何时发生(使用 DateTimeZone.nextTransition),并相应地向后/向前移动

      【讨论】:

        猜你喜欢
        • 2015-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-14
        • 1970-01-01
        相关资源
        最近更新 更多