tzwrapper.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "tzwrapper.h"
00014 #include <string.h>
00015 #include <stdio.h>
00016
00017 namespace Barry { namespace Sync {
00018
00019 time_t utc_mktime(struct tm *utctime)
00020 {
00021 time_t result;
00022 struct tm tmp, check;
00023
00024
00025
00026
00027
00028
00029 tmp = *utctime;
00030 tmp.tm_isdst = -1;
00031 result = mktime(&tmp);
00032 if( result == (time_t)-1 )
00033 return (time_t)-1;
00034 if( gmtime_r(&result, &check) == NULL )
00035 return (time_t)-1;
00036
00037
00038 while( check.tm_year != utctime->tm_year ||
00039 check.tm_mon != utctime->tm_mon ||
00040 check.tm_mday != utctime->tm_mday ||
00041 check.tm_hour != utctime->tm_hour ||
00042 check.tm_min != utctime->tm_min )
00043 {
00044 tmp.tm_min += utctime->tm_min - check.tm_min;
00045 tmp.tm_hour += utctime->tm_hour - check.tm_hour;
00046 tmp.tm_mday += utctime->tm_mday - check.tm_mday;
00047 tmp.tm_year += utctime->tm_year - check.tm_year;
00048 tmp.tm_isdst = -1;
00049
00050 result = mktime(&tmp);
00051 if( result == (time_t)-1 )
00052 return (time_t)-1;
00053 gmtime_r(&result, &check);
00054 if( gmtime_r(&result, &check) == NULL )
00055 return (time_t)-1;
00056 }
00057
00058 return result;
00059 }
00060
00061 struct tm* iso_to_tm(const char *timestamp,
00062 struct tm *result,
00063 bool &utc)
00064 {
00065 memset(result, 0, sizeof(struct tm));
00066 char zflag = 0;
00067
00068 int found = sscanf(timestamp, "%04d%02d%02dT%02d%02d%02d%c",
00069 &(result->tm_year), &(result->tm_mon), &(result->tm_mday),
00070 &(result->tm_hour), &(result->tm_min), &(result->tm_sec),
00071 &zflag);
00072
00073 result->tm_year -= 1900;
00074 result->tm_mon -= 1;
00075 result->tm_isdst = -1;
00076
00077 utc = (found == 7 && zflag == 'Z');
00078
00079 return (found >= 6) ? result : 0;
00080 }
00081
00082 std::string tm_to_iso(const struct tm *t, bool utc)
00083 {
00084 char tmp[128];
00085
00086 int cc = snprintf(tmp, sizeof(tmp), "%04d%02d%02dT%02d%02d%02d",
00087 t->tm_year + 1900,
00088 t->tm_mon + 1,
00089 t->tm_mday,
00090 t->tm_hour,
00091 t->tm_min,
00092 t->tm_sec
00093 );
00094 if( cc < 0 || (size_t)cc >= sizeof(tmp) )
00095 return "";
00096
00097 if( utc ) {
00098 if( (size_t)cc >= (sizeof(tmp) - 1) )
00099 return "";
00100 tmp[cc++] = 'Z';
00101 tmp[cc] = 0;
00102 }
00103
00104 return tmp;
00105 }
00106
00107 time_t TzWrapper::iso_mktime(const char *timestamp)
00108 {
00109 bool utc;
00110 struct tm t;
00111 if( !iso_to_tm(timestamp, &t, utc) )
00112 return (time_t)-1;
00113 TzWrapper tzw;
00114 if( utc )
00115 tzw.SetUTC();
00116 return tzw.mktime(&t);
00117 }
00118
00119 }}
00120
00121
00122 #ifdef TZ_TEST_MODE
00123 #include <iostream>
00124 using namespace std;
00125 using namespace Barry::Sync;
00126 int main()
00127 {
00128 time_t now = time(NULL);
00129
00130 cout << "TZ: " << TzWrapper().ctime(&now);
00131 cout << "UTC: " << TzWrapper("").ctime(&now);
00132 cout << "UTC: " << TzWrapper().SetUTC().ctime(&now);
00133 cout << "SysLocaltime: " << TzWrapper().SetUTC().SetSysLocal().ctime(&now);
00134 cout << "TZ: " << TzWrapper().SetUTC().SetDefault().ctime(&now);
00135 cout << "Canada/Eastern: " << TzWrapper("Canada/Eastern").ctime(&now);
00136 cout << "Canada/Pacific: " << TzWrapper("Canada/Pacific").ctime(&now);
00137
00138 {
00139 TzWrapper tzw("UTC");
00140 cout << "UTC: " << ctime(&now);
00141 }
00142
00143 cout << "TZ: " << ctime(&now);
00144
00145
00146 cout << "Using Canada/Eastern:" << endl;
00147 TzWrapper tzw("Canada/Eastern");
00148 const char *iso1 = "20100430T231500";
00149 const char *iso2 = "20100501T031500Z";
00150 time_t t1 = TzWrapper::iso_mktime(iso1);
00151 time_t t2 = TzWrapper::iso_mktime(iso2);
00152 cout << " " << iso1 << ": (" << t1 << ") " << ctime(&t1);
00153 cout << iso2 << ": (" << t2 << ") " << ctime(&t2);
00154
00155 if( TzWrapper::iso_mktime("20100430") == (time_t)-1 )
00156 cout << "Fail check: passed" << endl;
00157 else
00158 cout << "Fail check: ERROR" << endl;
00159
00160 cout << "t1: " << tm_to_iso(gmtime(&t1), true) << endl;
00161 }
00162 #endif
00163