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

Generated on Mon Jun 16 14:58:57 2008 for loon by  doxygen 1.3.9.1