Home > Net >  Why does LocalDateTime.ofInstant() requires ZoneId
Why does LocalDateTime.ofInstant() requires ZoneId

Time:01-26

In Java,

  • If Instant represents a point in time, encoded as date and time in UTC.
  • And LocalDateTime represents a point in time, encoded as date and time in the JVM local timezone.

Why then does LocalDateTime.ofInstant() require a ZoneId as a second argument ?

This makes LocalDateTime not only confusing and potentially incorrect, but also makes it identical to ZonedDateTime; because the timezone of LocalDateTime can be any timezone just like ZonedDateTime.

CodePudding user response:

And LocalDateTime represents a point in time, encoded as date and time in the JVM local timezone.

No, that's not true. Regardless of the "encoded as" part (which I highly doubt, but which I don't have significant knowledge of to disprove), a LocalDateTime does not represent a point in time. It represents a local date/time, without reference to a specific time zone. Any given LocalDateTime occurs at different points in time in different time zones.

Currently the local date and time in the Europe/London time zone is 2023-01-26T08:50. The same point in time in (say) America/New_York would result in a different LocalDateTime. Whereas in America/New_York, the LocalDateTime of 2023-01-26T08:50 occurs as a different point in time.

For some LocalDateTime / time zone combinations, there may be zero or two corresponding points in time - for example, the LocalDateTime 2022-11-06T01:30 will occur in America/New_York at both 2022-11-06 05:30:00Z and 2022-11-06 06:30:00Z.

Hopefully this is sufficient evidence that a LocalDateTime really isn't a point in time...

CodePudding user response:

A LocalDateTime represents a date and time without time zone information. It is used to represent "local time" (as an example for me, right now the local time is 2023-01-26 09:50). An Instant is always at UTC (example, the time right now is 2023-01-26 08:50 UTC). To transform between an Instant and what the observer considers to be local time, you need to know the ZoneId of the location of the observer (e.g. for me Europe/Amsterdam), otherwise you cannot derive a local time.

And to be clear, a LocalDateTime does not represent a point in time (that is what Instant is for). To expand my example, for me the local time 2023-01-26 09:50 is now past, while for Jon Skeet (in Europe/London), that local time will happen in slightly less than an hour).

CodePudding user response:

.ofInstant() is there to specify the instant and timezone.

If you don't want to specify the time zone and instant you can use .now() wich will use the local date and time.

If you want to specify the instant but not the ZoneId you can use ZomeId.systemDefault().

CodePudding user response:

An Instant is independent from time zones or offsets, but a LocalDateTime is not. Although it does not have a ZoneId or ZoneOffset, it's values are partially based on the offset the specific zone currently has.

Here's a code example with different zones that lead to different values of the very same Instant:

public static void main(String[] args) throws DateTimeParseException {
    // example instant (see output)
    var instant = Instant.now();
    // get the instant with different time zones
    var ldtBerlin = LocalDateTime.ofInstant(instant, ZoneId.of("Europe/Berlin"));
    var ldtCanberra = LocalDateTime.ofInstant(instant, ZoneId.of("Australia/Canberra"));
    var ldtKolkata = LocalDateTime.ofInstant(instant, ZoneId.of("Asia/Kolkata"));
    var ldtLA = LocalDateTime.ofInstant(instant, ZoneId.of("America/Los_Angeles"));
    // print all the results
    System.out.println("Instant "   instant.toEpochMilli()   " in different zones:");
    System.out.println(ldtBerlin   " (Berlin)");
    System.out.println(ldtCanberra   " (Canberra)");
    System.out.println(ldtKolkata   " (Kolkata)");
    System.out.println(ldtLA   " (Los Angeles)");
}

Output:

Instant 1674724841016 in different zones:
2023-01-26T10:20:41.016228 (Berlin)
2023-01-26T20:20:41.016228 (Canberra)
2023-01-26T14:50:41.016228 (Kolkata)
2023-01-26T01:20:41.016228 (Los Angeles)

View the different values, those are the local dates and times of the zones, but a LocalDateTime does not have any! You can use other objects, like ZonedDateTime (has zone and offset) and OffsetDateTime (has offset). Both of them have a method toLocalDateTime(), in case you need a LocalDateTime later on…

  • Related