javatimezone-offsetzoneddatetimezoneid

ZonedDateTime produces incorrect date at Europe/Paris vs GMT+1


I am in +07:00 timezone.

Given this:

ZonedDateTime.of( LocalDateTime.of( 1899, 12, 31, 23, 9, 20, 0 ), ZoneOffset.UTC )
.withZoneSameInstant( ZoneId.of( "Europe/Paris" ) )

Would produce: 1899-12-31T23:18:41+00:09:21[Europe/Paris]

In the other hand:

ZonedDateTime.of( LocalDateTime.of( 1899, 12, 31, 23, 9, 20, 0 ), ZoneOffset.UTC )
.withZoneSameInstant( ZoneId.of( "GMT+1" ) )

Would produce: 1900-01-01T00:09:20+01:00[GMT+01:00]

Why they are different, since both ZoneId.of( "Europe/Paris" ).getRules().getOffset( LocalDateTime.now() ) and ZoneId.of( "GMT+1" ).getRules().getOffset( LocalDateTime.now() ) produce +01:00? I expect the fist attempt should give 1900-01-01T00:09:20+01:00[Europe/Paris]. BTW, where are the +00:09:21 at the first try come?


Solution

  • You are correct that Europe/Paris and GMT+1 have the same offset now (2025-02-09), but they didn't have the same offset back in 1899.

    Let's print out their offsets at the Instant that you are actually interested in,

    var zdt = ZonedDateTime.of( LocalDateTime.of(1899, 12, 31, 23, 9, 20, 0), ZoneOffset.UTC);
    System.out.println(ZoneId.of("Europe/Paris").getRules().getOffset(zdt.toInstant()));
    System.out.println(ZoneId.of("GMT+1").getRules().getOffset(zdt.toInstant()));
    

    This prints

    +00:09:21
    +01:00
    

    That's where +00:09:21 came from. Paris did not standardise their time zones until 1911. It is 9 minutes and 21 seconds ahead of GMT because Paris is just east of Greenwich by that much time. That is offset from GMT of the local mean time of Paris.

    The timezone offset of Europe/Paris changed a lot throughout history. See Wikipedia for more details. Or, you can just print

    System.out.println(ZoneId.of("Europe/Paris").getRules().getTransitions());