Java GregorianCalendar.toZonedDateTime()返回过去日期的不同日期

对于过去的某个日期,GregorianCalendar.toZonedDateTime()返回的日期是1天休息。

对于1893年4月2日,toZonedDateTime()返回相同的日期,对于1893年4月1日,ZonedDateTime向我显示1893年3月31日,并且“一年中的天”值也有所不同。在此“魔术”日期之前的日期始终存在偏移量。

以下是一些示例代码:

final GregorianCalendar gc = new GregorianCalendar(1893,1); // Set to 1st January 1893
for(int i = 1; i < 365; i++) {
    gc.set(Calendar.DAY_OF_YEAR,i); // Update day of year
    final ZonedDateTime zdt = gc.toZonedDateTime();

    System.out.println(String.format(
            "GC: %02d.%02d.%d (%d) -> ZDT: %02d.%02d.%d (%d)",gc.get(Calendar.DAY_OF_MONTH),gc.get(Calendar.MONTH) + 1,// "+1" is needed,because GregorianCalendar encodes January as 0.
            gc.get(Calendar.YEAR),gc.get(Calendar.DAY_OF_YEAR),zdt.getDayOfMonth(),zdt.getMonthValue(),zdt.getYear(),zdt.getDayOfYear()
            ));
}

运行代码时,您将获得输出

[...]
GC: 31.03.1893 (90) -> ZDT: 30.03.1893 (89)
GC: 01.04.1893 (91) -> ZDT: 31.03.1893 (90)
GC: 02.04.1893 (92) -> ZDT: 02.04.1893 (92)
GC: 03.04.1893 (93) -> ZDT: 03.04.1893 (93)
[...]

我在这里做什么错了?

提前感谢您的回答!

最好的问候, 马库斯

s173682752 回答:Java GregorianCalendar.toZonedDateTime()返回过去日期的不同日期

您的系统时区是什么?

我怀疑您可能在1893年4月1日观察到或观察到DST类型更改的语言环境。尝试在循环的每次迭代中打印出offset的{​​{1}}值

或者通过删除时区因子ZonedDateTime

可以收集更多信息

这似乎与柏林在该日期选择采用CET有关

  

欧洲的tzdata文件在整个德国仅包含一个区域Europe / Berlin。

     

由于以下几个原因,它不是最佳选择:

     

-柏林直到1893年才开始CET,比几个南部州晚。

https://mm.icann.org/pipermail/tz/2011-August/008736.html

,

来自JavaDocs of GregorianCalendar

  

public ZonedDateTime toZonedDateTime()

     

将此对象转换为ZonedDateTime,该时间表示与该GregorianCalendar在时间轴上的同一点。

     

由于该对象支持儒略日至格里高利安转换日期,而ZonedDateTime不支持,因此结果年,月和日可能具有不同的值。结果将代表ISO日历系统中的正确日期,也将与“修改儒略日”的值相同。

我认为这是一种非期望但预期的行为。

,

我怀疑这是GregorianCalendar中的错误。我以前见过Date中某些时区中1900年之前的错误。我认为ZonedDateTime和java.time中的其他类更可靠,更值得信赖。

柏林的偏移量为+0:53:28,直到1893年4月1日00:00为止。在第89年的某天(为示例起见),您的代码给出的ZonedDateTime为1893-03-29T23:53:28 + 00:53:28 [欧洲/柏林]提供正确的偏移量。但是您的GregorianCalendarZonedDateTime都代表1893-03-29T23:00:00Z(UTC)的时刻,因此GregorianCalendar似乎已假定偏移量为+01:00相反,这是错误的。转换正确地转换了时刻(正确地转换了时区),因此正确地转换了各个日期和时间字段。

来源:要获取直到1893年的柏林补偿,请访问timeanddate.com上的Time Zone in Berlin,Germany。在“柏林多年来的时间变化”下的右上角下拉列表中,选择“ 1850 — 1899”。在1850-92年间,您将看到“无变化,整个时间UTC +0:53:28小时”,以及1893年4月1日00:00更改为CET / UTC +1。

这是我在您的循环中尝试过的操作:

    System.out.println(gc.getTimeZone().getID());
    System.out.println(gc.getTime());
    System.out.println(Instant.ofEpochMilli(gc.getTimeInMillis()));
    System.out.println();

    final ZonedDateTime zdt = gc.toZonedDateTime();

    System.out.println(zdt);
    System.out.println(zdt.toInstant());

年份(i)89的输出为:

Europe/Berlin
Thu Mar 30 00:00:00 CET 1893
1893-03-29T23:00:00Z

1893-03-29T23:53:28+00:53:28[Europe/Berlin]
1893-03-29T23:00:00Z
本文链接:https://www.f2er.com/3108923.html

大家都在问