Dowser.Type.Date (Dowser.Client v0.5.0)

View Source

date and date_nanos — ISO-8601 strings or epoch numbers <-> Date, Time, DateTime or NaiveDateTime, depending on the field's "format".

Each supported format maps onto the Elixir function that reads it:

formatstoredElixir
epoch_millis1553391286000DateTime.from_unix(value, :millisecond)
epoch_second1553391286DateTime.from_unix(value, :second)
strict_date"2019-03-23"Date.from_iso8601/1
strict_date_hour_minute_second"2019-03-23T21:34:46"NaiveDateTime.from_iso8601/1
strict_date_hour_minute_second_millis"2019-03-23T21:34:46.123"NaiveDateTime.from_iso8601/1
strict_date_time_no_millis"2019-03-23T21:34:46-04:00"DateTime.from_iso8601/1
strict_date_time"2019-03-23T21:34:46.123-04:00"DateTime.from_iso8601/1
strict_hour_minute_second"21:34:46"Time.from_iso8601/1
strict_hour_minute_second_millis"21:34:46.123"Time.from_iso8601/1

Any other format — including none at all, which the backend reads as strict_date_optional_time||epoch_millis — is not cast: its values are returned as they are stored, in both directions. So is a value its format can't read.

A field with several supported formats ("strict_date||epoch_millis") reads a value with the first of them that recognizes it, and writes with the first.

Precision

Reading takes a value at whatever precision it carries. Writing produces exactly the precision the format declares: a DateTime, NaiveDateTime or Time is truncated to the second for strict_date_time_no_millis, strict_date_hour_minute_second, strict_hour_minute_second and epoch_second, and to the millisecond — padded to three digits when it has fewer — for their _millis counterparts, strict_date_time and epoch_millis. A date-time written to strict_date keeps its date, and one written to a time-of-day format its time.

Time zones

A DateTime is always loaded as one UTC DateTime: an offset in the value (-04:00) is applied and then dropped, as DateTime.from_iso8601/1 drops it. A value with no offset is read as UTC, as the backend reads it, and so is -00:00 (RFC 3339's "UTC, local offset unknown", which DateTime.from_iso8601/1 rejects). A DateTime in any other zone is dumped as its UTC instant, and a NaiveDateTime written to a format with an offset is taken to be UTC. So nothing here needs a time-zone database: the default Calendar.UTCOnlyTimeZoneDatabase and tzdata give the same results.

The instant is exact — the backend stores dates as UTC milliseconds — but the original offset is not kept: a document written as "2019-03-23T21:34:46-04:00", loaded and saved again, is written back as "2019-03-24T01:34:46Z". Keep the zone in a field of its own, or write a Dowser.Type module for that field, where the local time matters.