I am trying to find the difference between 2 datetime which are in Adelaide timezone. The difference in hours is returned correctly in case of DST start but wrong for DST end.
As per the output below, in case of DST start, for 1st Oct 2023, the difference in hours between 01:30 and 03:30 AM is 1 which is as expected considering DST switch(02:30 AM time does not exist).
But the same is not working in case of DST end. For 2nd April 2023, the difference in hours between 02:30 and 03:30 AM also should be 1 but the output is 2 (120 minutes).
Below the same code and it's respective output. Can you please let me know why the ZonedDateTime is able to handle only one side of the DST change and not the other. Note: Using Java 8.
public class DateHourDifference {
public static void main(String[] args) {
dstStart();
dstEnd();
}
private static void dstEnd() {
// When local daylight time is about to reach
// Sunday, 2 April 2023, 3:00:00 am clocks are turned backward 1 hour to
// Sunday, 2 April 2023, 2:00:00 am local standard time instead.
System.out.println("-------------DST End---------------------------------");
LocalDateTime schedulerRunTime = LocalDateTime.of(2023, 04, 02, 3, 30);
LocalDateTime lastStatusLogRecord = LocalDateTime.of(2023, 04, 02, 2, 30);
ZonedDateTime currentSchedulerRun = schedulerRunTime.atZone(ZoneId.of("Australia/Adelaide"));
ZonedDateTime lastSchedulerRun = lastStatusLogRecord.atZone(ZoneId.of("Australia/Adelaide"));
System.out.println("currentSchedulerRun " + currentSchedulerRun.toString());
System.out.println("lastSchedulerRun " + lastSchedulerRun.toString());
long deltaBetweenDatesInMinutes = ChronoUnit.MINUTES.between(lastSchedulerRun, currentSchedulerRun);
System.out.println("deltaBetweenDatesInMinutes " + deltaBetweenDatesInMinutes);
long deltaBetweenDatesInHours = ChronoUnit.HOURS.between(lastSchedulerRun, currentSchedulerRun);
System.out.println("deltaBetweenDatesInHours " + deltaBetweenDatesInHours);
}
private static void dstStart() {
// When local standard time is about to reach
// Sunday, 1 October 2023, 2:00:00 am clocks are turned forward 1 hour to
// Sunday, 1 October 2023, 3:00:00 am local daylight time instead.
System.out.println("---------------DST Start-------------------------------");
LocalDateTime schedulerRunTime = LocalDateTime.of(2023, 10, 01, 3, 30);
LocalDateTime lastStatusLogRecord = LocalDateTime.of(2023, 10, 01, 1, 30);
ZonedDateTime currentSchedulerRun = schedulerRunTime.atZone(ZoneId.of("Australia/Adelaide"));
ZonedDateTime lastSchedulerRun = lastStatusLogRecord.atZone(ZoneId.of("Australia/Adelaide"));
System.out.println("currentSchedulerRun " + currentSchedulerRun.toString());
System.out.println("lastSchedulerRun " + lastSchedulerRun.toString());
long deltaBetweenDatesInMinutes = ChronoUnit.MINUTES.between(lastSchedulerRun, currentSchedulerRun);
System.out.println("deltaBetweenDatesInMinutes " + deltaBetweenDatesInMinutes);
long deltaBetweenDatesInHours = ChronoUnit.HOURS.between(lastSchedulerRun, currentSchedulerRun);
System.out.println("deltaBetweenDatesInHours " + deltaBetweenDatesInHours);
}
}
---------------DST Start-------------------------------
currentSchedulerRun 2023-10-01T03:30+10:30[Australia/Adelaide]
lastSchedulerRun 2023-10-01T01:30+09:30[Australia/Adelaide]
deltaBetweenDatesInMinutes 60
deltaBetweenDatesInHours 1
-------------DST End---------------------------------
currentSchedulerRun 2023-04-02T03:30+09:30[Australia/Adelaide]
lastSchedulerRun 2023-04-02T02:30+10:30[Australia/Adelaide]
deltaBetweenDatesInMinutes 120
deltaBetweenDatesInHours 2
When a time zone is set to a java LocalDateTime, the date value is considered to be already in/converted to the specified TZ. If the TZ has DST settings, it's also considered to be already added/removed.
For your case : Australia/Adelaide DST starts 1st of Octobre at 02:00 and ends 2nd of April at the same time.
I'm now going to explain why the output is correct :
---------------DST Start-------------------------------
currentSchedulerRun 2023-10-01T03:30+10:30[Australia/Adelaide]
lastSchedulerRun 2023-10-01T01:30+09:30[Australia/Adelaide]
deltaBetweenDatesInHours 1
The date value is considered to be already in the Adelaide TZ and has the DST added, so the original time without DST is 02:30 which is exacly one hour from 01:30
-------------DST End---------------------------------
currentSchedulerRun 2023-04-02T03:30+09:30[Australia/Adelaide]
lastSchedulerRun 2023-04-02T02:30+10:30[Australia/Adelaide]
deltaBetweenDatesInHours 2
Like the above case, the date value is considered to be already in the Adelaide TZ and has the DST removed, so the original time with DST is 04:30 which is exacly two hours from 02:30
Hope this helps understanding more stuff about java timezones.