Time zone offset of future dates?

The Time.here function in elm/time has the following note:

[…] This means the Zone you get from this function will act weird if (1) an application stays open across a Daylight Saving Time boundary or (2) you try to use it on historical data.

I assume this applies to future dates as well? Time.here calculates the offset using -(new Date().getTimezoneOffset()) which means that you get the current offset. To get the offset of a timestamp in the future, I believe I need to provide new Date with the timestamp like this:


-(new Date(1638313199).getTimezoneOffset())

First question: Is my assumption correct?

Second question: Have you solved this problem in another way?

justinmimbs/timezone-data suggests looking into GitHub - github/relative-time-element: Web component extensions to the standard <time> element. for my use case, displaying future events dates in a nice format. I will try out time-elements but I’m curious to know about your experience in this subject.

If you need to model something like “this should happen exactly 24 hours from now” (an absolute amount of time after a past point) then you can calculate the Unix timestamp (seconds since 1970 or whatever) and store that.

If you need to model something like “15:00 on 2023-02-20” (a certain wall clock time in the future) then you also need to think about where in addition to when. Let’s say this is in Stockholm, Sweden. Then you could store “15:00 on 2023-02-20 in Stockholm/Sweden”. You can’t, however, store “15:00 on 2023-02-20 at UTC+1”. Well you could, but there has been talk about switching to summer time all year around in Sweden, which would be UTC+2. You can’t know what time zone will be used at a certain place in the future, so it’s better to store the place, I’d say.

Also don’t forget that some countries have multiple time zones, so it’s important to save a city as well.

I’m not sure if this helps, but those were some things I thought of!

1 Like

Hej @lydell! :slight_smile: I use UNIX timestamps everywhere so that shouldn’t be a problem. But let me explain my problem with an example:

https://ellie-app.com/fz72RrHXz37a1

In the ellie app, I simulate Time.here of today, 2021-10-14, in Sweden (GMT+2 or 120 minutes).

I want to display the month “Nov” from 1638313199 (Tue Nov 30 2021 23:59:59 GMT+0100).

This fails since Time.toMonth uses the current offset of 120 instead of the correct 60 (It’s wintertime on 2021-11-30 Sweden)

Now, one way to solve this is to have a Time.hereFromTimestamp function that takes my timestamp into account. I was hoping that more people would have had this problem before and could give me some input on how solve this problem.

As far as I know there is no time zone data in the browser. Just the current time zone and UTC. (There might be some API coming, but I don’t think there’s any as of now.)

You can try using timezone-data 5.1.0 which contains all time zones in the IANA Database.

If you just need to support Sweden you could try to calculate when summer time starts and ends each year. I did that in SQL quite recently and it was doable but a bit fiddly.

The Time.customZone function you are using accepts a list of offsets along with timestamps for when the that offset takes effect. These can be for both historical or future changes.

For example you might do:

swedishTime : Time.Zone
swedishTime =
    Time.customZone 120
        [ { start = 27261180, offset = 60 }    -- after Oct 31, 2021
        , { start = 27036180, offset = 120 }   -- after May 28, 2021
        ]

Do note that the values for future time are subject to change at any moment (e.g. the government might decide to skip daylight savings time this year, or it might decide to change timezones).

Using the Swedish timezone above, I was able to fix your Ellie to correctly show “Nov” https://ellie-app.com/fz8CsJXkp36a1

1 Like

Note though that the rule in Sweden is that summer time starts the last Sunday of March and ends the last Sunday of October. So the dates in your example are not correct, and would have to be calculated anyway.

I copied the start dates for the offsets from Time changes in Sweden and misread Mar as May :man_facepalming:

I don’t think I need to calculate the future offset.

I might be missing something but wouldn’t this be sufficient? The first line is basically what Time.here does. I can use ports in order to run the later one but I wonder if there is something I am missing?

I’m surprised that Elm does not include the later one, if it is this easy. Which makes me believe that there is something that I don’t understand.

3 Likes

Oh wow! I had no idea .getTimezoneOffset() worked that way! You seem to be right:

My guess would be that this is an oversight in Elm.

Edit: Possibly related: Time.here practically useless · Issue #28 · elm/time · GitHub

Good find! This issue is spot on, Time.here is indeed actually Time.hereAndNow.

I’ve pondered this issue for a few days and there are a few options from what I can understand:

1. Let the backend provide the timezone offset and every change reasonably far from now(), both future and past. Feed it to Time.customZone.

Doable but fiddly as you say. Could use the min and max timestamp from the database result to know what a reasonable timeframe is. Not the most attractive solution in my opinion. The request must include a timezone (i.e. “Europe/Stockholm”), a logged-in user setting, or a fallback. Intl.DateTimeFormat().resolvedOptions().timeZone is supported in all evergreen browsers.

2. Let the backend respond with a tuple of timestamp and offset instead of just the timestamp.

Maybe a bit simpler at the first glance. Again, the request must include a timezone (i.e. “Europe/Stockholm”), a logged-in user setting, or a fallback.

3. Let a port calculate the correct offset for every timestamp

Doable but it seems like too much work, I would prefer to have the offset included in the decoded response instead of running every entry through a port as an afterthought.

4. Hand the timestamp off to a custom element like github/time-elements

The most attractive option to me right now. Intl has enough support for my use case and I like the idea of letting the browser do the hard part. The backend can stay completely unchanged. Unfortunately, github/time-elements only seem to handle ISO 8601 timestamps. The first thing they do though is to transform the string into a UNIX timestamp. Most probably their backend returns timestamps as ISO 8601.

Any feedback or more ideas?

1 Like

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