8 #include <msp/strings/format.h>
9 #include <msp/core/systemerror.h>
10 #include "timestamp.h"
19 using Msp::Time::TimeZone;
22 long get_long(char *&ptr)
25 for(unsigned i=0; i<4; ++i)
26 result = (result<<8)+static_cast<unsigned char >(*ptr++);
31 TimeZone get_local_timezone()
34 TIME_ZONE_INFORMATION tzinfo;
35 DWORD dst = GetTimeZoneInformation(&tzinfo);
36 if(dst==TIME_ZONE_ID_INVALID)
37 throw Msp::system_error("GetTimeZoneInformation");
39 int offset = tzinfo.Bias;
40 if(dst==TIME_ZONE_ID_STANDARD)
41 offset += tzinfo.StandardBias;
42 else if(dst==TIME_ZONE_ID_DAYLIGHT)
43 offset += tzinfo.DaylightBias;
45 return TimeZone(offset);
47 int fd = open("/etc/localtime", O_RDONLY);
51 int len = read(fd, hdr, sizeof(hdr));
54 if(len==44 && hdr[0]=='T' && hdr[1]=='Z' && hdr[2]=='i' && hdr[3]=='f')
57 long isgmtcnt = get_long(ptr);
58 long isstdcnt = get_long(ptr);
59 long leapcnt = get_long(ptr);
60 long timecnt = get_long(ptr);
61 long typecnt = get_long(ptr);
62 long charcnt = get_long(ptr);
63 int size = timecnt*5+typecnt*6+isgmtcnt+isstdcnt+leapcnt*8+charcnt;
64 char *buf = new char[size];
65 len = read(fd, buf, size);
70 time_t cur_time = Msp::Time::now().to_unixtime();
71 for(int i=0; i<timecnt; ++i)
72 if(get_long(ptr)<=cur_time)
80 for(int i=0; i<typecnt; ++i)
82 if((index>=0 && i==index) || (index<0 && !ptr[4] && gmtoff==-1))
84 gmtoff = get_long(ptr);
99 return TimeZone(gmtoff/60, name);
110 TimeZone::TimeZone():
114 TimeZone::TimeZone(int minutes):
119 int m = abs(minutes);
120 name = format("UTC%c%d", (minutes<0 ? '-' : '+'), m/60);
122 name += format(":%02d", m%60);
128 TimeZone::TimeZone(int minutes, const string &n):
133 const TimeZone &TimeZone::utc()
135 static TimeZone tz(0);
139 const TimeZone &TimeZone::local()
141 static TimeZone tz = get_local_timezone();