Home > Net >  Need help understanding javadoc for ZonedDateTime::plusDays
Need help understanding javadoc for ZonedDateTime::plusDays

Time:09-05

I am not able to understand one specific part of doc provided for the plusDays() method in ZonedDateTimeClass. Doc states:

Returns a copy of this ZonedDateTime with the specified number of days added.

This operates on the local time-line, adding days to the local date-time. This is then converted back to a ZonedDateTime, using the zone ID to obtain the offset.

When converting back to ZonedDateTime, if the local date-time is in an overlap, then the offset will be retained if possible, otherwise the earlier offset will be used. If in a gap, the local date-time will be adjusted forward by the length of the gap.

This instance is immutable and unaffected by this method call.

Params: days – the days to add, may be negative

Returns: a ZonedDateTime based on this date-time with the days added, not null

Throws: DateTimeException – if the result exceeds the supported date range

How I understand this: Assume we have ZonedDateTime object representing September 4, 2022 6 PM in America/New_York TimeZone. So this method will first convert it to LocalDateTime, that is, it will lose timezone information and just retain September 4, 2022 6 PM. It will add some number of days to it, let's say 7, so that the result is September 11, 2022 6 PM, and now it will convert it back to ZonedDateTime object by providing back the information related to timezone.

However, I am not able to understand the latter part of documentation, that is,

When converting back to ZonedDateTime, if the local date-time is in an overlap, then the offset will be retained if possible, otherwise the earlier offset will be used. If in a gap, the local date-time will be adjusted forward by the length of the gap.

What do they mean by local date-time is in an overlap? ...then the offset will be retained if possible, otherwise the earlier offset will be used. - what are these two different offsets? If in a gap... - what is this gap?

Can someone please help me understand this part of the doc?

Thank you in advance.

CodePudding user response:

The "gap" and "overlap" terms are defined in the class-level Javadoc of the ZonedDateTime class:

This class handles conversion from the local time-line of LocalDateTime to the instant time-line of Instant. The difference between the two time-lines is the offset from UTC/Greenwich, represented by a ZoneOffset.

Converting between the two time-lines involves calculating the offset using the rules accessed from the ZoneId. Obtaining the offset for an instant is simple, as there is exactly one valid offset for each instant. By contrast, obtaining the offset for a local date-time is not straightforward. There are three cases:

  • Normal, with one valid offset. For the vast majority of the year, the normal case applies, where there is a single valid offset for the local date-time.
  • Gap, with zero valid offsets. This is when clocks jump forward typically due to the spring daylight savings change from "winter" to "summer". In a gap there are local date-time values with no valid offset.
  • Overlap, with two valid offsets. This is when clocks are set back typically due to the autumn daylight savings change from "summer" to "winter". In an overlap there are local date-time values with two valid offsets.

Example

Let's use your specific example of the America/New_York time zone. Per timeanddate.com, the daylight saving time changes in New York for 2022 are:

Mar 13, 2022 - Daylight Saving Time Started

When local standard time was about to reach
Sunday, March 13, 2022, 2:00:00 am clocks were turned forward 1 hour to
Sunday, March 13, 2022, 3:00:00 am local daylight time instead.

Nov 6, 2022 - Daylight Saving Time Ends

When local daylight time is about to reach
Sunday, November 6, 2022, 2:00:00 am clocks are turned backward 1 hour to
Sunday, November 6, 2022, 1:00:00 am local standard time instead.

Therefore, there are no times between 2:00 and 2:59 on March 13 in the New York time zone. 1:59 occurs in standard time. When that minute ends, no 2:00 hour occurs, and instead the local time jumps to 3:00 daylight time.

Additionally, the times between 1:00 and 1:59 occur twice on November 6: one in daylight time and then one in standard time.

Java ZonedDateTime example

ZoneId zone = ZoneId.of("America/New_York");

// 2022-03-13T03:15:30-04:00[America/New_York] (no 2:15)
System.out.println(
        ZonedDateTime.of(LocalDateTime.parse("2022-03-12T02:15:30"), zone)
        .plusDays(1));

Since 2:15 AM on March 12 doesn't exist and is within a 1-hour gap, the following logic you quoted applies, adding 1 hour to the local time:

If in a gap, the local date-time will be adjusted forward by the length of the gap.

Therefore, 3:15 AM is used when adding 1 day to March 11 at 1:15 AM.

ZoneId zone = ZoneId.of("America/New_York");

// 2022-11-06T01:15:30-04:00[America/New_York] (First 1:15)
System.out.println(
        ZonedDateTime.of(LocalDateTime.parse("2022-11-05T01:15:30"), zone)
        .plusDays(1));

// 2022-11-06T01:15:30-05:00[America/New_York] (Second 1:15)
System.out.println(
        ZonedDateTime.of(LocalDateTime.parse("2022-11-05T01:15:30"), zone)
        .plusDays(1).plusHours(1));

Since 1:15 AM is during an overlap — 1:15 AM occurs twice on November 6 — the following logic you quoted applies, using the same -04:00 zone offset as 1:15 AM on November 5:

if the local date-time is in an overlap, then the offset will be retained if possible

Therefore, adding 1 day to November 5 at 1:15 uses the first 1:15 on November 6. This is made more evident by the second call, which shows that adding an hour to this timestamp returns the second 1:15 of November 6. The fact that these are different points on the timeline despite both being 1:15 local time is evident by their differing zone offsets: -04:00 & -05:00.

CodePudding user response:

Political time presents anomalies

ZonedDateTime is political time. Politicians define time zones and set the rules.

Politicians around the world have shown a surprisingly common prediliction for fiddling with these rules. And they do so unpredictably, often with little or no warning.

Politicians can decide that everyone should rise an hour early in the morning, and then in half a year reverse their decision, mandating that people open their shops an hour later — this wacky plan is known as Daylight Saving Time (DST).

The newest fad: Politicians deciding that the people of their jurisdiction should stay on DST year-round. So then the sun is never overhead at noon, defying the definition of "noon".

Martial victors, colonizers, and occupiers may choose to impose a time zone that suits their home country.

Politicians may change the offset of their jurisdictions to annoy their neighbor(s), or to appease their neighbor(s), as a diplomatic move.

Spring forward; Fall back

During any of these anomalies, the hands of the clock must jump ahead or fall back some amount of time, some number of hours-minutes-seconds.

For example, many places in the US observing DST change their clocks twice a year. They jump ahead an hour at 2 AM on a particular day in the Spring. So the offset in use changes an hour, such as America/Los_Angeles changing from an offset of -08:00 to -07:00. Those places later fall back an hour at 2AM on a particular day in the Autumn. The offset in use changes by an hour, such as America/Los_Angeles changing from an offset of -07:00 to -08:00.

  • In the first case, clocks jumping ahead, the hour of 02:00 - 03:00 never exists, for a 23-hour day.
  • In the second case, clocks falling back, the hour of 01:00 - 02:00 happens twice, for a 25-hour day.

In that second case, when the clock falls back an hour, there is an ambiguity of how to recognize a time-of-day such as 01:30. Does "01:30" refer to the middle of the first hour occurrence or the middle of the second hour occurrence?

  • Related