The Servers, the Timezones and Me

So I’m trying to write a web-based app that tracks when something happens. You click a button, and the web app records when you clicked it.

Sounds easy, no?

The problem is timezones. I live in Australia, and the web server is in the USA. So if I click a button at 8pm (in Australia), the web server records the click at 1am (in California). Or possibly 2am or 3am in California, depending on who’s in Daylight Savings and who isn’t. Other users of my app could be in any country in any timezone in the world.

So the obvious answer is to record the time of the click in the server’s database in UTC, and translate that into the user’s timezone in PHP (or .net or whatever) before you send the HTML to the user’s browser. Easy, huh? You just need to know the user’s timezone.

So how does the server get to know the user’s timezone?

Well … there is one easy way, and that’s to ask the user when they sign up, possibly with a bloody great big drop-down menu. Simple – but ugly. It’s 2014, for Pete’s sake. Your phone has orders of magnitude more processing power than the computer that sent humans to the moon, it probably has a GPS built in, surely to goodness it’s possible to get the timezone automatically?

I assumed I could use the user’s IP number to get a (rough) latitude and longitude and use that to get a timezone … but if such a service exists (for free and currently supported), I didn’t find it.

Side note – I’m very keen to have a clean, simple interface. I’m using Facebook logins to save having to handle user registration, lost passwords, etc etc, and I’m looking for simple use cases and process flows. I really don’t want to have to stop the user part-way through the registration process just to get them to pick their timezone from a bloody great big list. Though it’s getting to look like one of the less ugly options…

Plan B is to ask the browser (which always knows, and a quick bit of Javascript can get the info for you). But how to get it from the browser into the server where it is needed? The timezone isn’t sent with the HTTP request header to the server, so the first page a user sees needs to ask the browser for the timezone via javascript, then bounce the user to a new page (including the timezone in a GET or POST) … which is possible, but it’s an extra page request … and, well, it’s just ugly. And you can’t do it once at registration and then keep it forever, because it’s only the offset not the timezone, so you’ll need to re-check once every session, in case daylight savings has started (or the user took their phone or laptop to another state).

The most elegant solution I’ve been able to come up with (well, least inelegant) is to not bother with timezones on the sever at all, and just store all dates in UTC and send them to the browser in UTC like <date timestamp="2014-11-09T10:37:27Z"></date>, and then use a jQuery loop on the browser to search through all <date> elements, load the timestamp property, use something like Moment.js to translate it to the local timezone and format it nicely, then replace the <date> element’s HTML with the formatted date string.

Not exactly elegant, but perhaps less ugly than some other options. But boy, this is dumb. Surely I’m not the only developer to ever want a web app to be able to handle timezones gracefully. Ugh.

…and later…

So I took a took a deep breath and slept on it, and discovered that Facebook gives the user’s timezone offset. (I’m using Facebook logins so that I don’t need to bother with authenticating users, handling lost passwords, etc etc.)

It doesn’t give the actual timezone, but it does give the offset, updated every time you get a new session. So I figured that’s good enough. Now I just have to think about storing and using dates in a timezone-aware fashion in MySQL and PHP

Advertisements
The Servers, the Timezones and Me

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s