Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

VldTimeStamp.cxx

Go to the documentation of this file.
00001 
00002 // $Id: VldTimeStamp.cxx,v 1.29 2009/02/28 21:46:17 gmieg Exp $
00003 //
00004 // The VldTimeStamp encapsulates the seconds and ns since EPOCH
00005 //
00006 // This extends (and isolates) struct timespec
00007 //    struct timespec
00008 //       {
00009 //          time_t   tv_sec;   /* seconds */
00010 //          long     tv_nsec;  /* nanoseconds */
00011 //       }
00012 //    time_t seconds is relative to Jan 1, 1970 00:00:00 UTC
00013 //
00014 // Due to ROOT/CINT limitations VldTimeStamp does not explicitly
00015 // hold a timespec struct; attempting to do so means the Streamer
00016 // must be hand written.  Instead we have chosen to simply contain
00017 // similar fields within the private area of this class.
00018 //
00019 // NOTE: the use of time_t (and its default implementation as a 32 int)
00020 //       implies overflow conditions occurs somewhere around
00021 //       Jan 18, 19:14:07, 2038.
00022 //       If this experiment is still going when it becomes significant
00023 //       someone will have to deal with it.
00024 //
00025 // Author:  R. Hatcher 2000.04.19
00026 //          R. Hatcher 2000.12.20 -- convert from TDatime to struct timespec
00027 //
00029 
00030 #include "Validity/VldTimeStamp.h"
00031 #include "MessageService/MsgService.h"
00032 #include <climits>
00033 #include <math.h>
00034 
00035 CVSID("$Id: VldTimeStamp.cxx,v 1.29 2009/02/28 21:46:17 gmieg Exp $");
00036 
00037 #ifdef R__WIN32
00038 #include "Windows4Root.h"
00039 #else
00040 #include <unistd.h>
00041 // timeval, timezone, gettimeofday
00042 #include <sys/time.h>
00043 #endif
00044 
00045 #include "TString.h"
00046 
00047 ClassImp(VldTimeStamp)
00048 
00049 const Int_t kNsPerSec = 1000000000;
00050 
00051 //_____________________________________________________________________________
00052 std::ostream& operator<<(std::ostream& os, const VldTimeStamp& ts) 
00053 {
00054    if (os.good()) {
00055       if (os.tie()) os.tie()->flush(); // instead of opfx
00056       os << ts.AsString("c");
00057    }
00058    // instead of os.osfx()
00059    if (os.flags() & std::ios::unitbuf) os.flush();
00060    return os;
00061 }
00062 
00063 VldTimeStamp VldTimeStamp::GetBOT()
00064 {
00065     return VldTimeStamp((time_t)0,0);
00066 }
00067 
00068 VldTimeStamp VldTimeStamp::GetEOT()
00069 {
00070     return VldTimeStamp((time_t)INT_MAX,0);
00071 }
00072 
00073 VldTimeStamp VldTimeStamp::GetNBOT()
00074 {
00075     return VldTimeStamp((time_t)INT_MIN,0);
00076 }
00077 
00078 
00079 //_____________________________________________________________________________
00080 // don't put these in the header or using the include file w/ CINT
00081 // become problematic
00082 
00083 // default ctor sets it value to current time (as best possible)
00084 VldTimeStamp::VldTimeStamp() : fSec(0), fNanoSec(0) { Set(); }
00085 VldTimeStamp::~VldTimeStamp() { ; }
00086 
00087 //_____________________________________________________________________________
00088 VldTimeStamp::VldTimeStamp(UInt_t year, UInt_t month,
00089                            UInt_t day,  UInt_t hour,
00090                            UInt_t min,  UInt_t sec,
00091                            UInt_t nsec, 
00092                            Bool_t isUTC, Int_t secOffset)
00093   : fSec(0), fNanoSec(0)
00094 {
00095    // Create a VldTimeStamp and set it to the specified year, month,
00096    // day, time, hour, minute, second and nanosec.
00097    // If !isUTC then it is assumed to be the standard local time zone.
00098    //
00099    // If local time is PST then one can use
00100    //    VldTimeStamp(year,month,day,hour,min,sec,nsec,kFALSE,0);
00101    // or
00102    //    Int_t secOffset = 8*60*60;
00103    //    VldTimeStamp(year,month,day,hour,min,sec,nsec,kTRUE,8*60*60);
00104    
00105    Set(year, month, day, hour, min, sec, nsec, isUTC, secOffset);
00106 }
00107 
00108 //_____________________________________________________________________________
00109 VldTimeStamp::VldTimeStamp(UInt_t date, UInt_t time, UInt_t nsec, 
00110                            Bool_t isUTC, Int_t secOffset)
00111   : fSec(0), fNanoSec(0)
00112 {
00113    // Create a VldTimeStamp and set it to the specified date, time, nanosec.
00114    // If !isUTC then it is assumed to be the standard local time zone.
00115 
00116    Set(date, time, nsec, isUTC, secOffset);
00117 }
00118 
00119 //_____________________________________________________________________________
00120 const char *VldTimeStamp::AsString(Option_t *option) const
00121 {
00122    // Return the date & time as a string.
00123    //
00124    // Result is pointer to a statically allocated string.
00125    // User should copy this into their own buffer before calling
00126    // this method again.  This is somewhat mitigated
00127    // by use of a circular buffer of strings.
00128    //
00129    // Option "l" returns it in local zone format
00130    // (can be applied to default or compact format).
00131    //
00132    // Default format is RFC822 compliant:
00133    //   "Mon, 02 Jan 2001 18:11:12 +0000 (GMT) +999999999 nsec"
00134    //   "Mon, 02 Jan 2001 10:11:12 -0800 (PST) +999999999 nsec"
00135    //
00136    // Option "c" compact is (almost) ISO 8601 compliant:
00137    //   "2001-01-02 18:11:12.9999999999Z"
00138    //   "2001-01-02 10:11:12.9999999999-0800"  if PST
00139    //      * uses "-" as date separator as specified in ISO 8601
00140    //      * uses "." rather than preferred "," for decimal separator
00141    //      * -HHMM is the difference between local and UTC (if behind, + if ahead).
00142    //   The "-HHMM" is replaced with "Z" if given as UTC.
00143    //   To be strictly conforming it should use "T" instead of the
00144    //   blank separating the date and time.
00145    //
00146    // Option "2" returns as {sec,nsec} integers.
00147    //
00148    // Option "s" returns "2001-01-02 18:11:12" with an implied UTC,
00149    // overrides "l" option.
00150 
00151    // Internally uses a circular list of buffers to avoid problems
00152    // using AsString multiple times in a single statement.
00153 
00154    const int nbuffers = 8;     // # of buffers
00155 
00156    static char formatted[nbuffers][64];  // strftime fields substituted
00157    static char formatted2[nbuffers][64]; // nanosec field substituted
00158    static int ibuffer = nbuffers;
00159    ibuffer = (ibuffer+1)%nbuffers; // each call moves to next buffer
00160 
00161    TString opt = option;
00162    opt.ToLower();
00163 
00164    if (opt.Contains("2")) {
00165       // return string formatted as integer {sec,nsec}
00166       sprintf(formatted[ibuffer], "{%d,%d}", fSec, fNanoSec);
00167       return formatted[ibuffer];
00168    }
00169 
00170 #ifdef linux
00171    // under linux %z is the hour offset and %Z is the timezone name
00172    const char *RFC822   = "%a, %d %b %Y %H:%M:%S %z (%Z) +#9ld nsec";
00173    const char *ISO8601  = "%Y-%m-%d %H:%M:%S.#9.9ld%z";
00174    const char *ISO8601Z = "%Y-%m-%d %H:%M:%S.#9.9ldZ";
00175 #else
00176    // otherwise only %Z is guarenteed to be defind
00177    const char *RFC822   = "%a, %d %b %Y %H:%M:%S %Z +#9ld nsec";
00178    const char *ISO8601  = "%Y-%m-%d %H:%M:%S.#9.9ld%Z";
00179    const char *ISO8601Z = "%Y-%m-%d %H:%M:%S.#9.9ldZ";
00180 #endif
00181    const char *SQL = "%Y-%m-%d %H:%M:%S";
00182 
00183    Bool_t asLocal = opt.Contains("l");
00184    Bool_t asSQL   = opt.Contains("s");
00185    if (asSQL) asLocal = kFALSE;
00186 
00187    const char *format = RFC822;
00188    if (opt.Contains("c")) {
00189       format = ISO8601;
00190       if (!asLocal) format = ISO8601Z;
00191    }
00192    if (asSQL) format = SQL;
00193 
00194    struct tm *ptm;
00195    time_t seconds = (time_t) fSec;   // deal with possible mismatch of types 
00196                                      // of fSec and the time_t required 
00197                                      // by functions
00198 
00199    // get the components into a tm struct
00200    ptm = (asLocal) ? localtime(&seconds) : gmtime(&seconds);
00201 
00202    // format all but the nsec field
00203    // size_t length =
00204    strftime(formatted[ibuffer], sizeof(formatted[ibuffer]), format, ptm);
00205 
00206    if (asSQL) return formatted[ibuffer];
00207 
00208    // hack in the nsec part
00209    char *ptr = strrchr(formatted[ibuffer], '#');
00210    if (ptr) *ptr = '%';    // substitute % for #
00211    sprintf(formatted2[ibuffer], formatted[ibuffer], fNanoSec);
00212 
00213    return formatted2[ibuffer];
00214 }
00215 
00216 //_____________________________________________________________________________
00217 void VldTimeStamp::Copy(VldTimeStamp &ts) const
00218 {
00219    // Copy this to ts.
00220 
00221    ts.fSec     = fSec;
00222    ts.fNanoSec = fNanoSec;
00223 
00224 }
00225 
00226 //_____________________________________________________________________________
00227 Int_t VldTimeStamp::GetDate(Bool_t inUTC, Int_t secOffset,
00228                             UInt_t* year, UInt_t* month, UInt_t* day) const
00229 {
00230    // Return date in form of 19971224 (i.e. 24/12/1997),
00231    // if non-zero pointers supplied for year, month, day fill those as well
00232 
00233    time_t atime = fSec + secOffset;
00234    struct tm *ptm = (inUTC) ? gmtime(&atime) : localtime(&atime);
00235 
00236    if (year)  *year  = ptm->tm_year + 1900;
00237    if (month) *month = ptm->tm_mon + 1;
00238    if (day)   *day   = ptm->tm_mday;
00239 
00240    return (1900+ptm->tm_year)*10000 + (1+ptm->tm_mon)*100 + ptm->tm_mday;
00241 
00242 }
00243 
00244 //_____________________________________________________________________________
00245 Int_t VldTimeStamp::GetTime(Bool_t inUTC, Int_t secOffset,
00246                             UInt_t* hour, UInt_t* min, UInt_t* sec) const
00247 {
00248    // Return time in form of 123623 (i.e. 12:36:23),
00249    // if non-zero pointers supplied for hour, min, sec fill those as well
00250 
00251    time_t atime = fSec + secOffset;
00252    struct tm *ptm = (inUTC) ? gmtime(&atime) : localtime(&atime);
00253 
00254    if (hour) *hour = ptm->tm_hour;
00255    if (min)  *min  = ptm->tm_min;
00256    if (sec)  *sec  = ptm->tm_sec;
00257 
00258    return ptm->tm_hour*10000 + ptm->tm_min*100 + ptm->tm_sec;
00259 
00260 }
00261 
00262 //_____________________________________________________________________________
00263 Int_t VldTimeStamp::GetZoneOffset()
00264 {
00265    // Static method returning local (current) time zone offset from UTC.
00266    // This is the difference in seconds between UTC and local standard time.
00267 
00268    // ?? should tzset (_tzset) be called?
00269 #ifndef R__WIN32
00270    tzset();
00271 #if !defined(R__MACOSX) && !defined(R__FBSD)
00272    return  timezone;   /* unix has extern long int */
00273 #else
00274    time_t *tp = 0;
00275    time(tp);
00276    return localtime(tp)->tm_gmtoff;
00277 #endif
00278 #else
00279    _tzset();
00280    return _timezone;   /* Win32 prepends "_" */
00281 #endif
00282 }
00283 
00284 //_____________________________________________________________________________
00285 void VldTimeStamp::Add(const VldTimeStamp &offset)
00286 {
00287    // Add "offset" as a delta time.
00288 
00289    fSec     += offset.fSec;
00290    fNanoSec += offset.fNanoSec;
00291    NormalizeNanoSec();
00292 
00293 }
00294 
00295 void VldTimeStamp::Add(Double_t seconds)
00296 {
00297   // Add 'seconds' as a delta time
00298 
00299   fSec += (Int_t) seconds;
00300   fNanoSec += (Int_t) (fmod(seconds,1.0) * 1e9);
00301   NormalizeNanoSec();
00302   if(seconds > 1e6) 
00303     MSG("Vld",Msg::kWarning) << "VldTimeStamp moved by offset " << seconds <<" which is too large to maintain ns accuracy." << endl;
00304 }
00305 
00306 //_____________________________________________________________________________
00307 void VldTimeStamp::Print(Option_t *option) const
00308 {
00309    // Print date and time.
00310 
00311    printf("Date/Time = %s\n", AsString(option));
00312 
00313 }
00314 
00315 //_____________________________________________________________________________
00316 void VldTimeStamp::Set()
00317 {
00318    // Set Date/Time to current time as reported by the system.
00319    // no accounting for nanoseconds with std ANSI functions,
00320    // ns part faked so that subsequent calls simply add 1 to it
00321    // this ensures that calls within the same second come back
00322    // distinct (and sortable).
00323 
00324 #ifdef R__WIN32
00325    ULARGE_INTEGER time;
00326    GetSystemTimeAsFileTime((FILETIME *)&time);
00327    // NT keeps time in FILETIME format which is 100ns ticks since
00328    // Jan 1, 1601. TTimeStamps use time in 100ns ticks since Jan 1, 1970.
00329    // The difference is 134774 days.
00330    fNanoSec = Int_t((time.QuadPart * (unsigned __int64) 100) %
00331                     (unsigned __int64) 1000000000);
00332    time.QuadPart -=
00333             (unsigned __int64) (1000*1000*10)       // seconds
00334           * (unsigned __int64) (60 * 60 * 24)       // days
00335           * (unsigned __int64) (134774);            // # of days
00336 
00337    fSec     = Int_t(time.QuadPart/(unsigned __int64) (1000*1000*10));
00338 #else
00339    // this should work on UNIX to get microsec precision
00340    // we'll stick to a ns hack to make calls unique
00341    struct timeval now;
00342    if (!gettimeofday(&now,0)) {
00343       fSec     = now.tv_sec;
00344       fNanoSec = now.tv_usec * 1000;
00345    }
00346    else {
00347       time_t nowtime;
00348       time(&nowtime);
00349       fSec     = nowtime;
00350       fNanoSec = 0;
00351    }
00352 #endif
00353    static Int_t sec = 0, nsec = 0, fake_ns = 0;
00354 
00355    if (fSec == sec && fNanoSec == nsec)
00356       fNanoSec += ++fake_ns;
00357    else {
00358       fake_ns = 0;
00359       sec     = fSec;
00360       nsec    = fNanoSec;
00361    }
00362 
00363 }
00364 
00365 //_____________________________________________________________________________
00366 void VldTimeStamp::Set(Int_t year, Int_t month, Int_t day,
00367                        Int_t hour, Int_t min, Int_t sec, 
00368                        Int_t nsec, Bool_t isUTC, Int_t secOffset)
00369 {
00370    // Set Date/Time from components.
00371    // 
00372    // month & day both use normal 1..12 and 1..31 counting
00373    // hours, min, sec run from 0 to 23, 59, 59 respectively;
00374    // secOffset provides method for adjusting for alternative timezones
00375    //
00376    // "year"  |    0    1 ... 37 | 38...69   |   70 .. 100  101 ..  137
00377    // true    | 2000 2001   2037 | undefined | 1970   2000 2001 .. 2037
00378    //
00379    // "year"  | 138...1969 | 1970 .. 2037 | ...
00380    // true    | undefined  | 1970 .. 2037 | undefined
00381    //
00382 
00383 
00384    // deal with special formats of year
00385    if (year <= 37)                year += 2000;
00386    if (year >= 70 && year <= 137) year += 1900;
00387    // tm.tm_year is years since 1900
00388    if (year >= 1900)              year -= 1900;
00389 
00390    struct tm tmstruct;
00391    tmstruct.tm_year  = year;    // years since 1900
00392    tmstruct.tm_mon   = month-1; // months since Jan [0,11]
00393    tmstruct.tm_mday  = day;     // day of the month [1,31]
00394    tmstruct.tm_hour  = hour;    // hours since midnight [0,23]
00395    tmstruct.tm_min   = min;     // minutes after the hour [0,59]
00396    tmstruct.tm_sec   = sec + secOffset;  // seconds after the minute [0,59]
00397    tmstruct.tm_isdst = -1;     // let "mktime" determine DST setting
00398 
00399    const time_t bad_time_t = (time_t) -1;
00400    // convert tm struct to time_t, if values are given in UTC then
00401    // no standard routine exists and we'll have to use our homegrown routine,
00402    // if values are given in local time then use "mktime"
00403    // which also normalizes the tm struct as a byproduct
00404    time_t utc_sec = (isUTC) ? MktimeFromUTC(&tmstruct) : mktime(&tmstruct);
00405  
00406    //   VldTimeStamp::Dump_tm_struct(tmstruct);
00407 
00408    if (utc_sec == bad_time_t)
00409       MSG("Vld",Msg::kInfo) 
00410          << "VldTimeStamp::Set mktime returned -1" << endl;
00411 
00412    fSec  = utc_sec;
00413    fNanoSec = nsec;
00414 
00415    NormalizeNanoSec();
00416 }
00417 
00418 //_____________________________________________________________________________
00419 void VldTimeStamp::Set(Int_t date, Int_t time, Int_t nsec,
00420                        Bool_t isUTC, Int_t secOffset)
00421 {
00422    // Set date/time from integers of the form [yy]YYMMDD and HHMMSS,
00423    // assume UTC (UTC) components:
00424    //
00425    //  MM: 01=January .. 12=December
00426    //  DD: 01 .. 31
00427    //
00428    //  HH: 00=midnight .. 23
00429    //  MM: 00 .. 59
00430    //  SS: 00 .. 69
00431    //
00432    // Date must be in format 980418 or 19980418
00433    //                       1001127 or 20001127  (i.e. year 100 = 2000).
00434    // Time must be in format 224512 (second precision).
00435    // Date must be >= 700101.
00436 
00437    Int_t year  = date/10000;
00438    Int_t month = (date-year*10000)/100;
00439    Int_t day   = date%100;
00440 
00441    // protect against odd attempts at time offsets
00442    const Int_t oneday = 240000;
00443    while (time < 0) {
00444       time += oneday;
00445       day  -= 1;
00446    }
00447    while (time > oneday) {
00448       time -= oneday;
00449       day  += 1;
00450    }
00451    Int_t hour  = time/10000;
00452    Int_t min   = (time-hour*10000)/100;
00453    Int_t sec   = time%100;
00454 
00455    Set(year, month, day, hour, min, sec, nsec, isUTC, secOffset);
00456 
00457 }
00458 
00459 //_____________________________________________________________________________
00460 void VldTimeStamp::NormalizeNanoSec()
00461 {
00462    // Ensure that the fNanoSec field is in range [0,99999999].
00463 
00464    // deal with negative values
00465    while (fNanoSec < 0) {
00466       fNanoSec += kNsPerSec;
00467       fSec -= 1;
00468    }
00469    // deal with values inf fNanoSec greater than one sec
00470    while (fNanoSec >= kNsPerSec) {
00471       fNanoSec -= kNsPerSec;
00472       fSec += 1;
00473    }
00474 }
00475 //_____________________________________________________________________________
00476 time_t VldTimeStamp::MktimeFromUTC(tm_t *tmstruct)
00477 {
00478    // Equivalent of standard routine "mktime" but
00479    // using the assumption that tm struct is filled with UTC, not local, time.
00480 
00481    // This version *ISN'T* configured to handle every possible
00482    // weirdness of out-of-range values in the case of normalizing
00483    // the tm struct.
00484 
00485    // This version *DOESN'T* correctly handle values that can't be
00486    // fit into a time_t (i.e. beyond year 2038-01-18 19:14:07, or
00487    // before the start of Epoch).
00488 
00489    const Int_t days[]     = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
00490    const Int_t daysLeap[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
00491 
00492    Int_t year = tmstruct->tm_year + 1900;
00493    Bool_t isleap = VldTimeStamp::IsLeapYear(year);
00494 
00495    const Int_t *daysInMonth = days;
00496    if (isleap) daysInMonth = daysLeap;
00497 
00498    // fill in tmstruct->tm_yday
00499 
00500    int &ref_tm_mon = tmstruct->tm_mon;
00501    int &ref_tm_mday = tmstruct->tm_mday;
00502    // count days in months past
00503    tmstruct->tm_yday = 0;
00504    for (Int_t imonth = 0; imonth < ref_tm_mon; imonth++) {
00505       tmstruct->tm_yday += daysInMonth[imonth];
00506    }
00507    tmstruct->tm_yday += ref_tm_mday - 1;  // day [1-31] but yday [0-365]
00508 
00509    // adjust if day in this month is more than the month has
00510    while (ref_tm_mday > daysInMonth[ref_tm_mon]) {
00511       ref_tm_mday -= daysInMonth[ref_tm_mon];
00512       ref_tm_mon++;
00513    }
00514 
00515    // *should* calculate tm_wday (0-6) here ...
00516 
00517    // UTC is never DST
00518    tmstruct->tm_isdst = 0;
00519 
00520    // Calculate seconds since the Epoch based on formula in
00521    // POSIX  IEEEE Std 1003.1b-1993 pg 22
00522 
00523    Int_t utc_sec = tmstruct->tm_sec +
00524                    tmstruct->tm_min*60 +
00525                    tmstruct->tm_hour*3600 +
00526                    tmstruct->tm_yday*86400 +
00527                    (tmstruct->tm_year-70)*31536000 +
00528                    ((tmstruct->tm_year-69)/4)*86400;
00529 
00530    return utc_sec;
00531 }
00532 
00533 //_____________________________________________________________________________
00534 Bool_t VldTimeStamp::IsLeapYear(Int_t year)
00535 {
00536    // Is the given year a leap year.
00537 
00538 
00539    // The calendar year is 365 days long, unless the year is exactly divisible
00540    // by 4, in which case an extra day is added to February to make the year
00541    // 366 days long. If the year is the last year of a century, eg. 1700, 1800,
00542    // 1900, 2000, then it is only a leap year if it is exactly divisible by
00543    // 400. Therefore, 1900 wasn't a leap year but 2000 was. The reason for
00544    // these rules is to bring the average length of the calendar year into
00545    // line with the length of the Earth's orbit around the Sun, so that the
00546    // seasons always occur during the same months each year.
00547 
00548    if (year%4 != 0) {
00549       return false;
00550    }
00551    else {
00552       if (year%400 == 0) {
00553          return true;
00554       }
00555       else { 
00556          if (year%100 == 0) {
00557             return false;
00558          }
00559          else {
00560             return true;
00561          }
00562       }
00563    }
00564 
00565 }
00566 
00567 //_____________________________________________________________________________
00568 void VldTimeStamp::DumpTMStruct(const tm_t &tmstruct) 
00569 {
00570    // Print out the "tm" structure:
00571    // tmstruct.tm_year = year;    // years since 1900
00572    // tmstruct.tm_mon  = month-1; // months since Jan [0,11]
00573    // tmstruct.tm_mday = day;     // day of the month [1,31]
00574    // tmstruct.tm_hour = hour;    // hours since midnight [0,23]
00575    // tmstruct.tm_min  = min;     // minutes after the hour [0,59]
00576    // tmstruct.tm_sec  = sec;     // seconds after the minute [0,59]
00577    // tmstruct.tm_wday            // day of week [0,6]
00578    // tmstruct.tm_yday            // days in year [0,365]
00579    // tmstruct.tm_isdst           // DST [-1/0/1]  (unknown,false,true)
00580 
00581    printf(" tm { year %4d, mon   %2d, day   %2d,\n",
00582           tmstruct.tm_year,
00583           tmstruct.tm_mon,
00584           tmstruct.tm_mday);
00585    printf("      hour   %2d, min   %2d, sec   %2d,\n",
00586           tmstruct.tm_hour,
00587           tmstruct.tm_min,
00588           tmstruct.tm_sec);
00589    printf("      wday   %2d, yday %3d, isdst %2d",
00590           tmstruct.tm_wday,
00591           tmstruct.tm_yday,
00592           tmstruct.tm_isdst);
00593 #ifdef linux
00594 //#ifdef __GNUC__
00595 // special GCC extras
00596    printf(",\n      tm_gmtoff %7ld,  tm_zone \"%s\"",
00597 #ifdef __USE_BSD
00598           tmstruct.tm_gmtoff,tmstruct.tm_zone);
00599 #else
00600           tmstruct.__tm_gmtoff,tmstruct.__tm_zone);
00601 #endif
00602 #endif
00603    printf("}\n");
00604 }
00605 //_____________________________________________________________________________

Generated on Sat Nov 21 22:48:05 2009 for loon by  doxygen 1.3.9.1