How can I parse tzdata database (published by IANA, or by operating system vendors) to get historical timezone information?
For example I would like to know what was the time offset to GMT in Asia/Tokyo
at a specific point in time like 1435100000
which was actually 2015-04-25T22:13:20+00:00 (UTC)
You don't usually need to parse the data files yourself to answer this kind of question.
Under most versions of Unix and Linux, this program will give you the time offset you're looking for:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
time_t t = 1435100000;
struct tm *tmp;
setenv("TZ", "Asia/Tokyo", 1);
tzset();
tmp = localtime(&t);
printf("offset = %ld\n", tmp->tm_gmtoff);
}
Unfortunately, the tm_gmtoff
field which this program relies on, though massively useful, is nonstandard. (Under some versions of Unix it may be named _tm_gmtoff
. Under some versions it may not exist at all.) If you don't have tm_gmtoff
available, or if you need your code to be as portable as possible, you can use this trick instead:
time_t t2;
tmp = gmtime(&t);
t2 = mktime(tmp);
printf("offset = %ld\n", t - t2);
For Unix, Linux, MacOS, and any platform using the IANA code and data, programs like these should give the correct result for any time zone and any time since January 1, 1970.
For times before January 1, 1970, the ordinary IANA data is not comprehensive, so if you need to work with older dates and times, you may need to do something different. (The IANA data does have some coverage of pre-1970 time zone rules, but it's not as comprehensive and does not claim to be definitive.)
As I understand it, the date and time code under Windows does not keep historical time zone information, and always uses the current year's rules for any historical date, so under Windows you might need to write your own code, or obtain and compile the IANA code. (But you still shouldn't need to parse any data files by hand.)