MenoData / Time4J

Advanced date, time and interval library for Java with sun/moon-astronomy and calendars like Chinese, Coptic, Ethiopian, French Republican, Hebrew, Hijri, Historic Christian, Indian National, Japanese, Julian, Korean, Minguo, Persian, Thai, Vietnamese
GNU Lesser General Public License v2.1
442 stars 65 forks source link

Deploy the interface TemporalAmount #218

Closed MenoData closed 9 years ago

MenoData commented 9 years ago

The class net.time4j.Duration should implement the interface java.time.temporal.TemporalAmount.

Main advantage: Durations spanning over calendrical units as well as clock units can be applied on JSR-310-types like LocalDateTime. Furthermore, the JSR-310-types can take profit from the improved time arithmetic algorithms of Time4J when it comes to negative durations.

MenoData commented 9 years ago

The topic of this issue was mainly motivated by the missing gap in JSR-310, namely a duration spanning over calendrical units as well as clock units. But unfortunately there is a very negative side effect when implementing TemporalAmount. As with all time-axis-related classes in JSR-310, this is not type-safe at all. If Time4J really implemented TemporalAmount then it would be possible to add clock units to a plain calendar date at compile time (just to pick an example, other consequences are not less frightening like getting the duration between a LocalDateTime and an OffsetDateTime).

Not acceptable.

For comparison and information => A compilable and even runnable bizarre example from JSR-310 which Time4J will and should never accept (similar to comparing apples and oranges):

    LocalTime lt = OffsetTime.of(17, 45, 0, 0, ZoneOffset.ofHours(+2)).toLocalTime();
    OffsetTime ot = OffsetTime.of(lt, ZoneOffset.ofHours(-1)); // any arbitrary offset allowed!
    Duration dur = Duration.between(lt, ot);
    System.out.print(dur); // PT0S
MenoData commented 9 years ago

The best Time4J can do for the support of general durations applied on LocalDateTime to fill the mentioned gap in JSR-310 is the introduction of two new methods:

This is type-safe and fills a gap in Java-8 although the addTo()-syntax is not sooo nice (but at least understandable).

UPDATE: However, the disadvantage of the described between()-method is the lack to specify the metric how the duration shall be calculated. The whole thing does not integrate smoothly into the rest of the Duration-API. A simple workaround for addTo()/subtractFrom() is possible as follows:

LocalDateTime input = ...;
Duration<IsoUnit> duration = ...;

LocalDateTime result = PlainTimestamp.from(input).plus(duration).toTemporalAccessor();

For between()-method (example):

LocalDateTime start = ...;
LocalDateTime end = ...;

Duration<IsoUnit> result = 
  Duration.inYearsMonthsDays().between(
    PlainTimestamp.from(start),
    PlainTimestamp.from(end));

Not a big deal. The same statement is valid for the other types LocalDate and LocalTime. If someone has a new or better idea how to develop the API then welcome. For now, I am closing this issue as "won't fix". There is not enough surplus-value as the easy workarounds indicate. The root cause of the described difficulties is the fact that Time4J is strongly generified while JSR-310 is not.