[Haskell-cafe] Towards a better time library (announcing tz)
Renzo Carbonara
gnuk0001 at gmail.com
Tue Apr 1 01:21:36 UTC 2014
I'm currently a user of the `timezone-olson` and `timezone-series`
libraries, so I can understand the requirement for better time zone
representations than the one offered by `time`. I think it would be
best for the community if your work and the one in `timezone-olson`
and `timezone-series` could be integrated somehow, as there doesn't
seem to be a need to have two different implementations for parsing
the Olson file format. As far as I know, Yitzchak is willing to
improve his libraries, I CC him here.
Given that you are shipping a timezone database with your package, as
a user I'd really prefer `loadTZFromDB` to be `String -> Maybe TZ`
instead of `String -> IO TZ` so that it can be used in pure code.
You'd probably need to hardcode the contents of the `*.zone` files you
are including within a Haskell module, but that could be done
automatically using some script.
Moreover, an idea I've been toying with is writing a program that
parses the tzdata information files and generates a type-safe pure API
for interacting with the tz data in memory. For example, given the
tzdata information files you would generate types, values and pure
functions such as the following:
data TimeZone
= Europe__Paris
| America__Buenos_Aires
| ...
timeZoneName :: TimeZone -> Text
timeZoneName Europe__Paris = "Europe/Paris"
timeZoneName America__Buenos_Aires = "America/Buenos_Aires"
timeZoneName ... = ...
timeZoneFromName :: Text -> Maybe TimeZone
timeZoneFromName "Europe/Paris" = Just Europe__Paris
timeZoneFromName "America/Buenos_Aires" = Just America__Buenos_Aires
timeZoneFromName ... = ...
timeZoneFromName _ = Nothing
timeZoneInfo :: TimeZone -> TZ
timeZoneInfo Europe_Paris = ... some hardcoded value (the `TZ` in
your library) ...
timeZoneInfo ... = ...
As a minor tidbit: If one is going to do this, I think a good idea is
to devise a package versioning system that's somewhat follows the tz
database versions. This is what I had in mind for the `tzdata` package
I was planning to create (unless someone else does it first):
The version number of the package is always @YYYYMMDD.B.C@, where
@YYYYMMDD@ are the year (@YYYY@), the month (@MM@) and the day (@DD@)
of the @tzdata@ release this particular version was designed for. For
example, @tzdata 2013i@ was officially released on @2013-12-17@, so a
version of this package that was designed for @tzdata 2013i@ will
carry the version number @20131217.B.C at . However, that doesn't mean
that this library won't work with versions of the @tzdata@ library
different than @2013i@, it's just that support for new or old data
(say, the name of a new time zone that was introduced) can be missing.
The @B@ and @C@ values in the version number of this library as
treated as the /major/ and /minor/ versions respectively, as suggested
in the /Haskell Package Version Policy/ page:
http://www.haskell.org/haskellwiki/Package_versioning_policy
Maybe the `timezone-olson`, `timezone-series`, this `tzdata` idea and
`tz` could all live together; with `tz` depending on the others? Just
a thought :)
Regards,
Renzo Carbonara.
On Mon, Mar 31, 2014 at 3:15 PM, Mihaly Barasz <klao at nilcons.com> wrote:
>
> I would like to propose reforming the 'time' [1] library.
>
>
> Initially, I was just planning to announce my new 'tz' [2] library, but
> realized that I have a more important agenda. Namely: Haskell needs a
> better time library!
>
> Let me summarize what are ‒ in my view ‒ the biggest deficiencies of
> 'time':
>
> 1. Inefficient data structures and implementations.
>
> 2. Ad-hoc API which is hard to remember and frustrating to work with.
>
> 3. Conceptually wrong representations and/or missing concepts.
>
> The wonderful thyme [3] package (by Liyang HU) improves a lot on #1 by
> choosing better data structures and careful implementations and on #2
> by lensifying the API.
>
> But, it was the #3 that caused me the most frustration lately; most
> importantly the time zone handling.
>
> There is a TimeZone data type in 'time', but it is a misnomer, it
> basically represents a fixed time difference (with a label and a DST
> flag). 'time' basically adapts the broken approach from libc: you can
> work with one time zone at a time, which is defined globally for your
> program (via the TZ environment variable). So, the transformation
> between UTCTime and LocalTime which should have been a pure
> function can only be done in IO now. Like this:
>
> do tz <- getTimeZone ut
> return $ utcToLocalTime tz ut
>
>
> Oh, and just to hammer down on the point #1 from the list above. This
> code runs in about 6100 ns on my machine. The drop-in replacement from
> tz: utcToLocalTimeTZ [4] (which is actually pure) runs in 2300 ns.
> While this is a significant improvement, it's easy to miss the point
> where the bulk of the inefficiency comes from the data structures. In
> my main project we represent times as Int64 (raw nanoseconds since
> UNIX epoch; and similar representation for zoned times). And to
> convert those to and from different time zones we need 40 ns. That's
> right, a 150 _times_ improvement! (There are many other interesting
> benchmark results that I could mention. An exciting bottom line: we
> can actually beat the libc in many use-cases!)
>
> The 'tz' package is still very much in flux. I will try to solidify
> the API soon, but until then it should be considered more of a proof
> of concept. There is some missing functionality, for example. On the
> other hand, there are the 'timezone-series' [5] and 'timezone-olson'
> [6] packages that together provide about the same functionality as
> 'tz' (minus the efficiency), and I'd like to explore if we could
> remove some of the overlap. But, all kind of suggestions and requests
> are welcome!
>
> More importantly, I'd like to hear the opinions of the community about
> the general issue of a better time library! Do we need one? How
> should we proceed about it? I think, Haskell could potentially have
> one of the best time libraries, but the current de-facto standard is
> mediocre at best. Unfortunately, designing a good time library is very
> far from trivial, as many existing examples demonstrate. And I
> definitely don't know enough for it. (I understand time zone info
> files, now that I wrote tz, but that's just a tiny fraction of what's
> needed.) So, if you think you can contribute to the design (have
> important use-cases in mind, know good examples of API, have some
> experience working with dates and time, etc. etc.) ‒ speak up!
>
>
> Mihaly
>
>
> Footnotes:
>
> [1] http://hackage.haskell.org/package/time
> [2] http://hackage.haskell.org/package/tz
> [3] http://hackage.haskell.org/package/thyme
> [4] http://hackage.haskell.org/package/tz-0.0.0.1/docs/Data-Time-Zones.html#v:utcToLocalTimeTZ
> [5] http://hackage.haskell.org/package/timezone-series
> [6] http://hackage.haskell.org/package/timezone-olson
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.6 (GNU/Linux)
>
> iQEVAwUBUzmwz/i5FOsZqz9DAQJGcAgAhPF4JLWnL4ApJ2qxqAwHqXcIPqRpVb5A
> TH2LERH2A/6b3xXCRYsPgyD43j2CzqZGffRvINSw9fGoJYWuRmis5dCf9hwPiKtg
> hK1wUCz9AsKlKBZztR9eLxROqM/xXMH4HaFydr/YOVffDVY6fUIK9fPbRFJBVCBq
> UwtoemQSVLUIIRxZyg5pdL+dxadnttm7bGC+UuQJHtSSBRweEh3unr8dcNm4idC3
> nxWOMclbo2hyMdwzDo1bqugugq2xCGPiGrL550aF1lCGD2pf2vQO1feW/5XyMaCR
> Oj6gI+eHo8SuhUx30Dokv1kx8Ssay0aVmmASCJKnR8Bwv1J9AKWo3A==
> =Bp64
> -----END PGP SIGNATURE-----
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
More information about the Haskell-Cafe
mailing list