Convert a timestamp before year 1900 in java

送分小仙女□ 提交于 2021-01-28 01:07:56

问题


My Android app communicate with an API which give me the following timestamp : -2209161600. Converted to a date time, it's supposed to be 12-30-1899 00:00:00

The problem is, I tried to convert this timestamp using both the default library, threetenbp, and then jodatime, but I always get the same wrong result, using Europe/Paris timezone : 12-30-1899 00:09:21

Why does that happen ?

EDIT: For example with jodatime

DateTime dt = new DateTime(-2209161600000L, DateTimeZone.forID("Europe/Paris")); // dt: "1899-12-30T00:09:21.000+00:09:21"

回答1:


I think I found the answer on the FAQ as part of Why is the offset for a time-zone different to the JDK?:

... affects date-times before the modern time-zone system was introduced. The time-zone data is obtained from the time-zone database. The database contains information on "Local Mean Time" (LMT) which is the local time that would have been observed at the location following the Sun's movements.

Joda-Time uses the LMT information for all times prior to the first time-zone offset being chosen in a location. ...

In other words, the database does not have entries for that time so it is uses the Local Mean Time (e.g. 0:09:21 for Paris, or -0:14:44 for Madrid 1).

System.out.println(new DateTime(-2209161600000L, DateTimeZone.forID("Europe/Paris")));
System.out.println(new DateTime(-2209161600000L, DateTimeZone.forID("Europe/Madrid")));

will print

1899-12-30T00:09:21.000+00:09:21
1899-12-29T23:45:16.000-00:14:44

Solution: depends what tis time is needed for, if UTC is sufficient, use

new DateTime(-2209161600000L, DateTimeZone.forID("UTC"))  // 1899-12-30T00:00:00.000Z

or just the standard java.time classes like

Instant.ofEpochSecond(-2209161600L)
Instant.ofEpochMilli(-2209161600000L)

1 - http://home.kpn.nl/vanadovv/time/TZworld.html#eur




回答2:


Carlos Heuberger may have said it already. As far as I can see, it’s a matter of using UTC instead of Europe/Paris time zone.

    long unixTimestamp = -2_209_161_600L;
    Instant inst = Instant.ofEpochSecond(unixTimestamp);
    System.out.println("As Instant: " + inst);

Output is:

As Instant: 1899-12-30T00:00:00Z

If you need date and time:

    OffsetDateTime dateTime = inst.atOffset(ZoneOffset.UTC);
    System.out.println("As OffsetDateTime: " + dateTime);

As OffsetDateTime: 1899-12-30T00:00Z

Am I missing something?

Explanation

Why does it matter? Because in 1899 Paris used the local mean time in Paris, which is at offset +00:09:21 from UTC. Therefore the correct and expected result in Europe/Paris time zone is the one you got, 12-30-1899 00:09:21. To check this offset: Go to Time Zone in Paris, Île-de-France, France. In the Time zone changes for dropdown choose 1850 – 1899. You will see that the offset of +00:09:21 was in effect during this entire interval if years (both before and after the change of time zone abbreviation in 1891).



来源:https://stackoverflow.com/questions/57326821/convert-a-timestamp-before-year-1900-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!