3 /// Timezone adjustment class, wrapping the TZ environment
4 /// variable to make struct tm -> time_t conversions easier.
8 Copyright (C) 2010, Chris Frey <cdfrey@foursquare.net>, To God be the glory
9 Released to the public domain.
10 Included in Barry and Barrified the namespace July 2010
13 #include "tzwrapper.h"
17 namespace Barry
{ namespace Sync
{
19 time_t utc_mktime(struct tm
*utctime
)
24 // loop, converting "local time" to time_t and back to utc tm,
25 // and adjusting until there are no differences... this
26 // automatically takes care of DST issues.
28 // do first conversion
31 result
= mktime(&tmp
);
32 if( result
== (time_t)-1 )
34 if( gmtime_r(&result
, &check
) == NULL
)
38 while( check
.tm_year
!= utctime
->tm_year
||
39 check
.tm_mon
!= utctime
->tm_mon
||
40 check
.tm_mday
!= utctime
->tm_mday
||
41 check
.tm_hour
!= utctime
->tm_hour
||
42 check
.tm_min
!= utctime
->tm_min
)
44 tmp
.tm_min
+= utctime
->tm_min
- check
.tm_min
;
45 tmp
.tm_hour
+= utctime
->tm_hour
- check
.tm_hour
;
46 tmp
.tm_mday
+= utctime
->tm_mday
- check
.tm_mday
;
47 tmp
.tm_year
+= utctime
->tm_year
- check
.tm_year
;
50 result
= mktime(&tmp
);
51 if( result
== (time_t)-1 )
53 gmtime_r(&result
, &check
);
54 if( gmtime_r(&result
, &check
) == NULL
)
61 struct tm
* iso_to_tm(const char *timestamp
,
65 memset(result
, 0, sizeof(struct tm
));
68 int found
= sscanf(timestamp
, "%04d%02d%02dT%02d%02d%02d%c",
69 &(result
->tm_year
), &(result
->tm_mon
), &(result
->tm_mday
),
70 &(result
->tm_hour
), &(result
->tm_min
), &(result
->tm_sec
),
73 result
->tm_year
-= 1900;
75 result
->tm_isdst
= -1;
77 utc
= (found
== 7 && zflag
== 'Z');
79 return (found
>= 6) ? result
: 0;
82 time_t TzWrapper::iso_mktime(const char *timestamp
)
86 if( !iso_to_tm(timestamp
, &t
, utc
) )
91 return tzw
.mktime(&t
);
94 }} // namespace Barry::Sync
100 using namespace Barry::Sync
;
103 time_t now
= time(NULL
);
105 cout
<< "TZ: " << TzWrapper().ctime(&now
);
106 cout
<< "UTC: " << TzWrapper("").ctime(&now
);
107 cout
<< "UTC: " << TzWrapper().SetUTC().ctime(&now
);
108 cout
<< "SysLocaltime: " << TzWrapper().SetUTC().SetSysLocal().ctime(&now
);
109 cout
<< "TZ: " << TzWrapper().SetUTC().SetDefault().ctime(&now
);
110 cout
<< "Canada/Eastern: " << TzWrapper("Canada/Eastern").ctime(&now
);
111 cout
<< "Canada/Pacific: " << TzWrapper("Canada/Pacific").ctime(&now
);
114 TzWrapper
tzw("UTC");
115 cout
<< "UTC: " << ctime(&now
);
118 cout
<< "TZ: " << ctime(&now
);
120 // test iso_mktime()... the test values assume a Canada/Eastern TZ
121 cout
<< "Using Canada/Eastern:" << endl
;
122 TzWrapper
tzw("Canada/Eastern");
123 const char *iso1
= "20100430T231500";
124 const char *iso2
= "20100501T031500Z";
125 time_t t1
= TzWrapper::iso_mktime(iso1
);
126 time_t t2
= TzWrapper::iso_mktime(iso2
);
127 cout
<< " " << iso1
<< ": (" << t1
<< ") " << ctime(&t1
);
128 cout
<< iso2
<< ": (" << t2
<< ") " << ctime(&t2
);
130 if( TzWrapper::iso_mktime("20100430") == (time_t)-1 )
131 cout
<< "Fail check: passed" << endl
;
133 cout
<< "Fail check: ERROR" << endl
;