00001
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "CTB.hxx"
00015 #include "CTBioState.hxx"
00016 #include "CTBosFill.hxx"
00017 #include "CTBprintf.hxx"
00018 #include "CTBnum.hxx"
00019 #include "CTBtime.hxx"
00020
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <ctype.h>
00024 #include <time.h>
00025 #include <sys/time.h>
00026 #include <unistd.h>
00027 #include <math.h>
00028
00041
00043
00044 void CTBtime::GetSystemTime()
00045 {
00046 timeval tv;
00047
00048 if(gettimeofday(&tv,0) == 0) {
00049 md_time = (double)tv.tv_sec + 1.e-6 * (double)tv.tv_usec;
00050 } else {
00051 md_time = -1.;
00052 }
00053
00054 return;
00055 }
00056
00057
00059
00060 void CTBtime::Split(CTBint32& i_sec, CTBint32& i_usec) const
00061 {
00062 if (Valid()) {
00063 double d_sec = floor(md_time);
00064 double d_usec = floor(1.e6*(md_time-d_sec));
00065
00066 if (d_usec >= 1.e6) {
00067 d_sec += 1.;
00068 d_usec -= 1.e6;
00069 }
00070 i_sec = (CTBint32) d_sec;
00071 i_usec = (CTBint32) d_usec;
00072
00073 } else {
00074 i_sec = -1;
00075 i_usec = 0;
00076 }
00077
00078 return;
00079 }
00080
00081
00083
00084 void CTBtime::ToStream(ostream& os) const
00085 {
00086 CTBtimeParsed tp = *this;
00087 tp.ToStream(os);
00088 return;
00089 }
00090
00091
00093
00094 void CTBtime::FromStream(istream& is)
00095 {
00096 CTBtimeParsed tp;
00097
00098 tp.FromStream(is);
00099 *this = tp.MakeTime();
00100
00101 return;
00102 }
00103
00104
00106
00117 CTBint32 CTBtime::ymdhms2ui(int i_year, int i_month, int i_day,
00118 int i_hour, int i_min, int i_sec)
00119 {
00120 struct tm s_time;
00121 time_t i_time;
00122
00123 i_year -= 1900;
00124 i_month -= 1;
00125
00126 s_time.tm_sec = i_sec;
00127 s_time.tm_min = i_min;
00128 s_time.tm_hour = i_hour;
00129 s_time.tm_mday = i_day;
00130 s_time.tm_mon = i_month;
00131 s_time.tm_year = i_year;
00132 s_time.tm_wday = 0;
00133 s_time.tm_yday = 0;
00134 s_time.tm_isdst = -1;
00135
00136 i_time = mktime(&s_time);
00137
00138 if (s_time.tm_sec != i_sec ||
00139 s_time.tm_min != i_min ||
00140 s_time.tm_hour != i_hour ||
00141 s_time.tm_mday != i_day ||
00142 s_time.tm_mon != i_month ||
00143 s_time.tm_year != i_year) return -1;
00144
00145 return i_time;
00146 }
00147
00148
00150
00151 CTBint32 CTBtime::vms2ui(const char* c_time)
00152 {
00153 int i_year = -1;
00154 int i_month = -1;
00155 int i_day = -1;
00156 int i_hour = 0;
00157 int i_min = 0;
00158 int i_sec = 0;
00159 int ni_year = -1;
00160 int ni_month = -1;
00161 int ni_day = -1;
00162 int ni_hour = -1;
00163 int ni_min = -1;
00164 int ni_sec = -1;
00165 char c_dtsep = 0;
00166
00167 char c_month[4];
00168 char *c_mtable[12] =
00169 {"JAN","FEB","MAR","APR","MAY","JUN",
00170 "JUL","AUG","SEP","OCT","NOV","DEC"};
00171
00172 c_month[0] = 0;
00173
00174 (void) sscanf(c_time,"%d%n-%3s%n-%d%n%c%d%n:%d%n:%d%n",
00175 &i_day,&ni_day,c_month,&ni_month,&i_year,&ni_year,
00176 &c_dtsep,&i_hour,&ni_hour,&i_min,&ni_min,&i_sec,&ni_sec);
00177
00178
00179
00180
00181
00182 if (ni_day == -1) return -1;
00183 if (c_time[ni_day] != '-') return -1;
00184 if (ni_month == -1) return -1;
00185 if (c_time[ni_month] != '-') return -1;
00186 if (ni_year == -1) return -1;
00187 if (c_time[ni_year] != ' ' &&
00188 c_time[ni_year] != ':' &&
00189 c_time[ni_year] != 0) return -1;
00190 if (ni_hour > 0 &&
00191 c_time[ni_hour] != ':' &&
00192 c_time[ni_hour] != 0) return -1;
00193 if (ni_min > 0 &&
00194 c_time[ni_sec] != ':' &&
00195 c_time[ni_sec] != 0) return -1;
00196 if (ni_sec > 0 &&
00197 c_time[ni_sec] != 0) return -1;
00198
00199 for (int i = 0; i < 3; i++) c_month[i] = toupper(c_month[i]);
00200
00201 i_month = -1;
00202
00203 for (int i = 0; i < 12; i++) {
00204 if (strcmp(c_mtable[i],c_month) == 0) {
00205 i_month = i+1;
00206 break;
00207 }
00208 }
00209
00210 if (i_month == -1) return -1;
00211
00212 if (i_year < 100) {
00213 if (i_year >= 70) i_year += 1900;
00214 else i_year += 2000;
00215 }
00216
00217 return ymdhms2ui(i_year,i_month,i_day,i_hour,i_min,i_sec);
00218 }
00219
00220
00222
00228 void CTBtime::ui2local(char* c_time, int i_size,
00229 const char* c_format, CTBint32 i_time)
00230 {
00231 time_t i_time_val = i_time;
00232 struct tm* ps_time = localtime(&i_time_val);
00233
00234 strftime(c_time,i_size,c_format,ps_time);
00235
00236 return;
00237 }
00238
00239
00241
00247 void CTBtime::ui2utc(char* c_time, int i_size,
00248 const char* c_format, CTBint32 i_time)
00249 {
00250 time_t i_time_val = i_time;
00251 struct tm* ps_time = gmtime(&i_time_val);
00252
00253 strftime(c_time,i_size,c_format,ps_time);
00254
00255 return;
00256 }
00257
00258
00260
00265 void CTBtime::ui2vms(char c_time[21], CTBint32 i_time)
00266 {
00267 ui2local(c_time,21,"%d-%b-%Y %H:%M:%S",i_time);
00268 return;
00269 }
00270
00271
00277
00279
00280 void CTBtimeParsed::ParseTime(const CTBtime& time)
00281 {
00282
00283 if (time.Valid()) {
00284 CTBint32 i_sec;
00285 CTBint32 i_usec;
00286
00287 time.Split(i_sec,i_usec);
00288
00289 time_t i_time = i_sec;
00290 tm* p_time = localtime(&i_time);
00291
00292 mi_year = p_time->tm_year + 1900;
00293 mi_month = p_time->tm_mon + 1;
00294 mi_day = p_time->tm_mday;
00295 mi_wday = p_time->tm_wday;
00296 mi_yday = p_time->tm_yday;
00297 mi_hour = p_time->tm_hour;
00298 mi_min = p_time->tm_min;
00299 mi_sec = p_time->tm_sec;
00300 mi_usec = i_usec;
00301 mi_tzoffset = __timezone;
00302 mi_dst = p_time->tm_isdst;
00303 if (mi_dst > 0) {
00304 strncpy(mc_tzname,__tzname[1],8);
00305 mc_tzname[7] = 0;
00306 mi_tzoffset -= 3600;
00307 } else {
00308 strncpy(mc_tzname,__tzname[0],8);
00309 mc_tzname[7] = 0;
00310 }
00311
00312 } else {
00313 Init();
00314 }
00315
00316 return;
00317 }
00318
00319
00321
00322 CTBtime CTBtimeParsed::MakeTime()
00323 {
00324 double d_time = -1.;
00325 tm s_time;
00326
00327 s_time.tm_year = mi_year - 1900;
00328 s_time.tm_mon = mi_month - 1;
00329 s_time.tm_mday = mi_day;
00330 s_time.tm_wday = -1;
00331 s_time.tm_yday = -1;
00332 s_time.tm_hour = mi_hour;
00333 s_time.tm_min = mi_min;
00334 s_time.tm_sec = mi_sec;
00335 s_time.tm_isdst = mi_dst;
00336
00337 time_t i_time = mktime(&s_time);
00338 if (i_time >= 0) {
00339 d_time = (double)i_time + 1.e-6*mi_usec;
00340 mi_year = s_time.tm_year + 1900;
00341 mi_month = s_time.tm_mon + 1;
00342 mi_day = s_time.tm_mday;
00343 mi_wday = s_time.tm_wday;
00344 mi_yday = s_time.tm_yday;
00345 mi_hour = s_time.tm_hour;
00346 mi_min = s_time.tm_min;
00347 mi_sec = s_time.tm_sec;
00348 mi_dst = s_time.tm_isdst;
00349 mi_tzoffset = __timezone;
00350 if (mi_dst > 0) {
00351 strncpy(mc_tzname,__tzname[1],8);
00352 mc_tzname[7] = 0;
00353 mi_tzoffset -= 3600;
00354 } else {
00355 strncpy(mc_tzname,__tzname[0],8);
00356 mc_tzname[7] = 0;
00357 }
00358 }
00359 return CTBtime(d_time);
00360 }
00361
00362
00364
00374 void CTBtimeParsed::ToStream(ostream& os) const
00375 {
00376 if (Valid()) {
00377 os << CTBprintf(mi_year,"d0",4)
00378 << "-" << CTBprintf(mi_month,"d0",2)
00379 << "-" << CTBprintf(mi_day,"d0",2)
00380 << " " << CTBprintf(mi_hour,"d0",2)
00381 << ":" << CTBprintf(mi_min,"d0",2)
00382 << ":" << CTBprintf(mi_sec,"d0",2);
00383
00384 if (mi_usec != 0) os << "." << CTBprintf(mi_usec,"d0",6);
00385
00386 int i_tzs = CTBabs(mi_tzoffset);
00387 int i_tzh = i_tzs/3600;
00388 int i_tzm = (i_tzs-3600*i_tzh)/60;
00389 os << " " << ((mi_tzoffset>0) ? '-' : '+')
00390 << CTBprintf(i_tzh,"d0",2) << CTBprintf(i_tzm,"d0",2);
00391 } else {
00392 os << "0000-00-00 00:00:00 +0000";
00393 }
00394
00395 return;
00396 }
00397
00398
00400
00409 void CTBtimeParsed::FromStream(istream& is)
00410 {
00411 CTBioState iostate(is,"d");
00412 double d_secfrac;
00413 int i_tzoff;
00414
00415 Init();
00416 is >> mi_year;
00417
00418 if (is.get() != '-') is.setstate(ios::failbit);
00419 is >> mi_month;
00420
00421 if (is.get() != '-') is.setstate(ios::failbit);
00422 is >> mi_day;
00423
00424 is >> mi_hour;
00425
00426 if (is.get() != ':') is.setstate(ios::failbit);
00427 is >> mi_min;
00428
00429 if (is.get() != ':') is.setstate(ios::failbit);
00430 is >> d_secfrac;
00431 double d_sec = floor(d_secfrac);
00432 mi_sec = (int) floor(d_sec);
00433 mi_usec = (int) floor(1.e6*(d_secfrac-d_sec));
00434
00435 is >> i_tzoff;
00436
00437 return;
00438 }
00439
00440
00442
00443 void CTBtimeParsed::Dump(int i_indent, ostream& os, const char* p_text) const
00444 {
00445 CTBosFill bl(i_indent);
00446 os << bl << "--CTBtimeParsed ";
00447 if (p_text) os << p_text;
00448 os << " @ " << this << endl;
00449 os << bl << " mi_year: " << CTBprintf(mi_year,"d",6) << "\n";
00450 os << bl << " mi_month: " << CTBprintf(mi_month,"d",6) << "\n";
00451 os << bl << " mi_day: " << CTBprintf(mi_day,"d",6) << "\n";
00452 os << bl << " mi_wday: " << CTBprintf(mi_wday,"d",6) << "\n";
00453 os << bl << " mi_yday: " << CTBprintf(mi_yday,"d",6) << "\n";
00454 os << bl << " mi_hour: " << CTBprintf(mi_hour,"d",6) << "\n";
00455 os << bl << " mi_min: " << CTBprintf(mi_min,"d",6) << "\n";
00456 os << bl << " mi_sec: " << CTBprintf(mi_sec,"d",6) << "\n";
00457 os << bl << " mi_usec: " << CTBprintf(mi_usec,"d",6) << "\n";
00458 os << bl << " mi_tzoffset: " << CTBprintf(mi_tzoffset,"d",6) << "\n";
00459 os << bl << " mc_tzname: " << mc_tzname << "\n";
00460 os << bl << " mi_dst: " << mi_dst << "\n";
00461
00462 return;
00463 }
00464
00465
00467
00468 CTBtimeParsed::operator CTBtime() const
00469 {
00470 CTBtimeParsed temp(*this);
00471 return temp.MakeTime();
00472 }
00473
00474
00476
00477 void CTBtimeParsed::Init()
00478 {
00479 mi_year = 0;
00480 mi_month = 0;
00481 mi_day = 0;
00482 mi_wday = -1;
00483 mi_yday = -1;
00484 mi_hour = 0;
00485 mi_min = 0;
00486 mi_sec = 0;
00487 mi_usec = 0;
00488 mi_tzoffset = 0;
00489 mc_tzname[0] = 0;
00490 mi_dst = -1;
00491 return;
00492 }