How to parse xs:date with NodaTime?

I have to process XML documents sent by various external systems that also contain some dates. xs:date allows adding a "time zone", i.e. an offset, to a date. E.g. "2017-06-02+03:00" is a valid value. Also, offsets are not used consistently in a single XML document. Some dates have an offset, most do not.

LocalDatePattern.IsoPattern does not handle values with an offset and my attempts at a custom pattern were also fruitless.

What would be the best way to parse these values into a LocalDate?

I debated to 2 possible options:

  1. Simply strip the offset part from the textual value and continue using LocalDatePattern.IsoPattern.
  2. Use OffsetDateTimePattern with a custom pattern that does not contain the time part and then construct the LocalDate manually from the parsed value.

I ended up going with option 1, because I do not need the offset for any conversions.

Jon Skeet
people
quotationmark

I would parse the value as OffsetDateTimePattern as that most closely represents the information you actually have in the text. My experience is that it's best to parse in a form that retains all the information you need, then use the Noda Time APIs to change to a format that you actually want... rather than do the transformation on the string and then parse.

Benefits of that:

  • It validates all the text, not just the text you're interested in. The value "2017-06-09-badger-badger" clearly suggests there's something very wrong, but if you're using a substring approach you'd miss that.
  • It's more robust - you're less likely to end up with magic numbers in your code, and it's much easier to handle things like variable-width formats (not a problem in this specific case, of course)
  • It makes it easier to change your mind about what you want, because the decision remains entirely in the "date and time" domain, not the "text parsing" domain.

The only exception I normally make to this is if the string is unparseable at the moment - e.g. it includes some unsupported aspect like ordinals ("June 3rd 2017").

We could consider adding this as a text format for LocalDate - I don't anticipate creating an OffsetDate type, unless there's significant demand.

people

See more on this question at Stackoverflow