Compatibility between Instant and ZonedDateTime

ZonedDateTime I understand ZonedDateTime indeed an improved version of Instant . It contains all the data that is in Instant (the exact value on the UTC scale), as well as information about the time zone. So my naive assumption was that ZonedDateTime is Instant and that any method using Instant ZonedDateTime would happily take ZonedDateTime instead. Also, I was expecting isBefore() , isAfter() , etc. isAfter() work seamlessly between Instant and ZonedDateTime .

Looking at the API documentation for Instant and ZonedDateTime , this is not the case. I can compare Instant with Instant and ZonedDateTime with ZonedDateTime , but these two classes seem to be incompatible. Moreover, third-party code such as ThreeTen-Extra Interval seems to work exclusively with Instant s.

Is there a reason why Instant and ZonedDateTime should not mix?

+9
source share
3 answers

Instant and ZonedDateTime have a different state - Instant is just a few nanoseconds from the era, and ZonedDateTime consists of LocalDateTime , ZoneId and ZoneOffset . Thus, two classes can be converted to / from each other, but do not match (and you lose information when converting ZonedDateTime to Instant ).

The behavior of isBefore() and isAfter() exactly matches between them. While the Comparable implementation is in Comparable with the recommended behavior, which is that β€œIt is highly recommended (though not necessary) that natural orders match equally.” i.e. compareTo() takes into account local date-time, time zone and offset, while isBefore() and isAfter() take into account only the moment.

Writing a comparator to compare Instant and a ZonedDateTime relatively simple:

 Comparator<TemporalAccessor> comparator = (a, b) -> Instant.from(a).compareTo(Instant.from(b)); 

which can also be written as:

 Comparator<TemporalAccessor> comparator = Comparator.comparing(Instant::from); 
+7
source

Because translation is not injective. Take Sunday, October 30, 2016, 2:15 in Germany / Munich, for example: Which Instant does this date / time match? It does not depend on any assumptions, because you do not know whether this time should be converted to Instant before or after the shift for daylight saving time (DST). Or Sunday, March 27, 2016 2:15 AM in Germany / Munich: This combination of date and time should not exist, since the clock must be set to 3 hours when it reaches 2 hours.

Without DST, the three possible cases for converting a LocalDateTime to Instant (exact match, summer time overlap, winter overlap) will be reduced to one, and the conversion will be injective, AFAIK.

Edit: Hands, this problem, when you display the date / time in our JSF-based application, we always transfer the offset calculated according to the current state of the DST to the formatter.

+6
source

Instant and ZonedDateTime have different arithmetic rules. This is the only reason I see to avoid polymorphism for these two types. For example, adding n days to Instant means adding n times 86400 seconds to it. Is always. This would not be the case if ZonedDateTime was a subclass of Instant due to daylight saving rules.

ZonedDateTime I understand that Instant similar to ZonedDateTime with UTC ZonedDateTime , so you can argue that Instant instead is a ZonedDateTime . However, this will make Instant more complicated than today, as it will allow arithmetic with TemporalUnit such as MONTHS . Monthly arithmetic depends on the time zone, so Instant forces the programmer to select an explicit time zone before doing this.

In any case, unfortunately, Instant and ZonedDateTime are no longer compatible, as they both represent time uniquely. It seems like they are missing a common base class or interface without any methods for arithmetic.

0
source

Source: https://habr.com/ru/post/1012212/


All Articles