# Time zone explorations

**URL:** <https://discourse.elm-lang.org/t/time-zone-explorations/1837>\
**Category:** Show and Tell\
**Created:** [August 31, 2018, 2:29pm UTC](https://discourse.elm-lang.org/t/time-zone-explorations/1837 "2018-08-31T14:29:03Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![justinmimbs](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/justinmimbs/32/48_2.png) [@justinmimbs](https://discourse.elm-lang.org/u/justinmimbs)\
**Post date:** [August 31, 2018, 2:29pm UTC](https://discourse.elm-lang.org/t/time-zone-explorations/1837/1 "2018-08-31T14:29:03Z")

</div>

I’ve explored two approaches for getting `Time.Zone` values to use with `elm/time`, both of which use the IANA Time Zone Database (TZ).

* * *

To be clear, the use case is that you have `Posix` values and you want to extract parts from them in some local time, not just UTC.

Often you have UTC timestamps that you just need to display nicely formatted in the client’s local time zone. For this, it’s possible to push the job out to custom elements, like Github’s [time-elements](https://github.com/github/time-elements).

The following, however, are ways of getting time zone data into Elm.

* * *

### 1. Fetch only the zone data you need at runtime

Since Elm targets web browsers, this seems a natural fit.

The [timezone-json](https://github.com/justinmimbs/timezone-json) repo contains a script you can use to build a set of JSON files from (the compiled artifacts of) the TZ database. It also contains Elm examples of fetching and decoding them to `Time.Zone` values.

### 2. Include the time zone database in your compiled asset

This sounds a little crazy, but I can imagine use cases for this, and once minified and gzipped it only adds 18 KB.

The [timezone-data](https://package.elm-lang.org/packages/justinmimbs/timezone-data/latest/) package allows this. Data in the package is generated by a script that converts (the source files of) the TZ database to Elm source; each zone must be “unpacked” to get a `Time.Zone` value. The unpacked `Time.Zone` values match exactly those built from the `timezone-json` approach above.

* * *

With both of these, the `Time.Zone` values only cover changes between 1970 and 2037.

Each of the links above should contain examples to get you started, but please let me know if you have questions.

---

<div class="post-metadata">

**Author:** ![stephenreddek](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/stephenreddek/32/3368_2.png) [@stephenreddek](https://discourse.elm-lang.org/u/stephenreddek)\
**Post date:** [September 4, 2018, 6:44pm UTC](https://discourse.elm-lang.org/t/time-zone-explorations/1837/2 "2018-09-04T18:44:45Z")

</div>

I really like what you’ve done here! I’ve been using `elm-community/elm-time`, but I’m working on using the `timezone-data` for my upgraded 0.19 app.

There are two things that I can’t figure out how to do between this library and the core `Time`:

1. Get the zone name (ie `America/Chicago`) for a given time zone (I only see a way to do it for _my_ timezone)
2. Get the zone abbreviation (`CDT` or `CST`) for a given zone and time

Do you see these as being handled by your library in the future or in a separate package? I don’t know if it’s possible to add the name and abbreviations in the same way that it was handled in `elm-time` or not.

Again, thank you for working on this problem as well as the `Date` package!

---

<div class="post-metadata">

**Author:** ![Qqwy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/qqwy/32/1062_2.png) [@Qqwy](https://discourse.elm-lang.org/u/Qqwy)\
**Post date:** [September 4, 2018, 7:07pm UTC](https://discourse.elm-lang.org/t/time-zone-explorations/1837/3 "2018-09-04T19:07:40Z")

</div>

Wow, only 18 Kb? That is a lot less than I had expected!

Of course, a disadvantage of that is that new timezone changes will require a recompilation of your application, but it’s still really nice.

Great work!

---

<div class="post-metadata">

**Author:** ![justinmimbs](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/justinmimbs/32/48_2.png) [@justinmimbs](https://discourse.elm-lang.org/u/justinmimbs)\
**Post date:** [September 4, 2018, 8:50pm UTC](https://discourse.elm-lang.org/t/time-zone-explorations/1837/4 "2018-09-04T20:50:01Z")

</div>

Thank you, Stephen!

The `Zone` in `elm/time` doesn’t store a zone name (e.g. `America/Chicago`). But the `TimeZone.getZone` task returns the local zone name too so that you can store it if you’d like to. And if you happen to get zone names at runtime in some other way, then you can look up zone data in the [`TimeZone.Data.packs`](https://package.elm-lang.org/packages/justinmimbs/timezone-data/latest/TimeZone-Data#packs) dictionary. In these cases you already have the zone name, so it’s not essential that `Zone` store a name.

And `Zone` doesn’t store zone abbreviation (e.g. `CST`, `CDT`) changes. The goal of this library was to provide `Zone` values, so it’s not something I had yet considered handling in another way.

---

<div class="post-metadata">

**Author:** ![avh4](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/avh4/32/97_2.png) [@avh4](https://discourse.elm-lang.org/u/avh4)\
**Post date:** [September 5, 2018, 3:08am UTC](https://discourse.elm-lang.org/t/time-zone-explorations/1837/5 "2018-09-05T03:08:09Z")

</div>

This looks great!

Can I ask, why is there a `Pack` type at all? (It doesn’t seem to be used for anything except unpacking?) Why doesn’t TimeZone.Data.\* just give the Zones? (Or possibly all be `() -> Zone` to avoid compuation/memory usage?)

Also, looking at the `elm/time` API, it looks like there’s no function to get all the human info at once (toYear/toMonth/toDay/… are all separate functions). Doesn’t that mean that if you want to show all fields it’s doing a lot of duplicate work to process the Zone?

---

<div class="post-metadata">

**Author:** ![justinmimbs](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/justinmimbs/32/48_2.png) [@justinmimbs](https://discourse.elm-lang.org/u/justinmimbs)\
**Post date:** [September 5, 2018, 1:28pm UTC](https://discourse.elm-lang.org/t/time-zone-explorations/1837/6 "2018-09-05T13:28:47Z")

</div>

Thanks, Aaron!

That’s a great idea to use thunks to simplify the API. Right, the reason for `Pack` was to avoid the cost of unpacking hundreds of Zones on page load, but you’re right, each zone could simply be a `() -> Zone` function instead. I’m glad you asked!

And yes, if you get N parts from the same `Zone` and `Posix`, then the offset is looked up from the `Zone` N times. Currently that lookup involves scanning an ordered list of transition times until a time \< the posix time is found.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [September 15, 2018, 1:28pm UTC](https://discourse.elm-lang.org/t/time-zone-explorations/1837/7 "2018-09-15T13:28:53Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
