Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert a timestamp before year 1900 in java

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"
like image 321
Bencri Avatar asked Jun 27 '26 20:06

Bencri


2 Answers

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

like image 124
user85421 Avatar answered Jun 30 '26 08:06

user85421


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).

like image 30
Ole V.V. Avatar answered Jun 30 '26 09:06

Ole V.V.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!