Hugos answer is only related to one detail aspect of the ISO-8601-standard, namely the combination of date and time part with a "T"-separator. This detail is indeed not supported by java.time
but supported by the external library Threeten-Extra (using the class PeriodDuration
in the version v1.2). However:
The ISO-8601-standard describes even more variations.
One variation is the usage of weeks in the form "P8W". Both java.time
and Threeten-Extra automatically change it to "P56D" but don't leave it in week-related form when parsing and formatting. A similar view can be obtained when looking at the time components. java.time.Duration
cannot directly store hours or minutes but automatically convert it to seconds. When formatting an automatical normalization is performed, too. Example:
System.out.println(Duration.parse("PT4200S")); // PT1H10M
So in both cases: What you put inside during construction is not always what you get when formatting.
Other points:
- Duration representations in ISO-8601 (as specified in section 4.4.4.2) are always called "Duration" (even if date-related) while
java.time
uses two different terms, namely Period
and Duration
(either date-related or time-related).
- Week-related durations are handled separately since two standard ways in ISO-8601-notation are described: "PnnYnnMnnDTnnHnnMnnS" or "PnnW".
- Signs don't exist in ISO-8601-specification (see section 3.4.2: symbol "n" defined as positive integer or zero) while
java.time
allows signs even inside the representations and interprete signs as component-related. Note that XML-Schema only handles signs preceding the whole duration expression (before "P"), that is not component-related but duration-related.
- Alternative representations of durations are also specified, either in basic or in extended format: "PYYYYMMDDThhmmss" resp. "PYYYY-MM-DDThh:mm:ss".
- Handling of fractional seconds: ISO-8601 speaks about usage of comma or dot (and even explicitly prefers the comma) while
java.time.Duration
only supports the dot.
Finally we can state:
The ISO-8601-standard is only partially supported by java.time
(and Threeten-Extra which only supports the combination of the classes Period
and java.time.Duration
as additional detail).
Alternative solution for true ISO-8601-support:
If you want or even need to overcome the limitations baked into java.time
then you can use my library Time4J which supports all the additional details of ISO-8601. See the API of class net.time4j.Duration. Following examples also show the compatibility with java.time
:
Duration<CalendarUnit> d1 = Duration.parseCalendarPeriod("P8W");
System.out.println(d1); // P8W
System.out.println(d1.getPartialAmount(CalendarUnit.WEEKS)); // 8
System.out.println(Duration.Formatter.ofPattern(CalendarUnit.class, "W' weeks'").format(d1)); // 8 weeks
System.out.println(PrettyTime.of(Locale.GERMAN).print(d1)); // 8 Wochen
LocalDate ld = LocalDate.of(2017, 9, 17);
System.out.println(PlainDate.from(ld).plus(d1)); // 2017-11-12
System.out.println(PlainDate.of(2017, 9, 17).plus(d1)); // 2017-11-12
Duration<IsoUnit> d2 = Duration.parsePeriod("P2DT5H10M");
LocalDateTime ldt = LocalDateTime.of(2017, 9, 17, 19, 15);
System.out.println(PlainTimestamp.from(ldt).plus(d2)); // 2017-09-20T00:25
System.out.println(PlainTimestamp.of(2017, 9, 17, 19, 15).plus(d2)); // 2017-09-20T00:25
System.out.println(PrettyTime.of(Locale.GERMAN).print(d2)); // 2 Tage, 5 Stunden und 10 Minuten
Duration<IsoUnit> d3 = Duration.parsePeriod("P0001-01-02T05:10:04");
System.out.println(d3); // P1Y1M2DT5H10M4S
LocalDateTime ldt = LocalDateTime.of(2017, 9, 17, 19, 15);
System.out.println(PlainTimestamp.from(ldt).plus(d3)); // 2018-10-20T00:25:04
Side note: Formatting of durations is possible in actually 86 languages.