Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing the ISO-8601 duration values of the AMAZON.DURATION slot type

Does the java.time library provide a consolidated way to parse the entire ISO-8601 Duration Specification?

The Alexa Slot Type reference for duration lists some example strings to expect when using the AMAZON.DURATION slot type. All strings are in ISO-8601 Duration, but P2YT3H10 cannot be parsed by either java.time.Period or java.time.Duration.

Seq(
 "PT10M",
 "PT5H",
 "P3D",
 "PT45S",
 "P8W",
 "P7Y",
 "PT5H10M",
 "P2YT3H10"
).map { s =>
 s -> Try {
   try {
     Period.parse(s)
   } catch {
     case ex: Throwable => Duration.parse(s)
   }
 }.map(x => x.toString -> x.getClass.getSimpleName)
}
.foreach(println)

Results:

(PT10M,Success((PT10M,Duration)))
(PT5H,Success((PT5H,Duration)))
(P3D,Success((P3D,Period)))
(PT45S,Success((PT45S,Duration)))
(P8W,Success((P56D,Period)))
(P7Y,Success((P7Y,Period)))
(PT5H10M,Success((PT5H10M,Duration)))
(P2YT3H10,Failure(java.time.format.DateTimeParseException: Text cannot be parsed to a Duration))
like image 804
Upio Avatar asked Sep 16 '17 21:09

Upio


People also ask

How do I specify the duration in an ISO 8601 format?

Briefly, the ISO 8601 notation consists of a P character, followed by years, months, weeks, and days, followed by a T character, followed by hours, minutes, and seconds with a decimal part, each with a single-letter suffix that indicates the unit. Any zero components may be omitted.

What does duration regular mean Amazon?

Job Duration Regular Employment. If you're looking for something a little more permanent, this is your schedule. These year-round opportunities can be full-time, reduced-time, or part-time.


1 Answers

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.

like image 147
Meno Hochschild Avatar answered Nov 05 '22 14:11

Meno Hochschild