0

Do you know why 4. and 6. prints have wrong hours in following code?

LocalDateTime ldtNow = LocalDateTime.now();
LocalDateTime ldtNextMonth = ldtNow.plusMonths(1);

System.out.println("1. " + ldtNow);
System.out.println("2. " + ldtNextMonth);

System.out.println("3. " + ldtNow.atZone(ZoneId.systemDefault()).toInstant().toString());
System.out.println("4. " + ldtNextMonth.atZone(ZoneId.systemDefault()).toInstant().toString());

System.out.println("5. " + ldtNow.atZone(ZoneOffset.systemDefault()).toInstant().toString());
System.out.println("6. " + ldtNextMonth.atZone(ZoneOffset.systemDefault()).toInstant().toString());

This is what it prints:

 1. 2022-10-26T16:53:59.691891
 2. 2022-11-26T16:53:59.691891

 3. 2022-10-26T14:53:59.691891Z
 4. 2022-11-26T15:53:59.691891Z //WRONG?

 5. 2022-10-26T14:53:59.691891Z
 6. 2022-11-26T15:53:59.691891Z //WRONG?

Prints 3. & 4. test it with ZoneId and prints 5. & 6. with ZoneOffset.

The only difference between 3. & 4. (and 5. & 6.) is the usage of LocalDateTime#plusMonths method. What should I do to get right result for zero time (2022-11-26T14:53:59.691891Z)?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
APTower
  • 343
  • 2
  • 8
  • 3
    You seem to have involved a DST change by accident. What's the default time zone of your system? It may change at the end of october and add an hour! Take `ZoneId.of("UTC")` instead of `ZoneId.systemDefault()`… – deHaar Oct 26 '22 at 15:07
  • wouldn't the 2nd one also be an hour plus 16 if they add an hour after October @deHaar – devin Oct 26 '22 at 15:10
  • That's what OP has to find out… I'm not sure it's the case, but it's possible… That means try and see. – deHaar Oct 26 '22 at 15:11
  • 1
    My system default is _Europe/Prague_. I didn't think of that it could be time change at the end of October. You are right! When using `ZoneId.of("UTC")` it gives equal results. – APTower Oct 26 '22 at 15:21
  • 1
    @devin NO, `LocalDateTime` has no concept of time zone (also the reason to need `atZone()` to convert it) – user16320675 Oct 26 '22 at 15:28

1 Answers1

1

The method atZone() returns ZonedDatetime and then you experience the daylight saving effect. Different zones around the globe have daylight saving at different dates.

So your prints are:

 1. 2022-10-26T16:53:59.691891  // LocalDateTime
 2. 2022-11-26T16:53:59.691891  // LocalDateTime

 3. 2022-10-26T14:53:59.691891Z // ZonedDateTime
 4. 2022-11-26T15:53:59.691891Z // ZonedDateTime

 5. 2022-10-26T14:53:59.691891Z // ZonedDateTime
 6. 2022-11-26T15:53:59.691891Z // ZonedDateTime  

UTC time zone is like a reference point for any other timezone. For example CET, central european time timezone have the zone offsets of UTC+2 and UTC+1 depending on the period of the year.

You can see this effect by executing the following snippet:

ZonedDateTime zdt1 = ldtNow.atZone(ZoneOffset.systemDefault());
ZonedDateTime zdt2 = ldtNextMonth.atZone(ZoneOffset.systemDefault());

System.out.println(ZoneOffset.from(zdt1));   // prints +02:00
System.out.println(ZoneOffset.from(zdt2));   // prints +01:00
c3R1cGFy
  • 505
  • 4
  • 12
  • 1
    More precisely, Central Europe TIme is used in several European and North African time zones *most*, not all, of which use summer time (DST). A few stay on UTC+1 all year. Otherwise a correct answer. – Ole V.V. Oct 27 '22 at 16:19