[Haskell-cafe] Towards a better time library (announcing tz)

Renzo Carbonara gnuk0001 at gmail.com
Mon Apr 7 16:20:40 UTC 2014


On Mon, Apr 7, 2014 at 12:49 PM, Mihaly Barasz <klao at nilcons.com> wrote:
> Hello Renzo and list,
>
> Since my last email I have implemented the two things that I mentioned:
> * a Template Haskell function with which you can include a few needed
> `TZ`s in your binary at compile time
> * a module which contains all of the time zones shipped in a pure way.
> So, if you use this module, all of the zone files will be compiled
> into your binary, so you can use them completely independently from
> the platform/machine you are running on. (This is appropriate for a
> webapp for example, where you need to display times to many users in
> many different time zones.)
>
> Renzo, please take a look at the Data.Time.Zones.All module
> (http://hackage.haskell.org/package/tz-0.0.0.3/docs/Data-Time-Zones-All.html).
> I tried to implement it with your comments in mind.

Yes! This is precisely what I had in mind, thanks so much for working
on this. Tools like these will allow us at work to deal with timezones
in a type-safe manner, purely within a closed world (the tz database
being used), avoiding any IO interactions, which is quite welcome when
building a piece of software that needs to deal with timezones
constantly like a web application attending users from different time
zones, just like you said. This same approach of including a full tz
database for internal use is done by other programs that need to
operate with timezones quite frequently; PostgreSQL comes to mind.

I particularly like that you are removing timezone names that are
links from the `TZLabel` constructors, yet allowing the link names to
be looked up when using `tzByName` (that is, both
`"America/Buenos_Aires"` and `"America/Argentina/Buenos_Aires"` point
to the canonical `America__Argentina__Buenos_Aires`).

I have two recommendations, both related to performance: First, I'd
prefer if instead of using `String` you used `ByteString` or `Text`.
`String` seems like an unnecessary cost to pay, even more so when one
of the purposes of this module is to avoid expensive lookups (in our
particular use case at work, we already have stored strings such as
`Europe/Rome` in the database, so reading them as `Text` or
`ByteString` will be cheaper than reading them as `String`). And the
second one, is that you could probably benefit from making
`tzDescriptions` be a `Data.Map.Map` from the time zone name to the
(either a `Text` or a `ByteString`) to the rest of the `TZDescription`
information. That'll certainly speed up the lookups by name (though by
looking at the definition of `tzByName`, maybe there are some
memoization tricks into play already which I can't immediately
recognize).


> If you think that
> this is something like what you need, something like what you were
> thinking about, I can release it as a separate package with your
> versioning scheme.

I don't think you really need to do this, it was just a minor
suggestion I made. As long as it's mentioned in the package and module
documentation what tz database version is being used, it should be
fine.


Regards,

Renzo Carbonara.


More information about the Haskell-Cafe mailing list