简体   繁体   English

java.util.Date 正在使用 1912 年之前的日期解析错误的日期

[英]java.util.Date is parsing wrong dates with dates before 1912

I don't understand the reason why Jackson library is parsing wrong dates before 1912. I suppose the problem is the java.util.Date conversion , because the problem persists with Gson.我不明白 Jackson 库在 1912 年之前解析错误日期的原因。我想问题是java.util.Date 转换,因为 ZA79956B0B2E7BDA97AZD5A572 问题仍然存在。

This is my code:这是我的代码:

ObjectMapper mapper = new ObjectMapper();
String tmp = "{\"date\":\"1911-01-01T00:00:00+00:00\"}";
        
Response resp = mapper.readValue(tmp, Response.class);
System.out.println("Date->"+resp.date);

date is a field of type java.util.Date date 是 java.util.Date 类型的字段

As you can see, the input is: 1911-01-01T00:00:00+00:00可以看到,输入为: 1911-01-01T00:00:00+00:00

And the output is: Sun Jan 01 00:09:21 CET 1911 (I don't understand why that time is set) output 是: Sun Jan 01 00:09:21 CET 1911 (我不明白为什么要设置那个时间)

But If I set this input: 1912-01-01T00:00:00+00:00但是如果我设置这个输入: 1912-01-01T00:00:00+00:00

The ouput is correct: Mon Jan 01 00:00:00 CET 1912输出是正确的: Mon Jan 01 00:00:00 CET 1912

Only happens with dates before 1912.仅发生在 1912 年之前的日期。

Jdk v1.8.0_101 JDK v1.8.0_101

Thanks.谢谢。

java.time java.time

Never use the legacy class Date .切勿使用旧版 class Date Do not waste your time trying to understand the awful mess that is Date and Calendar .不要浪费时间试图理解DateCalendar的混乱。

Use only the modern java.time classes.仅使用现代java.time类。 Later versions of Jackson support java.time . Jackson 的更高版本支持java.time

OffsetDateTime odt = OffsetDateTime.parse( "1911-01-01T00:00:00+00:00" ) ;

When asked to produce text representing its value, that OffsetDateTime generates:当被要求生成表示其值的文本时, OffsetDateTime生成:

odt.toString(): 1911-01-01T00:00Z odt.toString(): 1911-01-01T00:00Z

The Z on the end means an offset of zero hours-minutes-seconds from UTC, and is pronounced “Zulu”.末尾的Z表示与 UTC 零时分秒的偏移量,发音为“Zulu”。


For an explanation as to what happened with your code using the legacy classes, see the excellent Answer by Ole VV But notice that using the properly-designed classes in java.time avoids the underlying issue: Applying a time zone where none was called for.有关使用遗留类的代码发生的情况的解释,请参阅Ole VV 的优秀答案但请注意,使用java.time中设计正确的类可以避免根本问题:应用不需要的时区。

A time zone is a history of the past, present, and future changes to the offset used by the people of a particular region.时区是特定地区的人们使用的偏移量的过去、现在和未来变化的历史。 Your input carries an offset (of zero), with no indication of time zone.您的输入带有偏移量(零),没有时区指示。 So no need to involve a time zone in processing your input.因此,在处理您的输入时无需涉及时区。

The good answer with the good solution has been posted by Basil Bourque. Basil Bourque 已发布了具有良好解决方案的良好答案。 Here's the answer explaining the reason for what you observed.这是解释您观察到的原因的答案。

Europe/Paris time zone was at offset +00:09:21 from when a standard time was defined until March 11, 1911. I believe that some French possessions in Northern Africa (Algeria, Tunisia) followed suit.从定义标准时间到 1911 年 3 月 11 日,欧洲/巴黎时区的偏移量为 +00:09:21。我相信北非(阿尔及利亚、突尼斯)的一些法国属地也会效仿。 So if your default time zone falls within one of those places, then VGR is correct in the comment that your output is correct.因此,如果您的默认时区属于这些地方之一,那么 VGR 在您的 output 是正确的评论中是正确的。

Nit-picking: Only the time zone abbreviation is debatable.挑剔:只有时区缩写是有争议的。 According to the link below it should be PMT (supposedly for Paris Mean Time), not CET (supposedly for Central European Time).根据下面的链接,它应该是 PMT(据说是巴黎标准时间),而不是 CET(据说是中欧时间)。 I don't think the now outdated Date class ever had ambitions of giving correct historical time zone abbreviations though.我不认为现在过时的Date class 曾经有过提供正确的历史时区缩写的野心。 It probably just gives CET because these days Paris uses Central European Time.它可能只是给出CET ,因为这些天巴黎使用中欧时间。

Once upon a time every capital and also many other metropols had their time defined by their mean solar time rather than a whole number of hours from some standard time reference (the role that GMT later acquired and still later UTC).曾几何时,每个首都和许多其他大都市的时间都是由平均太阳时定义的,而不是从某个标准时间参考(格林威治标准时间后来获得的角色以及更晚的世界标准时间)的整数小时数。 So an offset of +00:09:21 was nothing special back then.所以当时 +00:09:21 的偏移量并没有什么特别之处。

    ZonedDateTime dateTimeInFrance = OffsetDateTime.parse("1911-01-01T00:00:00+00:00")
            .atZoneSameInstant(ZoneId.of("Europe/Paris"));
    System.out.println(dateTimeInFrance);

Output: Output:

1911-01-01T00:09:21+00:09:21[Europe/Paris] 1911-01-01T00:09:21+00:09:21[欧洲/巴黎]

Near-duplicate: Convert a timestamp before year 1900 in java .近乎重复: 在 java 中转换 1900 年之前的时间戳

Further link: Time Changes in Paris Over the Years更多链接:多年来巴黎的时间变化

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM