jsonschema2pojo icon indicating copy to clipboard operation
jsonschema2pojo copied to clipboard

Support for java Duration

Open B-hamza opened this issue 3 years ago • 7 comments
trafficstars

Json schema Spec support format duration as this issue mention https://github.com/json-schema-org/json-schema-spec/issues/565 Is it possible to have java time Duration generated for this format, as it the case for uuid format ?

B-hamza avatar May 31 '22 12:05 B-hamza

Should be an easy PR to add. Check out the FormatRule and FormatIT.

joelittlejohn avatar Aug 06 '22 12:08 joelittlejohn

It should be noted though that neither java.time.Duration nor java.time.Period are fully ISO 8601 compliant. Link in the issue mentions durations cited by https://www.rfc-editor.org/rfc/rfc3339.html#page-12

Durations:

dur-second = 1DIGIT "S" dur-minute = 1DIGIT "M" [dur-second] dur-hour = 1DIGIT "H" [dur-minute] dur-time = "T" (dur-hour / dur-minute / dur-second) dur-day = 1DIGIT "D" dur-week = 1DIGIT "W" dur-month = 1DIGIT "M" [dur-day] dur-year = 1*DIGIT "Y" [dur-month] dur-date = (dur-day / dur-month / dur-year) [dur-time]

duration = "P" (dur-date / dur-time / dur-week)

For example it is not possible to construct java.time.Duration of values:

  • P1W
  • P1Y
  • ...

unkish avatar Aug 08 '22 09:08 unkish

@unkish agree. But for the most use cases duration type is good enough. Like default regex implementation as I wrote below.

There's way more to add about compliance of Java types to JSON schema standards. E.g. one of such type types is regex: Java's version still support regexes like {3} (this is the full regex) and doesn't support some features of ECMA's. In this case to support it, I had to add jruby's implementation.

If parser-specific formatter exists in a parser library, it's better to add an annotation for it. Otherwise, I'd add parser-specific things to a parser or a separate library.

eirnym avatar Aug 08 '22 10:08 eirnym

@unkish It's a good point. I've found that using appropriate types provided by the host platform is most useful, even if they are not strictly compliant. The regex example is a good one.

However, in this case, if we don't support W, M or Y this is a serious problem I think. It looks like a common approach is to return TemporalAmount and have an implementation that uses Duration or Period depending on whether M/W/Y are used. I'm also interested to see how Jackson solves this (e.g. does it have a TemporalAmount ser/deser that implements some logic like this?).

joelittlejohn avatar Aug 08 '22 11:08 joelittlejohn

I'm sorry, maybe I misunderstand what You are trying to hint at. Following code would fail in runtime:

final ObjectMapper om = new ObjectMapper().registerModule(new JavaTimeModule());
final String p1y2mJson = om.writeValueAsString(Period.parse("P1Y2M"));
final Duration pAsDuration = om.readValue(p1y2mJson, Duration.class);

unkish avatar Aug 11 '22 07:08 unkish

Out if interest, does this work:

om.readValue("P1Y2M", TemporalAmount.class);

?

joelittlejohn avatar Aug 11 '22 09:08 joelittlejohn

Unfortunately not:

Cannot construct instance of java.time.temporal.TemporalAmount (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information

I can't imagine what it would return in case something more complex such as P1Y2MT4H5M - java.time.Duration ?

unkish avatar Aug 12 '22 07:08 unkish