Following on from my hard and easy way of getting timezone from an IP address, having the timezone (as text) is one thing, now finding the actual offset is entirely a different problem.

READER DISCOUNTSave $50 on terminal.training

I've published 38 videos for new developers, designers, UX, UI, product owners and anyone who needs to conquer the command line today.

TL:DR; jump to the spoiler if you can't be bothered to read/listen to me ramble!

The problem isn't timezones, it's day light saving

It's all very well knowing what timezone a particularly location is sitting on. We can show the user the UTC time, but when it doesn't match the wall clock because they're currently observing DST, then it's just…weird.

So now we need to know if the location is observing DST, or not. Or if perhaps they never observe DST (like Hawaii).

The long hard way

There is the IANA timezone dataset which has custom data structures that describe the location and how time is observed in that location for that particular date. Which is very cool because you can say: for the Ukraine, in 1921 on Thursday 5th July - were they observing DST or not.

There's a library in Python that does read this data straight off the shelf, but I couldn't find anything for JavaScript, so I went about parsing it myself.

The documentation is generally pretty useful, describing the structures:

From the source file

#Rule NAME    FROM TO    -   IN  ON      AT   SAVE LETTER
Rule  Chicago 1920 only  -   Jun 13      2:00 1:00 D
Rule  Chicago 1920 1921  -   Oct lastSun 2:00 0    S
Rule  Chicago 1921 only  -   Mar lastSun 2:00 1:00 D
Rule  Chicago 1922 1966  -   Apr lastSun 2:00 1:00 D
Rule  Chicago 1922 1954  -   Sep lastSun 2:00 0    S
Rule  Chicago 1955 1966  -   Oct lastSun 2:00 0    S

Reformatted

From To On At Action
1920 only June 13th 02:00 local go to daylight saving time
1920 1921 last Sunday in October return to standard time
1921 only in March go to daylight saving time
1922 1966 in April
1954 in September return to standard time
1955 1966 in October

I got fairly far, but hadn't implemented the lastSun, firstMon, Sun>=8 syntax (do drop a comment if you think this library might be useful).

The reason I stopped was because I remembered there was a way in literally a single line of code: Temporals.

Temporal API: working with dates and times

The JavaScript Date API is, in my own opinion, one of the worst parts of JavaScript. The temporal API does a massive overhaul of date and time processing, and, it so happens, it can give me whether a datetime is in DST for a given timezone.

Temporal.Now.instant().toZonedDateTimeISO("Europe/London").offset;
// => "+01:00"

Just like that, I've got my timezone offset lookup. Although, since both Node and Deno (since I was using Netlify Edge functions which use Deno) doesn't have the API natively, I need to load the polyfill first:

import { Temporal } from 'https://esm.sh/@js-temporal/polyfill';

And that was it. Two extra lines gave me the timezone offset: days-to-xmas (source).