Storing Time: How to Think About and Work With Time in Digital Systems

These two tutorials look at the big issues related to dealing with time while covering some applied strategies using the Clojure date-time libraries by @henry_w and company.

  • Storing Time: Part 1 talks about some of the basic problems with time abstractions and covers the basics of Java Time.
  • Storing Time: Part 2 addresses the problem of cultural memory in digital systems while digging into the time-literals library and reading/writing edn files.

I’m curious if anybody here works with abstractions that are much different than Joda Time or Java Time. Would love to hear more about alternatives with differing trade offs.

3 Likes

I started with Joda Time (and clj-time) early on building production systems in Clojure and have slowly switched to Java Time (with a mix of clojure.java-time and direct interop). Time is hard to work with so I’d also be very interested to hear of folks working with different abstractions!

In part 2 you say " I don’t want to work with java.util.Date , otherwise known as Joda Time." but java.util.Date is Java’s legacy date type – it isn’t Joda Time, which is a completely separate library (it is the forerunner of Java Time, by the same author). Am I misunderstanding what you’re trying to convey?

1 Like

I’m also puzzled by seeing :date "#time/date \"2019-07-15\"" in your EDN. Shouldn’t that be :date #time/date "2019-07-15" instead? Otherwise you’re reading the EDN in and then having to perform another read operation on each date/time field which seems… wrong.

1 Like

Thanks - I was incorrectly conflating the two in this sentence. Fixed.

Absolutely. I carried it over from working directly with strings in the REPL. Fixed it in the post and in the repository. Thanks for taking a look! Much appreciated.

2 Likes

My experiences:

I decided to store dates as 64-bit integer UNIX timestamps in UTC, having carefully considered a number of other options. This decision has served me well so far, and I do not intend to change this.

I cheat a little: I managed to avoid the complexity of managing timezone configuration by assuming that the browser knows which timezone it’s in and can convert timestamps for display. I am lucky to have a problem domain where this is possible (all times are to be displayed as local).

Both these decisions are unorthodox, but resulted in a tremendous simplification of my code. I think it is easy to fall into a rabbit hole of over-engineering time/date support: you have to make simplifying assumptions at some point, otherwise the problem will eat you alive.

I use clj-time on the server for all date-related operations and moment.js in ClojureScript. I have a thin cljc layer on top of both. I am not happy with this setup (especially as clj-time is considered deprecated) and I would really rather switch to a modern, well-supported unified library for date/time operations.

1 Like

I am not happy with this setup (especially as clj-time is considered deprecated) and I would really rather switch to a modern, well-supported unified library for date/time operations.

Did you check Tick ?
It’s still alpha but I think it’s a nice effort …

1 Like

I spent ten years working in the hotel booking industry which lacks effective standards for managing dates and times in electronic systems. The biggest liability comes from times that are expressed local to a hotel without an accompanying time zone. So while not “different from Joda Time or Java Time” because each has the concept of a LocalDate (which represents the (lack of) information adequately), I get the impression that it is a less common application of these libraries and the convenience functions needed some bolstering.

Trivia: if a hotel in an unknown time zone states that its earliest check-in time is 16:00h on 1 November 2020, and it is 28 October 2020 @12:00 EST5EDT (America/New_York) right now, what is the range of the intervals between now and the latest check-in?

Confounding Issue: For a consumer considering this hotel and whose time zone is also unknown, what is the range of intervals between now and check-in from his perspective?

These issues evaporate when dealing with Instants, but for LocalDate it’s a common problem we faced. One of the last efforts we made (before COVID killed our travel business) was geo-locating hotels into proper time zones to avoid this mess.

I enjoy your tone of writing. Really pleasant to follow.

Nitpick: in part 2, when explaining literals, I suspect you observed 3 + 7 to evaluate to 10 rather than 7?

1 Like

These are impossible problems without timezone info, right?

I have never worked with Sabre but I assume they have consistent timezones in their system and have perhaps even set something of a standard - they currently process over a third of all air travel bookings in the world. At one point, they certainly processed all computerized airline bookings.

Thus I’m a little surprised Sabre didn’t set something of a defacto standard in travel/time. Akin to how railroad set a standard for time and IBM has set certain computing standards along the way. Can you speak to this at all?

Yes, this is an impossible problem without some knowledge of timezones. With knowledge of timezones as of about four years ago (and probably not substantially changed since) the answer was roughly 26 hours.

Sadly, the OTA travel specs for hotels do not seem to have capitalized on the de facto Sabre standards adequately. There is typically no timezone information accompanying policy-based times like latest checkout and earliest checkin. Among the hotel partners with which I have experience there are some exceptions, but they are just that: exceptions.

When you run into these exceptions, I assume the additional information only causes more problems than it’s worth? Thinking about Postgres’ official stance on storing timezones:

Time zones, and time-zone conventions, are influenced by political decisions, not just earth geometry. Time zones around the world became somewhat standardized during the 1900s, but continue to be prone to arbitrary changes, particularly with respect to daylight-savings rules. PostgreSQL uses the widely-used IANA (Olson) time zone database for information about historical time zone rules. For times in the future, the assumption is that the latest known rules for a given time zone will continue to be observed indefinitely far into the future.

They go onto say that storing time with a timezone is essentially meaningless without a date. Not only for applying mathematical functions to dates in the past, but external changes in how a region might measure time into the future.

I assume you also see time stored as an offset in some systems, e.g. UTC +2. Which also lacks the specificity to be really dependable for the same reasons. Ugh. No wonder you’re seeing ludicrous measurements of ~26 hours.

Is this a market opportunity to supply a single source of truth to (what remains of) the travel industry? Fractions of a cent per transaction just to read a clock accurately?