X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Ftime%2Ftimezone.cpp;h=43d6d101c723ab760dcaae20db659a3f09dfa451;hp=fd2487b6475600412ca42700aa59cf36d58b7299;hb=efa772f72195ab4aaf7dfb880e27bf0e07195d65;hpb=3fd9d04e84cdd72aabe8f9878f9e8ff006275bb6 diff --git a/source/time/timezone.cpp b/source/time/timezone.cpp index fd2487b..43d6d10 100644 --- a/source/time/timezone.cpp +++ b/source/time/timezone.cpp @@ -1,16 +1,23 @@ /* $Id$ This file is part of libmspcore -Copyright © 2008 Mikko Rasa, Mikkosoft Productions +Copyright © 2008-2009 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ #include #include #include -#include +#ifdef WIN32 +#include +#else +#include +#endif +#include "../core/except.h" +#include "timestamp.h" #include "timezone.h" #include "units.h" +#include "utils.h" using namespace std; @@ -18,13 +25,23 @@ namespace { using Msp::Time::TimeZone; +#ifndef WIN32 +long get_long(char *&ptr) +{ + long result=0; + for(unsigned i=0; i<4; ++i) + result=(result<<8)+static_cast(*ptr++); + return result; +} +#endif + TimeZone get_local_timezone() { #ifdef WIN32 TIME_ZONE_INFORMATION tzinfo; DWORD dst=GetTimeZoneInformation(&tzinfo); if(dst==TIME_ZONE_ID_INVALID) - throw SystemError("Failed to get time zone information", GetLastError()); + throw Msp::SystemError("Failed to get time zone information", GetLastError()); int offset=tzinfo.Bias; if(dst==TIME_ZONE_ID_STANDARD) @@ -34,8 +51,60 @@ TimeZone get_local_timezone() return TimeZone(offset); #else - tzset(); - return TimeZone(timezone/60); + int fd=open("/etc/localtime", O_RDONLY); + if(fd>=-1) + { + char hdr[44]; + int len=read(fd, hdr, sizeof(hdr)); + long gmtoff=-1; + string name; + if(len==44 && hdr[0]=='T' && hdr[1]=='Z' && hdr[2]=='i' && hdr[3]=='f') + { + char *ptr=hdr+20; + long isgmtcnt=get_long(ptr); + long isstdcnt=get_long(ptr); + long leapcnt=get_long(ptr); + long timecnt=get_long(ptr); + long typecnt=get_long(ptr); + long charcnt=get_long(ptr); + int size=timecnt*5+typecnt*6+isgmtcnt+isstdcnt+leapcnt*8+charcnt; + char buf[size]; + len=read(fd, buf, size); + if(len==size) + { + ptr=buf; + int index=-1; + time_t cur_time=Msp::Time::now().to_unixtime(); + for(int i=0; i0) + index=ptr[index]; + ptr+=timecnt; + + int abbrind=0; + for(int i=0; i=0 && i==index) || (index<0 && !ptr[4] && gmtoff==-1)) + { + gmtoff=get_long(ptr); + ++ptr; + abbrind=*ptr++; + } + else + ptr+=6; + } + + name=ptr+abbrind; + } + } + close(fd); + + if(gmtoff!=-1) + return TimeZone(-gmtoff/60, name); + } + return TimeZone(); #endif } @@ -64,6 +133,11 @@ TimeZone::TimeZone(int minutes_west): name="UTC"; } +TimeZone::TimeZone(int minutes_west, const string &n): + name(n), + offset(minutes_west*min) +{ } + const TimeZone &TimeZone::utc() { static TimeZone tz(0);