tl;dr:
the use of specializations for Local and Utc are unneeded and confusing.
The Java domain model, at its core, is as follows:
| Java type |
Purpose |
closest chrono equivalent |
Instant |
timezone-agnostic point in time |
none |
LocalDate |
date-only |
NaiveDate |
LocalTime |
time-only |
NaiveTime |
LocalDateTime |
date-time without timezone |
NaiveDateTime |
OffsetDateTime |
date-time with an offset from UTC |
DateTime<FixedOffset> |
ZonedDateTime |
date-time with a timezone |
DateTime<Tz> (from the chrono-tz crate) |
(Note that ZonedDateTime is what people tend to want more in dealing with date/time than a strict offset, because of DST)
</ hr>
So why are Local and Utc specializations unnecessary?
Simply put, it's due to the rather bizarre fact that UTC is (almost) never relevant to your problem domain.
Okay, when we deal with date/time, we're generally concerned with one of two cases:
- Logging the exact point in time something has occurred.
- Anticipating a point in time in the future. Most often these will be "fuzzy", where the exact point in time will not be known.
This first case is trivial; an exact point in time occurs at the same "instant" universally, regardless of any notion of timezone. Ignoring any specifics about storage, logged events are best displayed after the fact in an interested party's own specified timezone (for example, the timestamp for when I raised this issue).
The second case is harder to deal with. The major problem with scheduling events for humans is that we schedule in our own timezone, when there's no guarantee that a specific "time" may stay the same instant, or possibly even exist. This means it is an architectural and design flaw to store future events in only an instant or UTC-zoned timestamp - you need to retain the zone (among other things) to keep human-focused schedules correct, should the rules change.
Taken together, these two cases eliminate UTC as a valid compile-time choice (an interested party may have reason to configure UTC as a runtime choice for either case).
The case for elimination of DateTime<Local> is based around the changing of timezones. If, after getting my first DateTime<Local>, I change my timezone... it's not going to be "local" is it. Defining a specialization as the "local timezone" creates an inherent race condition with regards to the local zone being changed.
Furthermore, there are instances where "local" is meaningless or even harmful: consider the case of the code being run on a server. In this scenario, the timezone or offset of the physical machine is irrelevant. The timezone of the application may be relevant, but this is best explicitly set and injected as a dependency (for one thing, it makes testing much safer and easier); normally, however, the timezone of an interested party is going to be more relevant.
tl;dr:
the use of specializations for
LocalandUtcare unneeded and confusing.The Java domain model, at its core, is as follows:
chronoequivalentInstantLocalDateNaiveDateLocalTimeNaiveTimeLocalDateTimeNaiveDateTimeOffsetDateTimeDateTime<FixedOffset>ZonedDateTimeDateTime<Tz>(from the chrono-tz crate)(Note that
ZonedDateTimeis what people tend to want more in dealing with date/time than a strict offset, because of DST)</ hr>
So why are
LocalandUtcspecializations unnecessary?Simply put, it's due to the rather bizarre fact that UTC is (almost) never relevant to your problem domain.
Okay, when we deal with date/time, we're generally concerned with one of two cases:
This first case is trivial; an exact point in time occurs at the same "instant" universally, regardless of any notion of timezone. Ignoring any specifics about storage, logged events are best displayed after the fact in an interested party's own specified timezone (for example, the timestamp for when I raised this issue).
The second case is harder to deal with. The major problem with scheduling events for humans is that we schedule in our own timezone, when there's no guarantee that a specific "time" may stay the same instant, or possibly even exist. This means it is an architectural and design flaw to store future events in only an instant or UTC-zoned timestamp - you need to retain the zone (among other things) to keep human-focused schedules correct, should the rules change.
Taken together, these two cases eliminate UTC as a valid compile-time choice (an interested party may have reason to configure UTC as a runtime choice for either case).
The case for elimination of
DateTime<Local>is based around the changing of timezones. If, after getting my firstDateTime<Local>, I change my timezone... it's not going to be "local" is it. Defining a specialization as the "local timezone" creates an inherent race condition with regards to the local zone being changed.Furthermore, there are instances where "local" is meaningless or even harmful: consider the case of the code being run on a server. In this scenario, the timezone or offset of the physical machine is irrelevant. The timezone of the application may be relevant, but this is best explicitly set and injected as a dependency (for one thing, it makes testing much safer and easier); normally, however, the timezone of an interested party is going to be more relevant.