nodatime

What is the realtime use of InZoneLeniently?


I am using the code mentioned on this link. I didn't understand the purpose of InZoneLeniently, Could someone explain by any real-time example when it is needed or when not needed?

I have started using NodaTime. If there are any changes in the IANA time zone or for example they add a new time zone. Then will we need to upgrade the nodatime library or will it handle it? In my case, I need to handle these conversions, but there may be more of a difference in future.

  1. Europe/London to America/Chicago
  2. Europe/Berlin to America/Chicago
  3. America/New_York to America/Chicago

Solution

  • Firstly, InZoneLeniently isn't used when converting from one time zone to another - it's used when converting from a LocalDateTime (with no offset information) to a ZonedDateTime.

    Background from the [documentation]:

    As well as mapping any particular instant to an offset, DateTimeZone allows you to find out the name of the part of the time zone for that instant, as well as when the next or previous change occurs - usually for daylight saving changes.

    Most of the time when you use a DateTimeZone you won't need worry about that - the main purpose is usually to convert between a ZonedDateTime and a LocalDateTime, where the names mean exactly what you expect them to. There's a slight twist to this: converting from an Instant or a ZonedDateTime to a LocalDateTime is unambiguous; at any point in time, all the (accurate) clocks in a particular time zone will show the same time... but the reverse isn't true. Any one local time can map to:

    • A single instant in time: this is the case for almost all the time.
    • Two instants in time: this occurs around a time zone transition which goes from one offset to an earlier one, e.g. turning clocks back in the fall. If the clocks go back at 2am local time to 1am local time, then 1.30am occurs twice... so you need to tell Noda Time which of the possibilities you want to account for.
    • Zero instants in time: this occurs around a time zone transition which goes from one offset to a later one, e.g. turning clocks forward in the spring. If the clocks go forward at 1am local time to 2am local time, then 1.30am doesn't occur at all.

    So for example, mapping a LocalDateTime to a ZonedDateTime in Europe/London, bearing in mind that on March 27th 2022, we had a "spring forward" from 1am to 2am at the start of summer time, and on October 30th 2022 we'll have a "fall back" from 2am to 1am.

    As the documentation for LocalDateTime.InZoneLeniently states:

    Returns the mapping of this local date/time within the given DateTimeZone, with "lenient" rules applied such that ambiguous values map to the earlier of the alternatives, and "skipped" values are shifted forward by the duration of the "gap".

    So in the cases above:

    So you need to ask yourself: if you've only got a local date/time in your app, what do you want to do if that local date/time was skipped or ambiguous? If InZoneLeniently doesn't do what you want, there's InZoneStrictly(DateTimeZone) or InZone(DateTimeZone, ZoneLocalMappingResolver).