对于过去的某个日期,GregorianCalendar.toZonedDateTime()返回的日期是1天休息。
对于1893年4月2日,toZonedDateTime()返回相同的日期,对于1893年4月1日,ZonedDateTime向我显示1893年3月31日,并且“一年中的天”值也有所不同。在此“魔术”日期之前的日期始终存在偏移量。
以下是一些示例代码:
final GregorianCalendar gc = new GregorianCalendar(1893, 0, 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)
[...]
我在这里做什么错了?
提前感谢您的回答!
最好的问候, 马库斯
答案 0 :(得分:3)
您的系统时区是什么?
我怀疑您可能在1893年4月1日观察到或观察到DST类型更改的语言环境。尝试在循环的每次迭代中打印出offset
的{{1}}值
或者通过删除时区因子ZonedDateTime
这似乎与柏林在该日期选择采用CET有关
欧洲的tzdata文件在整个德国仅包含一个区域Europe / Berlin。
由于以下几个原因,它不是最佳选择:
-柏林直到1893年才开始CET,比几个南部州晚。
答案 1 :(得分:0)
来自JavaDocs of GregorianCalendar
:
public ZonedDateTime toZonedDateTime()
将此对象转换为ZonedDateTime,该时间表示与该GregorianCalendar在时间轴上的同一点。
由于该对象支持儒略日至格里高利安转换日期,而ZonedDateTime不支持,因此结果年,月和日可能具有不同的值。结果将代表ISO日历系统中的正确日期,也将与“修改儒略日”的值相同。
我认为这是一种非期望但预期的行为。
答案 2 :(得分:0)
我怀疑这是GregorianCalendar
中的错误。我以前见过Date
中某些时区中1900年之前的错误。我认为ZonedDateTime
和java.time中的其他类更可靠,更值得信赖。
柏林的偏移量为+0:53:28,直到1893年4月1日00:00为止。在第89年的某天(为示例起见),您的代码给出的ZonedDateTime
为1893-03-29T23:53:28 + 00:53:28 [欧洲/柏林]提供正确的偏移量。但是您的GregorianCalendar
和ZonedDateTime
都代表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