How to get daylight saving status of another time zone
Let's say my Windows server application runs in an Eastern Time zone (NY).
I convert and store every datetime event (the moment they happen) in UTC, so that any client app that connects to the server reads the event's UTC time and converts and displays it in client's own TZ.
But here's the tricky part, some events report their timestamp in another state's time and doesn't explicitly specify daylight saving info (eg xx:xx:xx AM PT, meaning Pacific Time but I don't know if its currently in daylight saving time).
The server could check if it's in daylight saving period but that would be for server's own TZ (which is Eastern Time). The best I could come up with is to read the server's local daylight saving info and use that for PT as well but I know that's not 100% accurate. Especially thru the short window when ET has just started (or stopped) using daylight saving and PT has still hours to do so.
Now my question is, is there a way (in Windows API) to accurately find out about another time-zone's daylight saving status no matter which time zone the server app resides?
Edit: ok, how do I convert this to UTC "Sun, Mar 13, 2016 1:15 AM PT", from a Windows machine that runs in Eastern Time? (note that this date/time particularly selected when the running machine (in ET) is in DST at the moment and date/time to be converted is not just yet in DST. I have the UTC conversion covered but couldn't figure out if the given date/time is in DST or not.
Windows' Time Zone data is actually stored in the Registry:
HKLM
SOFTWARE
Microsoft
Windows NT
CurrentVersion
Time Zones
"Time Zones" is, in fact, two words.
Each Time Zone has its own subkey, and each subkey has a TZI
value that is a binary REG_TZI_FORMAT
structure:
typedef struct _REG_TZI_FORMAT
{
LONG Bias;
LONG StandardBias;
LONG DaylightBias;
SYSTEMTIME StandardDate;
SYSTEMTIME DaylightDate;
} REG_TZI_FORMAT;
The two relevant structure members are StandardDate
and DaylightDate
.
Refer to MSDN for more details: TIME_ZONE_INFORMATION
I'm not sure about the Windows API, but in general what you want to do is call mktime
, with the TZ value of your remote time in effect. Under Unix you can literally call setenv("TZ", whatever)
to do this. Not sure about Windows, but I think you can do the same sort of thing there, too.
It'd surely be nice if, besides mktime
and timegm
, there was a variant that let you specify the zone to use explicitly (rather than treating the TZ environment variable as a global variable), but such a variant is not standard.
When converting local times when you don't know whether DST is in effect or not, remember to set tm_isdst
to -1 so that the library will figure it out for you.
Here's an example:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
struct tm tm = {0};
time_t t;
tm.tm_hour = 12; tm.tm_min = 30, tm.tm_sec = 15; /* 12:30:15 */
tm.tm_year = 2005-1900; tm.tm_mon = 4-1; tm.tm_mday = 12; /* 2005-04-12 */
tm.tm_isdst = -1;
setenv("TZ", "America/Los_Angeles", 1);
t = mktime(&tm);
setenv("TZ", "America/New_York", 1);
printf("%ld = %.24sn", t, ctime(&t));
}
This tells you that the Los Angeles time 12:30:15 corresponds to the Unix (UTC) time 1113334215 and to the New York time 15:30:15.
Addendum: this won't help for Windows, either, but if you don't like setting an environment variable from inside your program every time you need to work with a time in a different time zone, see if you can use the BSD functions tzalloc
, localtime_rz
, and mktime_z
.
上一篇: 城市夏令时数据库
下一篇: 如何获得其他时区的夏令时状态