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

Generated on Fri Mar 28 15:41:52 2008 for loon by  doxygen 1.3.9.1