2015-10-07

Timezone related bugs

Since Sagittarius 0.6.7, it has timezone object. The rationale behind this is pretty simple. Before it used localtime and some other C APIs to get proper local timezone offset. I wasn't unhappy until I needed to handle other timezone offsets. I don't remember exact situation but related to time conversion. Unfortunately, on POSIX there is no way to treat timezone as objects (as far as I could research), so I've decided to implement own timezone handling.

Timezone is related to physical location. Of course, you can change your computer's setting to deceive yourself. I wasn't one of those people and that bit me. I've faced 2 timezone related bugs. Both could only happen in particular places, Japan and country where no summer time. Let me share the bug story. Starting from the first one.

There is IANA TZ database and I'm using it to find proper timezone offset. If you build Sagittarius from repository, then the pre-build process, not cmake but dist.sh, downloads TZ database and compiles it to S-expression. It's not too bad. The only bad thing is that it can't handle any rules not written in the TZ database, such as Japan.

Asia/Tokyo timezone has rather weird rules. According to the TZ database, Japan had summer time between 1948-1951. On the comment, it clearly says this is used only on US military base, for your information, so officially Japan didn't have it, though. Funny thing is that this rule, named Japan, is associated to Asia/Tokyo timezone and it's active now (2015 current). Additionally, the rule doesn't have definition of after 1951. So what should happen? Maybe I didn't read all the comment or how the rules defined properly so I missed something. Anyway, the previous behaviour of handling this situation was signaling an error. Which, of course, caused problem. The biggest one was Sagittarius couldn't be built in Japan.

Thanks to the comment on this blog, I could notice there was such a problem. Other than that, this would stay until I'd decide to go back to Japan. The fix was rather simple, instead of signaling an error, it simply returns default timezone offset without considering old timezone offset. I think that's good enough. (NB: the timezone object would consider the when, means if you ask timezone offset of before 1835 in the Netherlands, then it would return GMT+0:19:32. No need for this? just for fun.)

The second one was rather stupid mistake. Again it was in Japan. I've found a tweet that said time-utc->date didn't consider timezone offset but just return UTC. I saw this when I fixed the first bug so I thought it might be related. Well, kinda but not quite. This bug happened only on Windows (including Cygwin) running on a timezone without summer time (Japan for example).

The reproducing was one easy step. Change system timezone to 'Osaka, Sapporo, Tokyo' then get local timezone. Aha, it returned UTC. But why? Well, very simple. To get local timezone name on Windows (and Cygwin), Sagittarius uses GetTimeZoneInformation and check the return code. If the return code was not TIME_ZONE_ID_UNKNOWN then it returns standard timezone name, otherwise UTC. Hey, MSDN says if the timezone doesn't have summer time then this return code would be returned! That's why if it's in Japan, it returned always UTC. Careless (or stupid) mistake.

Even though I'm using CI services for Linux, Windows and OS X, this type of physical location related bugs are really hard to find. (Not even sure if I can change system timezone per build on the services) I've just seen importance of feedback in a fresh light.

08 Oct 2015
typo fix. the light wasn't from jewel meat...

No comments:

Post a Comment