夏令时(DST)切换日的乔达时间getSecondOfDay [英] Joda Time getSecondOfDay on DST switch day

查看:411
本文介绍了夏令时(DST)切换日的乔达时间getSecondOfDay的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我试图从DST转换日午夜开始获取秒数时,我从Joda Time得到了奇怪的行为。

I'm getting strange behavior from Joda Time when trying to get the seconds since midnight on a DST switch day.

我的代码:

public static void main(String[] args) {

    DateTimeZone timeZone = DateTimeZone.getDefault();
    System.out.println(timeZone);

    DateTimeFormatter dateFormatter = DateTimeFormat.shortDate();
    DateTimeFormatter dateTimeFormatter = DateTimeFormat.fullDateTime();
    LocalDate date = new LocalDate(2016, 10, 29);
    for (int i=0; i<3; i++) {

        System.out.println();
        System.out.println(dateFormatter.print(date) + ":");

        {
            DateTime instant = new DateTime(date.getYear(), date.getMonthOfYear(), date.getDayOfMonth(), 1, 0, 0, timeZone);
            System.out.println(dateTimeFormatter.print(instant) + " // " + instant.getSecondOfDay() + " // " + instant.getZone().getOffset(instant));
        }

        {
            DateTime instant = new DateTime(date.getYear(), date.getMonthOfYear(), date.getDayOfMonth(), 10, 0, 0, timeZone);
            System.out.println(dateTimeFormatter.print(instant) + " // " + instant.getSecondOfDay() + " // " + instant.getZone().getOffset(instant));
        }

        date = date.plusDays(1);
    }
}

输出:

Europe/Berlin

29.10.16:
Samstag, 29. Oktober 2016 01:00 Uhr MESZ // 3600 // 7200000
Samstag, 29. Oktober 2016 10:00 Uhr MESZ // 36000 // 7200000

30.10.16:
Sonntag, 30. Oktober 2016 01:00 Uhr MESZ // 3600 // 7200000
Sonntag, 30. Oktober 2016 10:00 Uhr MEZ // 36000 // 3600000

31.10.16:
Montag, 31. Oktober 2016 01:00 Uhr MEZ // 3600 // 3600000
Montag, 31. Oktober 2016 10:00 Uhr MEZ // 36000 // 3600000

(德语翻译:MEZ = CET,MESZ = CEST)

(translation from German: MEZ = CET, MESZ = CEST)

如您所见,DST转换日是10月30日。切换发生在2到3 AM之间。如果我没记错的话,夏令时为UTC + 2,而冬令时为UTC + 1,因此在凌晨3点,时钟会回到2 AM。

As you can see, Oct 30 is the DST switch day. The switch occurs between 2 and 3 AM. If I'm not mistaken, summer time is UTC+2 and winter time is UTC+1, so at 3 AM, clocks are turned back to 2 AM.

现在这显然暗示了2-3的重叠,但是我的测试使用的是1 AM和10 AM,这应该是明确的。我希望CEST的10月30日凌晨1点是午夜以来的3600秒,CET的10月30日10 AM凌晨点是午夜(11小时)以来的39600秒。但是getSecondOfDay()从午夜开始返回10个小时。

Now this obviously implies an overlap for 2-3, but my test uses 1 AM and 10 AM, which should be unambiguous. I'd expect the instant at Oct 30, 1 AM CEST to be 3600 seconds since midnight, and the instant at Oct 30, 10 AM CET to be 39600 seconds since midnight (11 hours). But getSecondOfDay() returns 10 hours since midnight.

我能想象的唯一含义(除了一个愚蠢的错误)是getSecondOfDay()实际上并没有返回自午夜以来的秒数,而是其他东西。但是,我在网上找到的每个示例似乎都暗示它确实返回自午夜以来的秒数。我也没有与DST相关的午夜重新定义。

The only implication I could imagine (besides a stupid error) is that getSecondOfDay() does not actually return the seconds since midnight, but something else. However, every example I found on the net seems to imply that it does return the number of seconds since midnight. There's no DST-related redefinition of "midnight" that I know of, either.

为什么会得到这些结果?
在这种情况下,getSecondOfDay()是什么意思?
我应该怎么做才能获得自午夜以来的秒数?

Why do I get these results? What is getSecondOfDay() meant to do in this situation? What else should I do to get the number of seconds since midnight?

推荐答案

字段SECOND_OF_DAY为这意味着,它不会计算自午夜以来的实际经过的SI或POSIX秒,而仅代表总持续24小时/每天晚上循环执行罢工,而不考虑任何DST问题。或另一种描述:假设该字段显示秒针在钟面上的位置。

The field SECOND_OF_DAY is inherently based on the local timeline. This means, it does not count the physically elapsed SI- or POSIX-seconds since midnight but only represents the nominal count of clock strikes as displayed on a wall clock which always has 24 hours/strikes per day-night-cycle ignoring any DST-issue. Or another description: Just imagine that this field displays the position of the second hand on the clock face.

但是您可以用另一种方法确定实际经过的秒数。类 DateTime 是一个瞬间,因此您可以首先确定午夜的瞬间,然后确定第二个瞬间,例如上午10点。然后应用以下表达式:

But you can determine the physically elapsed seconds in another way. The class DateTime is an instant, so you can first determine the instant for midnight and then the second instant for let's say at 10 AM. Then you apply this expression:

int elapsedSecondsSinceMidnight =
  Seconds.secondsBetween(instantMidnight, instant10AM).getSeconds();

请注意,如果本地时间确实如此,Joda-Time有时会导致为本地午夜创建瞬间的异常由于DST开关不存在(例如在夏令时在巴西)。因此,请谨慎处理Joda-Time中的瞬间创建。

Note that Joda-Time sometimes causes an exception to create an instant for local midnight if this local time does not exist due to DST-switch (like in Brazil when moving to summer time). So please handle the creation of instants in Joda-Time with care.

这篇关于夏令时(DST)切换日的乔达时间getSecondOfDay的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆