Could data.json support dates?

Description

Problem

Cheshire provides default formatting for dates out of the box. data.json does not, and just throws an exception.

Pitfalls

java.util.Date can easily be converted and formatted that way, but you also need to be careful about java.sql.Date – which Cheshire supports out of the box – but which cannot be directly converted to a java.time.Instant – throwing UnsupportedOperationException because SQL DATEs have no time component.

Our solution at work was to go to a LocalDate and then .atStartOfDay with (java.time.ZoneId/systemDefault) to get to something you can format as an instant.

Possible solutions

  1. Do nothing, let the consumer implement a :value-fn which does the transformation.

  2. Teach data.json how to handle dates

Tradeoffs

Do Nothing

Doing nothing is the easiest case for the maintainers of data.json, but does put a burden on all consumers, and it might be assumed that writing dates is a normal use case when writing json.

Teach data.json to handle dates

Seemingly both simple and easy, but javas date and time handling has evolved over time. As outlined below, there are some corner cases to be considered. There are also problems in providing useful defaults, but still letting the user override these as she pleases.

 

Proposed solution

The proposed solution basically follows what outlined in the original issue:

  1. Base everything off java.time.Instant

  2. Convert java.sql.Date to java.time.Instant by using a default-sql-date->instant-fn which goes via a LocalDate and its .atStartOfDay

  3. Add :date-formatter which accepts a DateTimeFormatter , with a default of DateTimeFormatter/ISO_INSTANT

  4. Add :sql-date-converter, an option to override default-sql-date->instant-fn

Environment

None

Activity

Show:
Alex Miller
April 16, 2021, 6:48 PM

Applied patch

Alex Miller
April 16, 2021, 6:47 PM

Nice that the new time formatter stuff properly handles java.sql.Timestamp nanos now.

Sean Corfield
April 8, 2021, 8:17 PM

The data.json test suite passes here in California and I ran our full test suite at work using the patched data.json and with our :value-fn changed to identity (it otherwise handles both dates and UUIDs). The place where we provide a custom formatter required the formatter to be wrapped in .withZone (with either UTC or the system default – tested with both). I did not test with java.sql.Timestamp.

I think the docs need to be clear about which date/time types are supported out of the box and what TZ is used for any conversions. An example of a TZ-sensitive formatter should also be provided, demonstrating the need for .withZone such as:

The patch looks good from my p.o.v.

Thanks!

Erik Assum
April 8, 2021, 8:00 AM

I’d really appreciate it if you had a thorough look through this patch (and maybe took it for a spin). Especially the tests, since even though I’ve tried to write them TZ-agnostic, I might just not have succeeded in that.

Fixed

Assignee

Alex Miller

Reporter

Erik Assum

Patch

Code and Test