[ANN] Timmy 1.0.0, a high level time and calendar library

I’m pleased to announce the availability on OPAM of the first stable version of Timmy, the library that powers all the time and calendar operations we perform at Routine.

It provides amongst other things:

  • Higher level types for time and calendar values.
  • Uncompromising timezone safety.
  • Timezone with DST support.
  • ISO weeks support.
  • Quality of life operators and common computations on most objects.
  • JavaScript back and forth conversions.

The philosophy and rationale for the library is explained at length in its root module documentation . Comments and contributions very welcome.

Happy coding!


Thanks for this!

How do you think it compares to Timedesc/Timere?


There is probably a large overlap; as noted in the first RFC for Timmy, both efforts happened roughly around the same time. Timere initial motivation is, AFAIK, to be a time reasoning library, while Timmy is “just” a higher level / safer interface on top of ptime with additional calendaring features such as ISO weeks and DST, which can influence some design decision.

For instance, the sole true initial motivation that sprouted Timmy was to be uncompromisingly safe wrt. the timezone, because we had one too many bug due to a forgotten optional timezone argument. Hence timezone is never optional and always enforced in Timmy, while I don’t think it’s the case in Timere. But indeed I think anything Timmy can do, Timere also can.

1 Like

Re: Time zone implementation of timmy-unix, I think it suffers from the same off-by-1 hour (sometimes) problem of ISO8601.ml (#17).

EDIT: okay, it’'ll be a slightly different issue after thinking about it a bit, but still related to general messiness of using mktime and friends. Or maybe it’s completely fine for local time zone.

EDIT2: okay, I just noticed the documentation on handling of ambiguous date time in Timmy.Timezone (“Note: In case of an ambiguous date, any of the two valid [Time.t] will be
picked depending on the implementation.”)
which side steps the accuracy concern I guess.

Re: Time zone being optional - one can in principle convert to a timestamp without appealing to a time zone in Timedesc by using the Zoneless module, but then it should be clear what they getting themselves into. Time zone is otherwise pervasive in Timedesc as far as I recall.

1 Like

I’d also add that Timmy (at least for timmy-unix) time zone implementation only provides local time zone construction out of the box (w.r.t. TZ env var at the time of resolution), while Timedesc allows construction of all time zones you (typically) see in your OS, regardless of what your current time zone is.

In principle one can modify the environment variable TZ to the desired time zone when resolving to timestamp in Timmy, but this goes back to the messiness of gmtime, mktime, and you now have to assert that no one else is touching TZ. In Timedesc, if you construct a time zone with “Europe/Paris”, it stays in “Europe/Paris”, you don’t have to care about TZ or any external factors.

Regarding the timezone ambiguity, I think indeed the issue only arise when the clock goes backward during DST ? Eg. in paris, Sunday, 29 October 2023, 02:30:00 will occur twice, and converting this date representation to a timestamp has two reasonably valid values. We could probably guarantee which one we pick. Part of the reasoning is that converting a date representation to a timestamp usually means conversion of user input to a timestamp, in the case of Routine when you type “Schedule something on october 29th at 2:30” in the console, which is an ambiguous request. But maybe you have additional insight regarding this.

We indeed do not bundle timezone information in the library and thus only support UTC and the local timezone out of the box. One can provide a custom implementation for timezones, so it could be done with an additional package providing timezone information (such as Timedesc :slight_smile: ), but it is not the current focus.

mktime doesn’t guarantee which one it’d give as far as I know - if Routine only resolves at server level, then maybe it’s fine.