7 #include <msp/strings/format.h>
8 #include <msp/core/systemerror.h>
18 using Msp::Time::TimeZone;
21 long get_long(char *&ptr)
24 for(unsigned i=0; i<4; ++i)
25 result = (result<<8)+static_cast<unsigned char >(*ptr++);
30 TimeZone get_local_timezone()
33 TIME_ZONE_INFORMATION tzinfo;
34 DWORD dst = GetTimeZoneInformation(&tzinfo);
35 if(dst==TIME_ZONE_ID_INVALID)
36 throw Msp::system_error("GetTimeZoneInformation");
38 int offset = tzinfo.Bias;
39 if(dst==TIME_ZONE_ID_STANDARD)
40 offset += tzinfo.StandardBias;
41 else if(dst==TIME_ZONE_ID_DAYLIGHT)
42 offset += tzinfo.DaylightBias;
44 return TimeZone(offset);
46 int fd = open("/etc/localtime", O_RDONLY);
50 int len = read(fd, hdr, sizeof(hdr));
53 if(len==44 && hdr[0]=='T' && hdr[1]=='Z' && hdr[2]=='i' && hdr[3]=='f')
56 long isgmtcnt = get_long(ptr);
57 long isstdcnt = get_long(ptr);
58 long leapcnt = get_long(ptr);
59 long timecnt = get_long(ptr);
60 long typecnt = get_long(ptr);
61 long charcnt = get_long(ptr);
62 int size = timecnt*5+typecnt*6+isgmtcnt+isstdcnt+leapcnt*8+charcnt;
64 len = read(fd, buf, size);
69 time_t cur_time = Msp::Time::now().to_unixtime();
70 for(int i=0; i<timecnt; ++i)
71 if(get_long(ptr)<=cur_time)
79 for(int i=0; i<typecnt; ++i)
81 if((index>=0 && i==index) || (index<0 && !ptr[4] && gmtoff==-1))
83 gmtoff = get_long(ptr);
97 return TimeZone(gmtoff/60, name);
108 TimeZone::TimeZone():
112 TimeZone::TimeZone(int minutes):
117 int m = abs(minutes);
118 name = format("UTC%c%d", (minutes<0 ? '-' : '+'), m/60);
120 name += format(":%02d", m%60);
126 TimeZone::TimeZone(int minutes, const string &n):
131 const TimeZone &TimeZone::utc()
133 static TimeZone tz(0);
137 const TimeZone &TimeZone::local()
139 static TimeZone tz = get_local_timezone();