include/corelib/ncbitime.hpp

Go to the documentation of this file.
00001 #ifndef CORELIB__NCBITIME__HPP
00002 #define CORELIB__NCBITIME__HPP
00003 
00004 /*  $Id: ncbitime.hpp 173523 2009-10-19 16:29:27Z ivanov $
00005  * ===========================================================================
00006  *
00007  *                            PUBLIC DOMAIN NOTICE
00008  *               National Center for Biotechnology Information
00009  *
00010  *  This software/database is a "United States Government Work" under the
00011  *  terms of the United States Copyright Act.  It was written as part of
00012  *  the author's official duties as a United States Government employee and
00013  *  thus cannot be copyrighted.  This software/database is freely available
00014  *  to the public for use. The National Library of Medicine and the U.S.
00015  *  Government have not placed any restriction on its use or reproduction.
00016  *
00017  *  Although all reasonable efforts have been taken to ensure the accuracy
00018  *  and reliability of the software and data, the NLM and the U.S.
00019  *  Government do not and cannot warrant the performance or results that
00020  *  may be obtained by using this software or data. The NLM and the U.S.
00021  *  Government disclaim all warranties, express or implied, including
00022  *  warranties of performance, merchantability or fitness for any particular
00023  *  purpose.
00024  *
00025  *  Please cite the author in any work or product based on this material.
00026  *
00027  * ===========================================================================
00028  *
00029  * Authors:  Anton Butanayev, Denis Vakatov, Vladimir Ivanov
00030  *
00031  * DayOfWeek():  Used code has been posted on comp.lang.c on March 10th, 1993
00032  *               by Tomohiko Sakamoto (sakamoto@sm.sony.co.jp).
00033  *
00034  */
00035 
00036 /// @file ncbitime.hpp
00037 /// Defines:
00038 ///   CTimeFormat - storage class for fime format.
00039 ///   CTime       - standard Date/Time class to represent an absolute time.
00040 ///   CTimeSpan   - class to represents a relative time span.
00041 ///   CTimeout    - timeout interval for various I/O etc activity.
00042 ///   CStopWatch  - stop watch class to measure elasped time.
00043 ///
00044 /// NOTE about CTime:
00045 ///
00046 ///   - The time zone database in most Windows-based computer systems usually
00047 ///     stores only a single start and end rule for each zone, regardless
00048 ///     of year. One of the problems of this approach is that using time-zone
00049 ///     information will get incorrect results if referring to a year with
00050 ///     rules that are different from those currently in the database.
00051 ///
00052 ///   - Do not use Local time and time_t and its dependent functions with
00053 ///     dates outside range January 1, 1970 to January 18, 2038.
00054 ///     Also avoid to use GMT -> Local time conversion functions.
00055 ///
00056 ///   - Do not use DataBase conversion functions with dates
00057 ///     less than January 1, 1900.
00058 
00059 #include <corelib/ncbistd.hpp>
00060 
00061 
00062 BEGIN_NCBI_SCOPE
00063 
00064 /** @addtogroup Time
00065  *
00066  * @{
00067  */
00068 
00069 // Forward declarations
00070 class CTimeSpan;
00071 class CFastLocalTime;
00072 
00073 
00074 /// Number of nanoseconds in one second.
00075 ///
00076 /// Interval for it is from 0 to 999,999,999.
00077 const long kNanoSecondsPerSecond = 1000000000;
00078 
00079 /// Number of microseconds in one second.
00080 ///
00081 /// Interval for it is from 0 to 999,999.
00082 const long kMicroSecondsPerSecond = 1000000;
00083 
00084 /// Number milliseconds in one second.
00085 ///
00086 /// Interval for it is from 0 to 999.
00087 const long kMilliSecondsPerSecond = 1000;
00088 
00089 
00090 // Time formats in databases (always contain local time only!)
00091 
00092 /// Number of seconds.
00093 typedef Int8 TSeconds;
00094 
00095 /// Database format for time where day and time is unsigned 16 bit.
00096 typedef struct {
00097     Uint2 days;   ///< Days from 1/1/1900
00098     Uint2 time;   ///< Minutes from the beginning of current day
00099 } TDBTimeU, *TDBTimeUPtr;
00100 
00101 /// Database format for time where day and time is signed 32 bit.
00102 typedef struct {
00103     Int4  days;   ///< days from 1/1/1900
00104     Int4  time;   ///< x/300 seconds from the beginning of current day
00105 } TDBTimeI, *TDBTimeIPtr;
00106 
00107 
00108 
00109 /////////////////////////////////////////////////////////////////////////////
00110 ///
00111 /// CTimeFormat --
00112 ///
00113 /// Defines a storage class for time format.
00114 ///
00115 /// See CTime::SetFormat and CTimeSpan::SetFormat for description
00116 /// of format symbols for specific class.
00117 
00118 class  CTimeFormat
00119 {
00120 public:
00121     /// Flags.
00122     ///
00123     /// @sa SetFormat, AsString
00124     enum EFlags {
00125         /// Use single characters as format symbols.
00126         fFormat_Simple     = (1 << 0),
00127         /// Specify that each format symbol have a preceding symbol '$'.
00128         /// This can be useful if you want to include to format string
00129         /// a characters that are a format symbols. 
00130         /// To include symbol '$' use '$$'.
00131         fFormat_Ncbi       = (1 << 1),
00132         /// A time string should strictly match the format string.
00133         fMatch_Strict      = (1 << 5),       ///< eg "Y" and "1997"
00134         /// A format string can have extra leading format symbols,
00135         /// that do not have matching symbols in the time string.
00136         /// Corresponding time components will be initialized by default
00137         /// in the time object.
00138         fMatch_ShortTime   = (1 << 6),       ///< eg "Y/M/D h:m:s" and "1997"
00139         fMatch_ShortFormat = (1 << 7),       ///< eg "Y" and "1997/07/16"
00140         fMatch_Weak        = fMatch_ShortFormat | fMatch_ShortTime,
00141         /// Default flags
00142         fDefault           = fFormat_Simple | fMatch_Strict,
00143 
00144         /// "Enums", used for backward compatibility. Please use flags instead.
00145         eNcbiSimple        = fFormat_Simple,
00146         eNcbi              = fFormat_Ncbi,
00147         eDefault           = fDefault
00148     };
00149     typedef unsigned int TFlags;  ///< Binary OR of "EFlags"
00150 
00151     /// Predefined formats.
00152     ///
00153     /// @sa GetPredefined, CTime::SetFormat
00154     enum EPredefined {
00155         // ISO 8601 formats (without time zone)
00156         eISO8601_Year         = 0,  ///< Y            (eg 1997)
00157         eISO8601_YearMonth    = 1,  ///< Y-M          (eg 1997-07)
00158         eISO8601_Date         = 2,  ///< Y-M-D        (eg 1997-07-16)
00159         eISO8601_DateTimeMin  = 3,  ///< Y-M-DTh:m    (eg 1997-07-16T19:20)
00160         eISO8601_DateTimeSec  = 4,  ///< Y-M-DTh:m:s  (eg 1997-07-16T19:20:30)
00161         eISO8601_DateTimeFrac = 5   ///< Y-M-DTh:m:s.l(eg 1997-07-16T19:20:30.123)
00162     };
00163 
00164     /// Default constructor.
00165     CTimeFormat(void);
00166 
00167     /// Copy constructor.
00168     CTimeFormat(const CTimeFormat& format);
00169 
00170     /// Constructor.
00171     ///
00172     /// @sa SetFormat
00173     CTimeFormat(const char* fmt, TFlags flags = fDefault);
00174 
00175     /// Constructor.
00176     ///
00177     /// @sa SetFormat
00178     CTimeFormat(const string& fmt, TFlags flags = fDefault);
00179 
00180     /// Assignment operator.
00181     CTimeFormat& operator= (const CTimeFormat& format);
00182 
00183     /// Set the current time format.
00184     ///
00185     /// @param fmt
00186     ///   String of letters describing the time format.
00187     /// @param flags
00188     ///   Flags specifying how to match a time string against format string.
00189     /// @sa
00190     ///   GetFormat, EFormat
00191     void SetFormat(const char* fmt, TFlags flags = fDefault);
00192 
00193     /// Set the current time format.
00194     ///
00195     /// @param fmt
00196     ///   String of letters describing the time format.
00197     /// @param flags
00198     ///   Flags specifying how to match a time string against format string.
00199     /// @sa
00200     ///   GetFormat, EFormat
00201     void SetFormat(const string& fmt, TFlags flags = fDefault);
00202 
00203     /// Get format string.
00204     ///
00205     /// @return
00206     ///   A string of letters describing the time format.
00207     /// @sa SetFormat, GetFlags
00208     const string& GetString(void) const;
00209 
00210     /// Get format flags.
00211     ///
00212     /// @return
00213     ///   A flags specifying how to match a time string against format string.
00214     /// @sa SetFormat, GetString
00215     TFlags GetFlags(void) const;
00216 
00217     /// Check that format string is empty.
00218     bool IsEmpty(void) const;
00219 
00220     /// Get predefined format.
00221     /// @param fmt
00222     ///   String of letters describing the time format.
00223     /// @param fmt_type
00224     ///   Specify type of the format string.
00225     /// @return
00226     ///   A time format object.
00227     /// @sa EPredefined, SetFormat
00228     static CTimeFormat GetPredefined(EPredefined fmt, TFlags flags = fDefault);
00229 
00230 public:
00231     /// Return time format as string.
00232     /// Note: This method added temporarely, and will be deleted soon.
00233     /// @deprecated Use CTimeFormat::GetString()/GetFormat() methods instead.
00234     NCBI_DEPRECATED operator string(void) const;
00235 
00236 private:
00237     string  m_Str;        ///< String format.
00238     TFlags  m_Flags;      ///< Format flags.
00239 };
00240 
00241 
00242 /////////////////////////////////////////////////////////////////////////////
00243 ///
00244 /// CTime --
00245 ///
00246 /// Defines a standard Date/Time class.
00247 ///
00248 /// Can be used to span time (to represent elapsed time). Can operate with
00249 /// local and GMT (aka UTC) time. The time is kept in class in the format
00250 /// in which it was originally given.
00251 ///
00252 /// Throw exception of type CTimeException on errors.
00253 ///
00254 /// NOTE: Do not use local time with time span and dates < "1/1/1900"
00255 /// (use GMT time only!!!).
00256 
00257 class  CTime
00258 {
00259 public:
00260     /// Which initial value to use for time.
00261     enum EInitMode {
00262         eCurrent,     ///< Use current time
00263         eEmpty        ///< Use "empty" time
00264     };
00265 
00266     /// Which initial value to use for timezone.
00267     enum ETimeZone {
00268         eLocal,       ///< Use local time
00269         eGmt          ///< Use GMT (Greenwich Mean Time)
00270     };
00271 
00272     /// Current timezone. Used in AsString() method.
00273     enum {
00274         eCurrentTimeZone = -1
00275     };
00276 
00277     /// Which format use to get name of month or week of day.
00278     enum ENameFormat {
00279         eFull,        ///< Use full name.
00280         eAbbr         ///< Use abbreviated name.
00281     };
00282 
00283     /// Month names.
00284     enum EMonth {
00285         eJanuary = 1,
00286         eFebruary,
00287         eMarch,
00288         eApril,
00289         eMay,
00290         eJune,
00291         eJuly,
00292         eAugust,
00293         eSeptember,
00294         eOctober,
00295         eNovember,
00296         eDecember
00297     };
00298 
00299     /// Day of week names.
00300     enum EDayOfWeek {
00301         eSunday = 0,
00302         eMonday,
00303         eTuesday,
00304         eWednesday,
00305         eThursday,
00306         eFriday,
00307         eSaturday
00308     };
00309 
00310     /// What time zone precision to use for adjusting daylight saving time.
00311     ///
00312     /// Controls when (if ever) to adjust for the daylight saving time
00313     /// (only if the time is represented in local timezone format).
00314     ///
00315     /// NOTE: if diff between previous time value and the time
00316     /// after manipulation is greater than this range, then try apply
00317     /// daylight saving conversion on the result time value.
00318     enum ETimeZonePrecision {
00319         eNone,    ///< Daylight saving not to affect time manipulations.
00320         eMinute,  ///< Check condition - new minute.
00321         eHour,    ///< Check condition - new hour.
00322         eDay,     ///< Check condition - new day.
00323         eMonth,   ///< Check condition - new month.
00324         eTZPrecisionDefault = eNone
00325     };
00326 
00327     /// Whether to adjust for daylight saving time.
00328     enum EDaylight {
00329         eIgnoreDaylight,   ///< Ignore daylight saving time.
00330         eAdjustDaylight,   ///< Adjust for daylight saving time.
00331         eDaylightDefault = eAdjustDaylight
00332     };
00333 
00334     /// Constructor.
00335     ///
00336     /// @param mode
00337     ///   Whether to build time object with current time or empty
00338     ///   time (default).
00339     /// @param tz
00340     ///   Whether to use local time (default) or GMT.
00341     /// @param tzp
00342     ///   What time zone precision to use.
00343     CTime(EInitMode          mode = eEmpty,
00344           ETimeZone          tz   = eLocal,
00345           ETimeZonePrecision tzp  = eTZPrecisionDefault);
00346 
00347     /// Conversion constructor for time_t representation of time.
00348     ///
00349     /// Construct time object from GMT time_t value.
00350     /// The constructed object will be in the eGMT format.
00351     ///
00352     /// @param t
00353     ///   Time in the GMT time_t format.
00354     /// @param tzp
00355     ///   What time zone precision to use.
00356     /// @sa SetTimeT, GetTimeT
00357     explicit CTime(time_t t, ETimeZonePrecision tzp = eTZPrecisionDefault);
00358 
00359     /// Conversion constructor for "struct tm" local time representation.
00360     ///
00361     /// Construct time object from "struct tm" time value.
00362     /// The constructed object will be in the eLocal format.
00363     ///
00364     /// @param t
00365     ///   Time in "struct tm" format.
00366     /// @param tzp
00367     ///   What time zone precision to use.
00368     /// @sa SetTimeTM, GetTimeTM
00369     CTime(const struct tm& t, ETimeZonePrecision tzp = eTZPrecisionDefault);
00370 
00371     /// Constructor.
00372     ///
00373     /// Construct time given the year, month, day, hour, minute, second,
00374     /// nanosecond parts of a time value.
00375     ///
00376     /// @param year
00377     ///   Year part of time.
00378     /// @param month
00379     ///   Month part of time. Note month starts from 1.
00380     /// @param day
00381     ///   Day part of time. Note day starts from 1.
00382     /// @param hour
00383     ///   Hour part of time.
00384     /// @param minute
00385     ///   Minute part of time.
00386     /// @param second
00387     ///   Second part of time.
00388     /// @param nanosecond
00389     ///   Nanosecond part of time.
00390     /// @param tz
00391     ///   Whether to use local time (default) or GMT.
00392     /// @param tzp
00393     ///   What time zone precision to use.
00394     CTime(int year, int month, int day,
00395           int hour = 0, int minute = 0, int second = 0, long nanosecond = 0,
00396           ETimeZone tz = eLocal,
00397           ETimeZonePrecision tzp = eTZPrecisionDefault);
00398 
00399     /// Constructor.
00400     ///
00401     /// Construct date as N-th day of the year.
00402     ///
00403     /// @param year
00404     ///   Year part of date.
00405     /// @param yearDayNumber
00406     ///   N-th day of the year.
00407     /// @param tz
00408     ///   Whether to use local time (default) or GMT.
00409     /// @param tzp
00410     ///   What time zone precision to use.
00411     CTime(int year, int yearDayNumber,
00412           ETimeZone tz = eLocal,
00413           ETimeZonePrecision tzp = eTZPrecisionDefault);
00414 
00415     /// Explicit conversion constructor for string representation of time.
00416     ///
00417     /// Construct time object from string representation of time.
00418     ///
00419     /// @param str
00420     ///   String representation of time in format "fmt".
00421     /// @param fmt
00422     ///   Format in which "str" is presented. Default value of kEmptyStr,
00423     ///   implies the format, that was previously setup using SetFormat()
00424     ///   method, or default "M/D/Y h:m:s".
00425     /// @param tz
00426     ///   Whether to use local time (default) or GMT.
00427     /// @param tzp
00428     ///   What time zone precision to use.
00429     /// @sa AsString, operator=
00430     explicit CTime(const string& str, const CTimeFormat& fmt = kEmptyStr,
00431                    ETimeZone tz = eLocal,
00432                    ETimeZonePrecision tzp = eTZPrecisionDefault);
00433 
00434     /// Copy constructor.
00435     CTime(const CTime& t);
00436 
00437     /// Assignment operator.
00438     CTime& operator= (const CTime& t);
00439 
00440     /// Assignment operator.
00441     ///
00442     /// If current format contains 'Z', then objects timezone will be set to:
00443     ///   - eGMT if "str" has word "GMT" in the appropriate position;
00444     ///   - eLocal otherwise.
00445     /// If current format does not contain 'Z', objects timezone
00446     /// will not be changed.
00447     /// NOTE: This operator expect a string in the format, 
00448     ///       that was previously setup using SetFormat() method.
00449     /// @sa CTime constructor from string, AsString
00450     CTime& operator= (const string& str);
00451 
00452     /// Set time using time_t time value.
00453     ///
00454     /// @param t
00455     ///   Time to set in time object. This is always in GMT time format, and
00456     ///   nanoseconds will be truncated.
00457     /// @return
00458     ///   Time object that is set.
00459     CTime& SetTimeT(const time_t& t);
00460 
00461     /// Get time in time_t format.
00462     ///
00463     /// The function return the number of seconds elapsed since midnight
00464     /// (00:00:00), January 1, 1970. Do not use this function if year is
00465     /// less 1970.
00466     /// @return
00467     ///   Time in time_t format.
00468     time_t GetTimeT(void) const;
00469 
00470     /// Set time using "struct tm" time value.
00471     ///
00472     /// @param t
00473     ///   Time to set in time object. This time always represents a local
00474     ///   time in current time zone. Time object will be set to have eLocal
00475     ///   time format, and nanoseconds will be truncated. Note, that all 
00476     ///   significant fields in the time structure should be set and have
00477     ///   correct vales, otherwise exception will be thrown.
00478     /// @return
00479     ///   Time object that is set.
00480     CTime& SetTimeTM(const struct tm& t);
00481 
00482     /// Get time in "struct tm" format.
00483     ///
00484     /// @return
00485     ///   Time in "struct tm" format (local time).
00486     struct tm GetTimeTM(void) const;
00487 
00488     /// Set time using database format time, TDBTimeU.
00489     ///
00490     /// Object's time format will always change to eLocal after call.
00491     ///
00492     /// @param t
00493     ///   Time to set in time object in TDBTimeU format.
00494     ///   This is always in local time format, and seconds, and nanoseconds
00495     ///   will be truncated.
00496     /// @return
00497     ///   Time object that is set.
00498     CTime& SetTimeDBU(const TDBTimeU& t);
00499 
00500     /// Set time using database format time, TDBTimeI.
00501     ///
00502     /// Object's time format will always change to eLocal after call.
00503     ///
00504     /// @param t
00505     ///   Time to set in time object in TDBTimeI format.
00506     ///   This is always in local time format, and seconds, and nanoseconds
00507     ///   will be truncated.
00508     /// @return
00509     ///   Time object that is set.
00510     CTime& SetTimeDBI(const TDBTimeI& t);
00511 
00512     /// Get time in database format time, TDBTimeU.
00513     ///
00514     /// @return
00515     ///   Time value in database format, TDBTimeU.
00516     TDBTimeU GetTimeDBU(void) const;
00517 
00518     /// Get time in database format time, TDBTimeI.
00519     ///
00520     /// @return
00521     ///   Time value in database format TDBTimeI.
00522     TDBTimeI GetTimeDBI(void) const;
00523 
00524     /// Make the time current in the presently active time zone.
00525     CTime& SetCurrent(void);
00526 
00527     /// Make the time "empty",
00528     CTime& Clear(void);
00529 
00530     /// Set the current time format.
00531     ///
00532     /// The default format is: "M/D/Y h:m:s".
00533     /// @param format
00534     ///   An object contains string of letters describing the time
00535     ///   format and its type. The format letters have
00536     ///   the following meanings:
00537     ///   - Y = year with century
00538     ///   - y = year without century           (00-99)
00539     ///   - M = month as decimal number        (01-12)
00540     ///   - B = full month name                (January-December)
00541     ///   - b = abbeviated month name          (Jan-Dec)
00542     ///   - D = day as decimal number          (01-31)
00543     ///   - d = day as decimal number (w/o 0)  (1-31)
00544     ///   - H = hour in 12-hour format         (00-12)
00545     ///   - h = hour in 24-hour format         (00-23)
00546     ///   - m = minute as decimal number       (00-59)
00547     ///   - s = second as decimal number       (00-59)
00548     ///   - l = milliseconds as decimal number (000-999)
00549     ///   - r = microseconds as decimal number (000000-999999)
00550     ///   - S = nanosecond as decimal number   (000000000-999999999)
00551     ///   - P = am/pm                          (AM/PM)
00552     ///   - p = am/pm                          (am/pm)
00553     ///   - Z = timezone format                (GMT or none)
00554     ///   - z = timezone shift                 ([GMT]+/-HHMM)
00555     ///         -- available only on POSIX platforms
00556     ///   - W = full day of week name          (Sunday-Saturday)
00557     ///   - w = abbreviated day of week name   (Sun-Sat)
00558     ///
00559     ///   Format string can represent date/time partially, in this case
00560     ///   current time, or defaut values, will be used to amplify time
00561     ///   object, if possible. Current date/time cannot be used
00562     ///   if format string contains "z" (time shift) format symbol.
00563     ///   Also, it cannot be used if time format is ambiguous, like "Y/D".
00564     ///   Note, that you still can use "Y/M", or even "Y", where month and
00565     ///   day will be defined to 1; or "M/D", where year will be set as
00566     ///   current year.
00567     /// @sa
00568     ///   CTimeFormat, GetFormat, AsString
00569     static void SetFormat(const CTimeFormat& format);
00570 
00571     /// Get the current time format.
00572     ///
00573     /// The default format is: "M/D/Y h:m:s".
00574     /// @return
00575     ///   An object describing the time format.
00576     /// @sa
00577     ///   CTimeFormat, SetFormat, AsString
00578     static CTimeFormat GetFormat(void);
00579 
00580     /// Get numerical value of the month by name.
00581     ///
00582     /// @param month
00583     ///   Full or abbreviated month name.
00584     /// @return
00585     ///   Numerical value of a given month (1..12).
00586     /// @sa
00587     ///   MonthNumToName, Month
00588     static int MonthNameToNum(const string& month);
00589 
00590     /// Get name of the month by numerical value.
00591     ///
00592     /// @param month
00593     ///   Full or abbreviated month name.
00594     /// @param format
00595     ///   Format for returned value (full or abbreviated).
00596     /// @return
00597     ///   Name of the month.
00598     /// @sa
00599     ///   MonthNameToNum, Month
00600     static string MonthNumToName(int month, ENameFormat format = eFull);
00601 
00602     /// Get numerical value of the day of week by name.
00603     ///
00604     /// @param day
00605     ///   Full or abbreviated day of week name.
00606     /// @return
00607     ///   Numerical value of a given day of week (0..6).
00608     /// @sa
00609     ///   DayOfWeekNumToName, DayOfWeek
00610     static int DayOfWeekNameToNum(const string& day);
00611 
00612     /// Get name of the day of week by numerical value.
00613     ///
00614     /// @param day
00615     ///   Full or abbreviated day of week name.
00616     /// @param format
00617     ///   Format for returned value (full or abbreviated).
00618     /// @return
00619     ///   Name of the day of week.
00620     /// @sa
00621     ///   DayOfWeekNameToNum, DayOfWeek
00622     static string DayOfWeekNumToName(int day, ENameFormat format = eFull);
00623 
00624     /// Transform time to string.
00625     ///
00626     /// @param format
00627     ///   Format specifier used to convert time to string.
00628     ///   If "format" is not defined, then GetFormat() will be used.
00629     /// @param out_tz
00630     ///   Output timezone. This is a difference in seconds between GMT time
00631     ///   and local time for some place (for example, for EST5 timezone
00632     ///   its value is 18000). This parameter works only with local time.
00633     ///   If the time object have GMT time that it is ignored.
00634     ///   Before transformation to string the time will be converted to output
00635     ///   timezone. Timezone can be printed as string 'GMT[+|-]HHMM' using
00636     ///   format symbol 'z'. By default current timezone is used.
00637     /// @sa
00638     ///   GetFormat, SetFormat
00639     string AsString(const CTimeFormat& format = kEmptyStr,
00640                     TSeconds           out_tz = eCurrentTimeZone) const;
00641 
00642     /// Return time as string using the format returned by GetFormat().
00643     operator string(void) const;
00644 
00645     //
00646     // Get various components of time.
00647     //
00648 
00649     /// Get year.
00650     ///
00651     /// Year = 1900 ..
00652     /// AsString() format symbols "Y", "y".
00653     int Year(void) const;
00654 
00655     /// Get month.
00656     ///
00657     /// Month number = 1..12.
00658     /// AsString() format symbols "M", "B", "b".
00659     int Month(void) const;
00660 
00661     /// Get day.
00662     ///
00663     /// Day of the month = 1..31
00664     /// AsString() format symbol "D".
00665     int Day(void) const;
00666 
00667     /// Get hour.
00668     ///
00669     /// Hours since midnight = 0..23.
00670     /// AsString() format symbol "h".
00671     int Hour(void) const;
00672 
00673     /// Get minute.
00674     ///
00675     /// Minutes after the hour = 0..59
00676     /// AsString() format symbol "m".
00677     int Minute(void) const;
00678 
00679     /// Get second.
00680     ///
00681     /// Seconds after the minute = 0..59
00682     /// AsString() format symbol "s".
00683     int Second(void) const;
00684 
00685     /// Get milliseconds.
00686     ///
00687     /// Milliseconds after the second = 0..999
00688     /// AsString() format symbol "l".
00689     /// @sa
00690     ///   NanoSecond
00691     long MilliSecond(void) const;
00692 
00693     /// Get microseconds.
00694     ///
00695     /// Microseconds after the second = 0..999999
00696     /// AsString() format symbol "r".
00697     /// @sa
00698     ///   NanoSecond
00699     long MicroSecond(void) const;
00700 
00701     /// Get nano-seconds.
00702     ///
00703     /// Nano-seconds after the second = 0..999999999
00704     /// AsString() format symbol "S".
00705     /// @sa
00706     ///   MilliSecond, MicroSecond
00707     long NanoSecond(void) const;
00708 
00709     //
00710     // Set various components of time.
00711     //
00712 
00713     /// Set year.
00714     ///
00715     /// Beware that this operation is inherently inconsistent.
00716     /// In case of different number of days in the months, the day number
00717     /// can change, e.g.:
00718     ///  - "Feb 29 2000".SetYear(2001) => "Feb 28 2001".
00719     /// Because 2001 is not leap year.
00720     /// @param year
00721     ///   Year to set.
00722     /// @sa
00723     ///   Year
00724     void SetYear(int year);
00725 
00726     /// Set month.
00727     ///
00728     /// Beware that this operation is inherently inconsistent.
00729     /// In case of different number of days in the months, the day number
00730     /// can change, e.g.:
00731     ///  - "Dec 31 2000".SetMonth(2) => "Feb 29 2000".
00732     /// Therefore e.g. calling SetMonth(1) again that result will be "Jan 28".
00733     /// @param month
00734     ///   Month number to set. Month number = 1..12.
00735     /// @sa
00736     ///   Month
00737     void SetMonth(int month);
00738 
00739     /// Set day.
00740     ///
00741     /// Beware that this operation is inherently inconsistent.
00742     /// In case of number of days in the months, the day number
00743     /// can change, e.g.:
00744     ///  - "Feb 01 2000".SetDay(31) => "Feb 29 2000".
00745     /// @param day
00746     ///   Day to set. Day of the month = 1..31.
00747     /// @sa
00748     ///   Day
00749     void SetDay(int day);
00750 
00751     /// Set hour.
00752     ///
00753     /// @param hour
00754     ///   Hours since midnight = 0..23.
00755     /// @sa
00756     ///   Hour
00757     void SetHour(int hour);
00758 
00759     /// Set minute.
00760     ///
00761     /// @param minute
00762     ///   Minutes after the hour = 0..59.
00763     /// @sa
00764     ///   Minute
00765     void SetMinute(int minute);
00766 
00767     /// Set second.
00768     ///
00769     /// @param second
00770     ///   Seconds after the minute = 0..59.
00771     /// @sa
00772     ///   Second
00773     void SetSecond(int second);
00774 
00775     /// Set milliseconds.
00776     ///
00777     /// @param millisecond
00778     ///   Milliseconds after the second = 0..999.
00779     /// @sa
00780     ///   MilliSecond, SetNanoSecond
00781     void SetMilliSecond(long millisecond);
00782 
00783     /// Set microseconds.
00784     ///
00785     /// @param microsecond
00786     ///   Microseconds after the second = 0..999999.
00787     /// @sa
00788     ///   MicroSecond, SetNanoSecond
00789     void SetMicroSecond(long microsecond);
00790 
00791     /// Set nanoseconds.
00792     ///
00793     /// @param nanosecond
00794     ///   Nanoseconds after the second = 0..999999999.
00795     /// @sa
00796     ///   NanoSecond, SetMilliSecond, SetMicroSecond
00797     void SetNanoSecond(long nanosecond);
00798 
00799     /// Get year's day number.
00800     ///
00801     /// Year day number = 1..366
00802     int YearDayNumber(void) const;
00803 
00804     /// Get this date's week number within the year.
00805     ///
00806     /// Calculate the week number in a year of a given date.
00807     /// The week can start on any day accordingly given parameter.
00808     /// First week always start with 1st January.
00809     /// @param week_start
00810     ///   What day of week is first.
00811     ///   Default is to use Sunday as first day of week. For Monday-based
00812     ///   weeks use eMonday as parameter value.
00813     /// @return
00814     ///   Week number = 1..54.
00815     int YearWeekNumber(EDayOfWeek first_day_of_week = eSunday) const;
00816 
00817     /// Get this date's week number in the month.
00818     ///
00819     /// @return
00820     ///   Week number in the month = 1..6.
00821     /// @sa
00822     ///   YearWeekNumber
00823     int MonthWeekNumber(EDayOfWeek first_day_of_week = eSunday) const;
00824 
00825     /// Get day of week.
00826     ///
00827     /// Days since Sunday = 0..6
00828     /// AsString() format symbols "W", "w".
00829     int DayOfWeek(void) const;
00830 
00831     /// Get number of days in the month.
00832     ///
00833     /// Number of days = 1..31
00834     int DaysInMonth(void) const;
00835 
00836     /// Add specified years and adjust for daylight saving time.
00837     ///
00838     /// It is an exact equivalent of calling AddMonth(years * 12).
00839     /// @sa
00840     ///   AddMonth
00841     CTime& AddYear(int years = 1, EDaylight adl = eDaylightDefault);
00842 
00843     /// Add specified months and adjust for daylight saving time.
00844     ///
00845     /// Beware that this operation is inherently inconsistent.
00846     /// In case of different number of days in the months, the day number
00847     /// can change, e.g.:
00848     ///  - "Dec 31 2000".AddMonth(2) => "Feb 28 2001" ("Feb 29" if leap year).
00849     /// Therefore e.g. calling AddMonth(1) 12 times for e.g. "Jul 31" will
00850     /// result in "Jul 28" (or "Jul 29") of the next year.
00851     /// @param months
00852     ///   Months to add. Default is 1 month.
00853     ///   If negative, it will result in a "subtraction" operation.
00854     /// @param adl
00855     ///   Whether to adjust for daylight saving time. Default is to adjust
00856     ///   for daylight savings time. This parameter is for eLocal time zone
00857     ///   and where the time zone precision is not eNone.
00858     CTime& AddMonth(int months = 1, EDaylight adl = eDaylightDefault);
00859 
00860     /// Add specified days and adjust for daylight saving time.
00861     ///
00862     /// @param days
00863     ///   Days to add. Default is 1 day.
00864     ///   If negative, it will result in a "subtraction" operation.
00865     /// @param adl
00866     ///   Whether to adjust for daylight saving time. Default is to adjust
00867     ///   for daylight saving time. This parameter is for eLocal time zone
00868     ///   and where the time zone precision is not eNone.
00869     CTime& AddDay(int days = 1, EDaylight adl = eDaylightDefault);
00870 
00871     /// Add specified hours and adjust for daylight saving time.
00872     ///
00873     /// @param hours
00874     ///   Hours to add. Default is 1 hour.
00875     ///   If negative, it will result in a "subtraction" operation.
00876     /// @param adl
00877     ///   Whether to adjust for daylight saving time. Default is to adjust
00878     ///   for daylight saving time. This parameter is for eLocal time zone
00879     ///   and where the time zone precision is not eNone.
00880     CTime& AddHour(int hours = 1, EDaylight adl = eDaylightDefault);
00881 
00882     /// Add specified minutes and adjust for daylight saving time.
00883     ///
00884     /// @param minutes
00885     ///   Minutes to add. Default is 1 minute.
00886     ///   If negative, it will result in a "subtraction" operation.
00887     /// @param adl
00888     ///   Whether to adjust for daylight saving time. Default is to adjust
00889     ///   for daylight saving time. This parameter is for eLocal time zone
00890     ///   and where the time zone precision is not eNone.
00891     CTime& AddMinute(int minutes = 1, EDaylight adl = eDaylightDefault);
00892 
00893     /// Add specified seconds.
00894     ///
00895     /// @param seconds
00896     ///   Seconds to add. Default is 1 second.
00897     ///   If negative, it will result in a "subtraction" operation.
00898     CTime& AddSecond(TSeconds seconds = 1, EDaylight adl = eDaylightDefault);
00899 
00900     /// Add specified nanoseconds.
00901     ///
00902     /// @param nanoseconds
00903     ///   Nanoseconds to add. Default is 1 nanosecond.
00904     ///   If negative, it will result in a "subtraction" operation.
00905     CTime& AddNanoSecond(long nanoseconds = 1);
00906 
00907     /// Add specified time span.
00908     ///
00909     /// @param timespan
00910     ///   Object of CTimeSpan class to add.
00911     ///   If negative, it will result in a "subtraction" operation.
00912     CTime& AddTimeSpan(const CTimeSpan& timespan);
00913 
00914 
00915     /// Precision for rounding time.
00916     /// @sa Round, Truncate
00917     enum ERoundPrecision {
00918         eRound_Day,         ///< Round to days
00919         eRound_Hour,        ///< Round to hours
00920         eRound_Minute,      ///< Round to minutes
00921         eRound_Second,      ///< Round to seconds
00922         eRound_Millisecond, ///< Round to milliseconds
00923         eRound_Microsecond  ///< Round to microseconds
00924     };
00925 
00926     /// Round time.
00927     ///
00928     /// Round stored time to specified precision. All time components with
00929     /// precision less that specified will be zero-filled, all other
00930     /// components will be adjusted accondingly to rules for rounding
00931     /// numbers.
00932     /// @param precision
00933     ///   Rounding precision. 
00934     /// @param adl
00935     ///   Whether to adjust for daylight saving time. Default is to adjust
00936     ///   for daylight saving time. This parameter is for eLocal time zone
00937     ///   and where the time zone precision is not eNone.
00938     /// @sa ERoundPrecision, Truncate
00939     CTime& Round(ERoundPrecision precision = eRound_Day, 
00940                  EDaylight       adl       = eDaylightDefault);
00941 
00942     /// Truncate time.
00943     ///
00944     /// Truncate stored time to specified precision. All time components with
00945     /// precision less that specified will be zero-filled. 
00946     /// By default method strips hours, minutes, seconds and nanoseconds.
00947     /// @param precision
00948     ///   Truncating precision. 
00949     /// @sa ERoundPrecision, Round
00950     CTime& Truncate(ERoundPrecision precision = eRound_Day);
00951 
00952     //
00953     // Add/subtract time span
00954     //
00955 
00956     // Operator to add time span.
00957     CTime& operator+= (const CTimeSpan& ts);
00958 
00959     /// Operator to subtract time span.
00960     CTime& operator-= (const CTimeSpan& ts);
00961 
00962     // Operator to add time span.
00963     CTime operator+ (const CTimeSpan& ts) const;
00964 
00965     /// Operator to subtract time span.
00966     CTime operator- (const CTimeSpan& ts) const;
00967 
00968     /// Operator to subtract times.
00969     CTimeSpan operator- (const CTime& t) const;
00970 
00971     //
00972     // Time comparison ('>' means "later", '<' means "earlier")
00973     //
00974 
00975     /// Operator to test equality of time.
00976     bool operator== (const CTime& t) const;
00977 
00978     /// Operator to test in-equality of time.
00979     bool operator!= (const CTime& t) const;
00980 
00981     /// Operator to test if time is later.
00982     bool operator>  (const CTime& t) const;
00983 
00984     /// Operator to test if time is earlier.
00985     bool operator<  (const CTime& t) const;
00986 
00987     /// Operator to test if time is later or equal.
00988     bool operator>= (const CTime& t) const;
00989 
00990     /// Operator to test if time is earlier or equal.
00991     bool operator<= (const CTime& t) const;
00992 
00993     //
00994     // Time difference
00995     //
00996 
00997     /// Difference in whole days from specified time.
00998     int DiffWholeDays(const CTime& t) const;
00999 
01000     /// Difference in days from specified time.
01001     double DiffDay(const CTime& t) const;
01002 
01003     /// Difference in hours from specified time.
01004     double DiffHour(const CTime& t) const;
01005 
01006     /// Difference in minutes from specified time.
01007     double DiffMinute(const CTime& t) const;
01008 
01009     /// Difference in seconds from specified time.
01010     TSeconds DiffSecond(const CTime& t) const;
01011 
01012     /// Difference in nanoseconds from specified time.
01013     double DiffNanoSecond(const CTime& t) const;
01014 
01015     /// Difference in nanoseconds from specified time.
01016     CTimeSpan DiffTimeSpan(const CTime& t) const;
01017 
01018     //
01019     // Checks
01020     //
01021 
01022     /// Is time object empty (date and time)?
01023     bool IsEmpty     (void) const;
01024 
01025     /// Is date empty?
01026     bool IsEmptyDate (void) const;
01027 
01028     /// Is time in a leap year?
01029     bool IsLeap      (void) const;
01030 
01031     /// Is time valid?
01032     bool IsValid     (void) const;
01033 
01034     /// Is time local time?
01035     bool IsLocalTime (void) const;
01036 
01037     /// Is time GMT time?
01038     bool IsGmtTime   (void) const;
01039 
01040     //
01041     // Timezone functions
01042     //
01043 
01044     /// Get time zone.
01045     ETimeZone GetTimeZone(void) const;
01046     NCBI_DEPRECATED ETimeZone GetTimeZoneFormat(void) const;
01047 
01048     /// Set time zone.
01049     ETimeZone SetTimeZone(ETimeZone val);
01050     NCBI_DEPRECATED ETimeZone SetTimeZoneFormat(ETimeZone val);
01051 
01052     /// Get time zone precision.
01053     ETimeZonePrecision GetTimeZonePrecision(void) const;
01054 
01055     /// Set time zone precision.
01056     ETimeZonePrecision SetTimeZonePrecision(ETimeZonePrecision val);
01057 
01058     /// Get difference between local timezone and GMT in seconds.
01059     TSeconds TimeZoneDiff(void) const;
01060 
01061     /// Get the time as local time.
01062     CTime GetLocalTime(void) const;
01063 
01064     /// Get the time as GMT time.
01065     CTime GetGmtTime(void) const;
01066 
01067     /// Convert the time into specified time zone time.
01068     CTime& ToTime(ETimeZone val);
01069 
01070     /// Convert the time into local time.
01071     CTime& ToLocalTime(void);
01072 
01073     /// Convert the time into GMT time.
01074     CTime& ToGmtTime(void);
01075 
01076 private:
01077     /// Helper method to set time value from string "str" using "format".
01078     void x_Init(const string& str, const CTimeFormat& format);
01079 
01080     /// Helper method to set time from 'time_t' -- If "t" not specified,
01081     /// then set to current time.
01082     CTime& x_SetTime(const time_t* t = 0);
01083 
01084     /// Version of x_SetTime() with MT-safe locks
01085     CTime& x_SetTimeMTSafe(const time_t* t = 0);
01086 
01087     /// Helper method to adjust day number to correct value after day
01088     /// manipulations.
01089     void x_AdjustDay(void);
01090 
01091     /// Helper method to adjust the time to correct timezone (across the
01092     /// barrier of winter & summer times) using "from" as a reference point.
01093     ///
01094     /// This does the adjustment only if the time object:
01095     /// - contains local time (not GMT), and
01096     /// - has TimeZonePrecision != CTime::eNone, and
01097     /// - differs from "from" in the TimeZonePrecision (or larger) part.
01098     CTime& x_AdjustTime(const CTime& from, bool shift_time = true);
01099 
01100     /// Helper method to forcibly adjust timezone using "from" as a
01101     /// reference point.
01102     CTime& x_AdjustTimeImmediately(const CTime& from, bool shift_time = true);
01103 
01104     /// Helper method to check if there is a need adjust time in timezone.
01105     bool x_NeedAdjustTime(void) const;
01106 
01107     /// Helper method to add hour with/without shift time.
01108     /// Parameter "shift_time" access or denied use time shift in
01109     /// process adjust hours.
01110     CTime& x_AddHour(int hours = 1, EDaylight daylight = eDaylightDefault,
01111                      bool shift_time = true);
01112 
01113 private:
01114 #if defined(NCBI_COMPILER_WORKSHOP)  &&  defined(__x86_64)  &&  NCBI_COMPILER_VERSION < 590
01115 // Work around some WorkShop versions' incorrect handling of bitfields
01116 // when compiling for x86-64 (at least with optimization enabled) by
01117 // not using them at all. :-/
01118 #  define NCBI_TIME_BITFIELD(n)
01119 #  define NCBI_TIME_EMPTY_BITFIELD
01120 #else
01121 #  define NCBI_TIME_BITFIELD(n)    : n
01122 #  define NCBI_TIME_EMPTY_BITFIELD unsigned : 0;
01123 #endif
01124     typedef struct {
01125         // Time
01126         unsigned int  year        NCBI_TIME_BITFIELD(12);  // 4 digits
01127         unsigned char month       NCBI_TIME_BITFIELD( 4);  // 0..12
01128         unsigned char day         NCBI_TIME_BITFIELD( 5);  // 0..31
01129         unsigned char hour        NCBI_TIME_BITFIELD( 5);  // 0..23
01130         unsigned char min         NCBI_TIME_BITFIELD( 6);  // 0..59
01131         unsigned char sec         NCBI_TIME_BITFIELD( 6);  // 0..61
01132         // Difference between GMT and local time in seconds,
01133         // as stored during the last call to x_AdjustTime***().
01134         Int4          adjTimeDiff NCBI_TIME_BITFIELD(18);
01135         // Timezone and precision
01136         ETimeZone     tz          NCBI_TIME_BITFIELD(2);  // local/GMT
01137         ETimeZonePrecision tzprec NCBI_TIME_BITFIELD(4);  // Time zone precision
01138         NCBI_TIME_EMPTY_BITFIELD  // Force alignment
01139         Int4          nanosec;
01140     } TData;
01141     TData m_Data;  ///< Packed members
01142 
01143     // Friend class
01144     friend class CFastLocalTime;
01145 };
01146 
01147 
01148 
01149 /////////////////////////////////////////////////////////////////////////////
01150 ///
01151 /// CTimeSpan
01152 ///
01153 /// Defines a class to represents a relative time span.
01154 /// Time span can be both positive and negative.
01155 ///
01156 /// Throw exception of type CTimeException on errors.
01157 
01158 class  CTimeSpan
01159 {
01160 public:
01161     /// Default constructor.
01162     CTimeSpan(void);
01163 
01164     /// Constructor.
01165     ///
01166     /// Construct time span given the number of days, hours, minutes, seconds,
01167     /// nanoseconds parts of a time span value.
01168     /// @param days
01169     ///   Day part of time. Note day starts from 1.
01170     /// @param hours
01171     ///   Hour part of time.
01172     /// @param minutes
01173     ///   Minute part of time.
01174     /// @param seconds
01175     ///   Second part of time.
01176     /// @param nanoseconds
01177     ///   Nanosecond part of time.
01178     CTimeSpan(long days, long hours, long minutes, long seconds,
01179               long nanoseconds = 0);
01180 
01181     /// Constructor.
01182     ///
01183     /// Construct time span given the number of seconds and nanoseconds.
01184     /// @param seconds
01185     ///   Second part of time.
01186     /// @param nanoseconds
01187     ///   Nanosecond part of time.
01188     explicit CTimeSpan(long seconds, long nanoseconds = 0);
01189 
01190     /// Constructor.
01191     ///
01192     /// Construct time span from number of seconds.
01193     /// Please, use this constructor as rarely as possible, because after
01194     /// doing some arithmetical operations and conversion with it,
01195     /// the time span can differ at some nanoseconds from expected value.
01196     /// @param seconds
01197     ///   Second part of time. The fractional part is used to compute
01198     ///   nanoseconds.
01199     explicit CTimeSpan(double seconds);
01200 
01201     /// Explicit conversion constructor for string representation of time span.
01202     ///
01203     /// Construct time span object from string representation of time.
01204     ///
01205     /// @param str
01206     ///   String representation of time span in format "fmt".
01207     /// @param fmt
01208     ///   Format in which "str" is presented. Default value of kEmptyStr,
01209     ///   implies the "-S.n" format.
01210     explicit CTimeSpan(const string& str, const CTimeFormat& fmt = kEmptyStr);
01211 
01212     /// Copy constructor.
01213     CTimeSpan(const CTimeSpan& t);
01214 
01215     /// Assignment operator.
01216     CTimeSpan& operator= (const CTimeSpan& t);
01217 
01218     /// Assignment operator.
01219     CTimeSpan& operator= (const string& str);
01220 
01221     /// Make the time span "empty",
01222     CTimeSpan& Clear(void);
01223 
01224     /// Get sign of time span.
01225     ESign GetSign(void) const;
01226 
01227     /// Set the current time span format.
01228     ///
01229     /// The default format is: "-S.n".
01230     /// @param format
01231     ///   An object contains string of letters describing the time
01232     ///   format and its type. The format letters have
01233     ///   the following meanings:
01234     ///   - - = add minus for negative time spans
01235     ///   - d = number of whole days
01236     ///   - H = total whole number of hours stored in the time span
01237     ///   - h = hours, "H" modulo 24 (-23 - 23)
01238     ///   - M = total whole number of minutes stored in the time span
01239     ///   - m = minutes, "M" modulo 60 (-59 - 59)
01240     ///   - S = total whole number of seconds stored in the time span
01241     ///   - s = seconds, "S" modulo 60 (-59 - 59)
01242     ///   - N = total whole number of nanoseconds stored in the time span
01243     ///   - n = nanoseconds (-999999999 - 999999999)
01244     /// @sa
01245     ///   CTimeFormat, GetFormat, AsString
01246     static void SetFormat(const CTimeFormat& format);
01247 
01248     /// Get the current time span format.
01249     ///
01250     /// The default format is: "-S.n".
01251     /// @return
01252     ///   An object describing the time format.
01253     /// @sa
01254     ///   CTimeFormat, SetFormat, AsString
01255     static CTimeFormat GetFormat(void);
01256 
01257     /// Transform time span to string.
01258     ///
01259     /// @param format
01260     ///   Format specifier used to convert time span to string.
01261     ///   If "format" is not defined, then GetFormat() will be used.
01262     /// @return
01263     ///   A string representation of time span in specified format.
01264     /// @sa
01265     ///   CTimeFormat, GetFormat, SetFormat
01266     string AsString(const CTimeFormat& format = kEmptyStr) const;
01267 
01268     /// Return span time as string using the format returned by GetFormat().
01269     operator string(void) const;
01270 
01271 
01272     /// Precision for span "smart" string. Used in AsSmartString() method.
01273     enum ESmartStringPrecision {
01274         // Named precision levels
01275         eSSP_Year,               ///< Round to years
01276         eSSP_Month,              ///< Round to months
01277         eSSP_Day,                ///< Round to days
01278         eSSP_Hour,               ///< Round to hours
01279         eSSP_Minute,             ///< Round to minutes
01280         eSSP_Second,             ///< Round to seconds
01281         eSSP_Millisecond,        ///< Round to milliseconds
01282         eSSP_Microsecond,        ///< Round to microseconds
01283         eSSP_Nanosecond,         ///< Do not round at all (accurate time span)
01284 
01285         // Float precision levels (1-7)
01286         eSSP_Precision1,
01287         eSSP_Precision2,
01288         eSSP_Precision3,
01289         eSSP_Precision4,
01290         eSSP_Precision5,
01291         eSSP_Precision6,
01292         eSSP_Precision7,
01293 
01294         eSSP_Default = eSSP_Day  ///< Default precision level
01295     };
01296 
01297     /// Which format use to zero time span output.
01298     enum ESmartStringZeroMode {
01299         eSSZ_SkipZero,           ///< Skip zero valued
01300         eSSZ_NoSkipZero,         ///< Print zero valued
01301         eSSZ_Default = eSSZ_SkipZero
01302     };
01303 
01304     /// Transform time span to "smart" string.
01305     ///
01306     /// @param precision
01307     ///   Enum value describing how many parts of time span should be
01308     ///   returned. Values from eSSP_Year to eSSP_Nanosecond apparently
01309     ///   describe part of time span which will be last in output string.
01310     ///   Floating precision levels eSSP_PrecisionN say that maximum 'N'
01311     ///   parts of time span will be put to output string.
01312     ///   The parts counting begin from first non-zero value.
01313     /// @param rounding
01314     ///   Rounding mode. By default time span will be truncated at last value
01315     //    specified by precision. If mode is eRound, that last significant
01316     //    part of time span will be arifmetically rounded on base .
01317     //    For example, if precison is eSSP_Day and number of hours in time
01318     //    span is 20, that number of days will be increased on 1.
01319     /// @param zero_mode
01320     ///   Mode to print or skip zero parts of time span which should be
01321     ///   printed but have 0 value. Trailing and leading zeros will be
01322     ///   never printed.
01323     /// @return
01324     ///   A string representation of time span.
01325     /// @sa
01326     ///   AsString, ESmartStringPrecision, ERound, ESmartStringZeroMode
01327     string AsSmartString(ESmartStringPrecision precision = eSSP_Default,
01328                          ERound                rounding  = eTrunc,
01329                          ESmartStringZeroMode  zero_mode = eSSZ_Default)
01330                          const;
01331 
01332     //
01333     // Get various components of time span.
01334     //
01335 
01336     /// Get number of complete days.
01337     long GetCompleteDays(void) const;
01338 
01339     /// Get number of complete hours.
01340     long GetCompleteHours(void) const;
01341 
01342     /// Get number of complete minutes.
01343     long GetCompleteMinutes(void) const;
01344 
01345     /// Get number of complete seconds.
01346     long GetCompleteSeconds(void) const;
01347 
01348     /// Get number of nanoseconds.
01349     long GetNanoSecondsAfterSecond(void) const;
01350 
01351     /// Return time span as number of seconds.
01352     ///
01353     /// @return
01354     ///   Return representative of time span as type double.
01355     ///   The fractional part represents nanoseconds part of time span.
01356     ///   The double representation of the time span is aproximate.
01357     double GetAsDouble(void) const;
01358 
01359     /// Return TRUE is an object keep zero time span.
01360     bool IsEmpty(void) const;
01361 
01362     //
01363     // Set time span
01364     //
01365 
01366     /// Set time span in seconds and nanoseconds.
01367     void Set(long seconds, long nanoseconds = 0);
01368 
01369     /// Set time span from number of seconds (fractional value).
01370     void Set(double seconds);
01371 
01372     //
01373     // Arithmetic
01374     //
01375 
01376     // Operator to add time span.
01377     CTimeSpan& operator+= (const CTimeSpan& t);
01378 
01379     // Operator to add time span.
01380     CTimeSpan operator+ (const CTimeSpan& t) const;
01381 
01382     /// Operator to subtract time span.
01383     CTimeSpan& operator-= (const CTimeSpan& t);
01384 
01385     /// Operator to subtract time span.
01386     CTimeSpan operator- (const CTimeSpan& t) const;
01387 
01388     /// Unary operator "-" (minus) to change time span sign.
01389     const CTimeSpan operator- (void) const;
01390 
01391     /// Invert time span. Changes time span sign.
01392     void Invert(void);
01393 
01394     //
01395     // Comparison
01396     //
01397 
01398     /// Operator to test equality of time span.
01399     bool operator== (const CTimeSpan& t) const;
01400 
01401     /// Operator to test in-equality of time span.
01402     bool operator!= (const CTimeSpan& t) const;
01403 
01404     /// Operator to test if time span is greater.
01405     bool operator>  (const CTimeSpan& t) const;
01406 
01407     /// Operator to test if time span is less.
01408     bool operator<  (const CTimeSpan& t) const;
01409 
01410     /// Operator to test if time span is greater or equal.
01411     bool operator>= (const CTimeSpan& t) const;
01412 
01413     /// Operator to test if time span is less or equal.
01414     bool operator<= (const CTimeSpan& t) const;
01415 
01416 private:
01417     /// Get hour.
01418     /// Hours since midnight = -23..23
01419     int x_Hour(void) const;
01420 
01421     /// Get minute.
01422     /// Minutes after the hour = -59..59
01423     int x_Minute(void) const;
01424 
01425     /// Get second.
01426     /// Seconds after the minute = -59..59
01427     int x_Second(void) const;
01428 
01429     /// Helper method to set time value from string "str" using "format".
01430     void x_Init(const string& str, const CTimeFormat& format);
01431 
01432     /// Helper method to normalize stored time value.
01433     void x_Normalize(void);
01434 
01435 private:
01436     long  m_Sec;      ///< Seconds part of the time span
01437     long  m_NanoSec;  ///< Nanoseconds after the second
01438 };
01439 
01440 
01441 
01442 /////////////////////////////////////////////////////////////////////////////
01443 ///
01444 /// CTimeout -- Timeout interval
01445 ///
01446 /// @sa STimeout, CConnTimeout, CTimeSpan
01447 /// @note Throw exception of type CTimeException on errors.
01448 
01449 class  CTimeout
01450 {
01451 public:
01452     /// Type of timeouts.
01453     enum EType {
01454         eDefault,   ///< Default timeout (depends from implementation).
01455         eInfinite,  ///< Infinite timeout.
01456         eZero       ///< Zero timeout, equal to CTimeout(0,0).
01457     };
01458 
01459     /// Create default timeout.
01460     CTimeout(void);
01461 
01462     /// Create timeout of specified type.
01463     CTimeout(EType type);
01464 
01465     /// Initialize timeout from CTimeSpan.
01466     ///
01467     /// @note
01468     ///   Nanoseconds part of the CTimeSpan will be rounded to microseconds.
01469     CTimeout(const CTimeSpan& ts);
01470 
01471     /// Initialize timeout in seconds and microseconds.
01472     CTimeout(unsigned int sec, unsigned int usec);
01473 
01474     /// Initialize timeout from number of seconds (fractional value).
01475     CTimeout(double sec);
01476 
01477     /// Copy constructor.
01478     CTimeout(const CTimeout& t);
01479 
01480     /// Destructor.
01481     ~CTimeout(void) {}
01482 
01483     /// Assignment operator.
01484     const CTimeout& operator= (const CTimeout& t);
01485 
01486     // Check on special timeout values.
01487     bool IsDefault()  const;
01488     bool IsInfinite() const;
01489     bool IsZero()     const;
01490     /// Check if timeout holds a numeric value.
01491     bool IsFinite()   const;
01492 
01493     //
01494     // Get timeout
01495     //
01496 
01497     /// Get as number of milliseconds.
01498     unsigned long GetAsMilliSeconds(void) const;
01499 
01500     /// Get as number of seconds (fractional value).
01501     double GetAsDouble(void) const;
01502 
01503     /// Convert to CTimeSpan.
01504     CTimeSpan GetAsTimeSpan(void) const;
01505 
01506     /// Get timeout in seconds and microseconds.
01507     void Get(unsigned int *sec, unsigned int *usec) const;
01508 
01509 
01510     //
01511     // Set timeout
01512     //
01513 
01514     /// Set special value.
01515     void Set(EType type);
01516 
01517     /// Set timeout in seconds and microseconds.
01518     void Set(unsigned int sec, unsigned int usec);
01519 
01520     /// Set timeout from number of seconds (fractional value).
01521     void Set(double sec);
01522 
01523     /// Set from CTimeSpan.
01524     ///
01525     /// @note
01526     ///   Nanoseconds part of the CTimeSpan will be rounded to microseconds.
01527     void Set(const CTimeSpan& ts);
01528 
01529     //
01530     // Comparison.
01531     // eDefault special value cannot be compared with any value.
01532     //
01533 
01534     /// Operator to test equality of timeouts.
01535     bool operator== (const CTimeout& t) const;
01536 
01537     /// Operator to test in-equality of timeouts.
01538     bool operator!= (const CTimeout& t) const;
01539 
01540     /// Operator to test if timeout is greater.
01541     bool operator>  (const CTimeout& t) const;
01542 
01543     /// Operator to test if timeout is less.
01544     bool operator<  (const CTimeout& t) const;
01545 
01546     /// Operator to test if timeout is greater or equal.
01547     bool operator>= (const CTimeout& t) const;
01548 
01549     /// Operator to test if timeout is less or equal.
01550     bool operator<= (const CTimeout& t) const;
01551 
01552 private:
01553     EType         m_Type;       ///< Type of timeout.
01554     bool          m_HasValue;   ///< Timeout holds numeric value.
01555     unsigned int  m_Sec;        ///< Seconds part of the timeout.
01556     unsigned int  m_MicroSec;   ///< Microseconds part of the timeout.
01557 };
01558 
01559 
01560 
01561 /////////////////////////////////////////////////////////////////////////////
01562 ///
01563 /// CFastLocalTime --
01564 ///
01565 /// Define a class for quick and dirty getting a local time.
01566 ///
01567 /// Getting local time may trigger request to a time server daemon,
01568 /// thus potentially causing a relatively significant delay,
01569 /// so we 'll need a caching local timer.
01570 
01571 class  CFastLocalTime
01572 {
01573 public:
01574     /// Constructor.
01575     /// It should not try to get local time from OS more often than once
01576     /// an hour. Default:  check once, 5 seconds after each hour.
01577     CFastLocalTime(unsigned int sec_after_hour = 5);
01578 
01579     /// Get local time
01580     CTime GetLocalTime(void);
01581 
01582     /// Get difference in seconds between UTC and current local time
01583     /// (daylight information included)
01584     int GetLocalTimezone(void);
01585 
01586     /// Do unscheduled check
01587     void Tuneup(void);
01588 
01589 private:
01590     /// Internal version of Tuneup()
01591     void x_Tuneup(time_t timer, long nanosec);
01592 
01593 private:
01594     unsigned int m_SecAfterHour;  ///< Time interval in seconds after hour
01595                               ///< in which we should avoid to do Tuneup().
01596     CTime   m_LocalTime;      ///< Current local time
01597     CTime   m_TunedTime;      ///< Last tuned time (changed by Tuneup())
01598 
01599     time_t  m_LastTuneupTime; ///< Last Tuneup() time
01600     time_t  m_LastSysTime;    ///< Last system time
01601     int     m_Timezone;       ///< Cached timezone adjustment for local time
01602     int     m_Daylight;       ///< Cached system daylight information
01603     bool    m_IsTuneup;       ///< Tuneup() in progress (MT)
01604 };
01605 
01606 
01607 /////////////////////////////////////////////////////////////////////////////
01608 ///
01609 /// CStopWatch --
01610 ///
01611 /// Define a stop watch class to measure elasped time.
01612 
01613 class  CStopWatch
01614 {
01615 public:
01616     /// Defines how to create new timer.
01617     enum EStart {
01618         eStart,   ///< Stat timer immediately after creating.
01619         eStop     ///< Do not start timer, just create it.
01620     };
01621 
01622     /// Constructor.
01623     /// NB. By default ctor doesn't start timer, it merely creates it.
01624     CStopWatch(EStart state = eStop);
01625 
01626     /// Constructor.
01627     /// Start timer if argument is true.
01628     /// @deprecated Use CStopWatch(EStat) constuctor instead.
01629     NCBI_DEPRECATED_CTOR(CStopWatch(bool start));
01630 
01631     /// Start the timer.
01632     void Start(void);
01633 
01634     /// Return time elapsed since first Start() or last Restart() call
01635     /// (in seconds).
01636     /// Result is 0.0 if Start() or Restart() wasn't previously called.
01637     double Elapsed(void) const;
01638 
01639     /// Suspend the timer.
01640     /// Next Start() call continue to count time accured before.
01641     void Stop(void);
01642 
01643     /// Return time elapsed since first Start() or last Restart() call
01644     /// (in seconds). Start new timer after that.
01645     /// Result is 0.0 if Start() or Restart() wasn't previously called.
01646     double Restart(void);
01647 
01648     /// Check state of stopwatch.
01649     /// @return
01650     ///   TRUE if stopwatch is "running", FALSE otherwise.
01651     /// @sa
01652     ///   Start, Stop
01653     bool IsRunning(void);
01654 
01655     /// Set the current stopwatch time format.
01656     ///
01657     /// The default format is: "-S.n".
01658     /// @param format
01659     ///   Format specifier used to convert time span to string.
01660     ///   If "format" is not defined, then GetFormat() will be used.
01661     ///   Uses the same time format as CTimeSpan class.
01662     /// @sa
01663     ///   CTimeFormat, CTimeSpan::SetFormat, AsString
01664     static void SetFormat(const CTimeFormat& format);
01665 
01666     /// Get the current stopwatch time format.
01667     ///
01668     /// The default format is: "-S.n".
01669     /// @return
01670     ///   An object describing the time format.
01671     ///   The letters having the same means that for CTimeSpan.
01672     /// @sa
01673     ///   CTimeFormat, CTimeSpan::GetFormat, AsString
01674     static CTimeFormat GetFormat(void);
01675 
01676     /// Transform stopwatch time to string.
01677     ///
01678     /// According to used OS, the double representation can provide much
01679     /// finer grained time control. The string representation is limited
01680     /// by nanoseconds.
01681     /// @param format
01682     ///   If "format" is not defined, then GetFormat() will be used.
01683     ///   Format specifier used to convert value returned by Elapsed()
01684     ///   to string.
01685     /// @sa
01686     ///   CTimeSpan::AsString, CTimeFormat, Elapsed, GetFormat, SetFormat
01687     string AsString(const CTimeFormat& format = kEmptyStr) const;
01688 
01689     /// Return stopwatch time as string using the format returned
01690     /// by GetFormat().
01691     operator string(void) const;
01692 
01693     /// Transform elapsed time to "smart" string.
01694     ///
01695     /// For more details see CTimeSpan::AsSmartString().
01696     /// @param precision
01697     ///   Enum value describing how many parts of time span should be
01698     ///   returned.
01699     /// @param rounding
01700     ///   Rounding mode.
01701     /// @param zero_mode
01702     ///   Mode to print or skip zero parts of time span.
01703     /// @return
01704     ///   A string representation of elapsed time span.
01705     /// @sa
01706     ///   CTimeSpan::AsSmartString, AsString, Elapsed
01707     string AsSmartString(
01708         CTimeSpan::ESmartStringPrecision precision = CTimeSpan::eSSP_Nanosecond,
01709         ERound                           rounding  = eTrunc,
01710         CTimeSpan::ESmartStringZeroMode  zero_mode = CTimeSpan::eSSZ_Default)
01711         const;
01712 
01713 protected:
01714     /// Get current time mark.
01715     static double GetTimeMark();
01716 
01717 private:
01718     double m_Start;  ///< Start time value.
01719     double m_Total;  ///< Accumulated elapsed time.
01720     EStart m_State;  ///< Stopwatch state (started/stopped)
01721 };
01722 
01723 
01724 
01725 /////////////////////////////////////////////////////////////////////////////
01726 ///
01727 /// CTimeException --
01728 ///
01729 /// Define exceptions generated by Time API.
01730 ///
01731 /// CTimeException inherits its basic functionality from CCoreException
01732 /// and defines additional error codes.
01733 
01734 class  CTimeException : public CCoreException
01735 {
01736 public:
01737     /// Error types that CTime can generate.
01738     enum EErrCode {
01739         eArgument,     ///< Bad function argument.
01740         eConvert,      ///< Error converting value from one format to another.
01741         eInvalid,      ///< Invalid time value.
01742         eFormat        ///< Incorrect format.
01743     };
01744 
01745     /// Translate from the error code value to its string representation.
01746     virtual const char* GetErrCodeString(void) const;
01747 
01748     // Standard exception boilerplate code.
01749     NCBI_EXCEPTION_DEFAULT(CTimeException, CCoreException);
01750 };
01751 
01752 
01753 /* @} */
01754 
01755 
01756 
01757 //=============================================================================
01758 //
01759 //  Extern
01760 //
01761 //=============================================================================
01762 
01763 /// Quick and dirty getter of local time.
01764 /// Use global object of CFastLocalTime class to obtain time.
01765 /// See CFastLocalTime for details.
01766 
01767 extern CTime GetFastLocalTime(void);
01768 
01769 
01770 extern void TuneupFastLocalTime(void);
01771 
01772 
01773 //=============================================================================
01774 //
01775 //  Inline
01776 //
01777 //=============================================================================
01778 
01779 // Add (subtract if negative) to the time (see CTime::AddXXX)
01780 
01781 inline
01782 CTime AddYear(const CTime& t, int  years = 1)
01783 {
01784     CTime tmp(t);
01785     return tmp.AddYear(years);
01786 }
01787 
01788 inline
01789 CTime AddMonth(const CTime& t, int  months = 1)
01790 {
01791     CTime  tmp(t);
01792     return tmp.AddMonth(months);
01793 }
01794 
01795 inline
01796 CTime AddDay(const CTime& t, int  days = 1)
01797 {
01798     CTime  tmp(t);
01799     return tmp.AddDay(days);
01800 }
01801 
01802 inline
01803 CTime AddHour(const CTime& t, int  hours = 1)
01804 {
01805     CTime  tmp(t);
01806     return tmp.AddHour(hours);
01807 }
01808 
01809 inline
01810 CTime AddMinute(const CTime& t, int  minutes = 1)
01811 {
01812     CTime  tmp(t);
01813     return tmp.AddMinute(minutes);
01814 }
01815 
01816 inline
01817 CTime AddSecond(const CTime& t, long seconds = 1)
01818 {
01819     CTime  tmp(t);
01820     return tmp.AddSecond(seconds);
01821 }
01822 
01823 inline
01824 CTime AddNanoSecond (const CTime& t, long nanoseconds = 1)
01825 {
01826     CTime  tmp(t);
01827     return tmp.AddNanoSecond(nanoseconds);
01828 }
01829 
01830 // Add/subtract CTimeSpan (see CTime::operator +/-)
01831 inline
01832 CTime operator+ (const CTimeSpan& ts, const CTime& t)
01833 {
01834     CTime tmp(t);
01835     tmp.AddTimeSpan(ts);
01836     return tmp;
01837 }
01838 
01839 // Get current time (in local or GMT format)
01840 inline
01841 CTime CurrentTime(
01842     CTime::ETimeZone          tz  = CTime::eLocal,
01843     CTime::ETimeZonePrecision tzp = CTime::eTZPrecisionDefault
01844     )
01845 {
01846     return CTime(CTime::eCurrent, tz, tzp);
01847 }
01848 
01849 // Truncate the time to days (see CTime::Truncate)
01850 inline
01851 CTime Truncate(const CTime& t)
01852 {
01853     CTime  tmp(t);
01854     return tmp.Truncate();
01855 }
01856 
01857 /// Dumps the current stopwatch time to an output stream.
01858 /// The time will be printed out using format specified
01859 /// by CStopWatch::GetFormat().
01860 inline
01861 ostream& operator<< (ostream& os, const CStopWatch& sw)
01862 {
01863     return os << sw.AsString();
01864 }
01865 
01866 /// Dumps the current CTime time to an output stream.
01867 /// The time will be printed out using format
01868 /// returned by CTime::GetFormat().
01869 inline
01870 ostream& operator<< (ostream& os, const CTime& t)
01871 {
01872     return os << t.AsString();
01873 }
01874 
01875 
01876 //=============================================================================
01877 //
01878 //  Inline class methods
01879 //
01880 //=============================================================================
01881 
01882 //
01883 //  CTimeFormat
01884 //
01885 
01886 inline
01887 void CTimeFormat::SetFormat(const string& fmt, TFlags flags)
01888 {
01889     m_Str   = fmt;
01890     m_Flags = flags;
01891 }
01892 
01893 inline
01894 void CTimeFormat::SetFormat(const char* fmt, TFlags flags)
01895 {
01896     m_Str   = fmt;
01897     m_Flags = flags;
01898 }
01899 
01900 inline
01901 const string& CTimeFormat::GetString(void) const
01902 {
01903     return m_Str;
01904 }
01905 
01906 inline
01907 CTimeFormat::TFlags CTimeFormat::GetFlags(void) const
01908 {
01909     return m_Flags;
01910 }
01911 
01912 inline
01913 bool CTimeFormat::IsEmpty(void) const
01914 {
01915     return m_Str.empty();
01916 }
01917 
01918 inline
01919 CTimeFormat::operator string(void) const
01920 {
01921     return m_Str;
01922 }
01923 
01924 
01925 //
01926 //  CTime
01927 //
01928 
01929 inline
01930 int CTime::Year(void) const { return m_Data.year; }
01931 
01932 inline
01933 int CTime::Month(void) const { return m_Data.month; }
01934 
01935 inline
01936 int CTime::Day(void) const { return m_Data.day; }
01937 
01938 inline
01939 int CTime::Hour(void) const { return m_Data.hour; }
01940 
01941 inline
01942 int CTime::Minute(void) const { return m_Data.min; }
01943 
01944 inline
01945 int CTime::Second(void) const { return m_Data.sec; }
01946 
01947 inline
01948 long CTime::MilliSecond(void) const { return (long)m_Data.nanosec/1000000; }
01949 
01950 inline
01951 long CTime::MicroSecond(void) const { return (long)m_Data.nanosec/1000; }
01952 
01953 inline
01954 long CTime::NanoSecond(void) const { return (long)m_Data.nanosec; }
01955 
01956 inline
01957 CTime& CTime::AddYear(int years, EDaylight adl)
01958 {
01959     return AddMonth(years * 12, adl);
01960 }
01961 
01962 inline
01963 CTime& CTime::SetTimeT(const time_t& t) { return x_SetTimeMTSafe(&t); }
01964 
01965 inline
01966 CTime& CTime::SetCurrent(void) { return x_SetTimeMTSafe(); }
01967 
01968 inline
01969 CTime& CTime::operator+= (const CTimeSpan& ts) { return AddTimeSpan(ts); }
01970 
01971 inline
01972 CTime& CTime::operator-= (const CTimeSpan& ts) { return AddTimeSpan(-ts); }
01973 
01974 inline
01975 CTime CTime::operator+ (const CTimeSpan& ts) const
01976 {
01977     CTime tmp(*this);
01978     tmp.AddTimeSpan(ts);
01979     return tmp;
01980 }
01981 
01982 inline
01983 CTime CTime::operator- (const CTimeSpan& ts) const
01984 {
01985     CTime tmp(*this);
01986     tmp.AddTimeSpan(-ts);
01987     return tmp;
01988 }
01989 
01990 inline
01991 CTimeSpan CTime::operator- (const CTime& t) const
01992 {
01993     return DiffTimeSpan(t);
01994 }
01995 
01996 inline
01997 CTime::operator string(void) const { return AsString(); }
01998 
01999 
02000 inline
02001 CTime& CTime::operator= (const string& str)
02002 {
02003     x_Init(str, GetFormat());
02004     return *this;
02005 }
02006 
02007 inline
02008 CTime& CTime::operator= (const CTime& t)
02009 {
02010     if ( &t == this ) {
02011         return *this;
02012     }
02013     m_Data = t.m_Data;
02014     return *this;
02015 }
02016 
02017 inline
02018 bool CTime::operator!= (const CTime& t) const
02019 {
02020     return !(*this == t);
02021 }
02022 
02023 inline
02024 bool CTime::operator>= (const CTime& t) const
02025 {
02026     return !(*this < t);
02027 }
02028 
02029 inline
02030 bool CTime::operator<= (const CTime& t) const
02031 {
02032     return !(*this > t);
02033 }
02034 
02035 inline
02036 CTime& CTime::AddHour(int hours, EDaylight use_daylight)
02037 {
02038     return x_AddHour(hours, use_daylight, true);
02039 }
02040 
02041 inline
02042 bool CTime::IsEmpty() const
02043 {
02044     return
02045         !Day()   &&  !Month()   &&  !Year()  &&
02046         !Hour()  &&  !Minute()  &&  !Second()  &&  !NanoSecond();
02047 }
02048 
02049 inline
02050 bool CTime::IsEmptyDate() const
02051 {
02052     // We check year value only, because all time object date fields
02053     // can be zeros only at one time.
02054     return !Year();
02055 }
02056 
02057 inline
02058 double CTime::DiffDay(const CTime& t) const
02059 {
02060     return (double)DiffSecond(t) / 60.0 / 60.0 / 24.0;
02061 }
02062 
02063 inline
02064 double CTime::DiffHour(const CTime& t) const
02065 {
02066     return (double)DiffSecond(t) / 60.0 / 60.0;
02067 }
02068 
02069 inline
02070 double CTime::DiffMinute(const CTime& t) const
02071 {
02072     return (double)DiffSecond(t) / 60.0;
02073 }
02074 
02075 inline
02076 double CTime::DiffNanoSecond(const CTime& t) const
02077 {
02078     long dNanoSec = NanoSecond() - t.NanoSecond();
02079     return (double) DiffSecond(t) * kNanoSecondsPerSecond + dNanoSec;
02080 }
02081 
02082 inline
02083 bool CTime::IsLocalTime(void) const { return m_Data.tz == eLocal; }
02084 
02085 inline
02086 bool CTime::IsGmtTime(void) const { return m_Data.tz == eGmt; }
02087 
02088 inline
02089 CTime::ETimeZone CTime::GetTimeZone(void) const
02090 {
02091     return m_Data.tz;
02092 }
02093 
02094 inline
02095 CTime::ETimeZone CTime::GetTimeZoneFormat(void) const
02096 {
02097     return GetTimeZone();
02098 }
02099 
02100 inline
02101 CTime::ETimeZonePrecision CTime::GetTimeZonePrecision(void) const
02102 {
02103     return m_Data.tzprec;
02104 }
02105 
02106 inline
02107 CTime::ETimeZone CTime::SetTimeZone(ETimeZone val)
02108 {
02109     ETimeZone tmp = m_Data.tz;
02110     m_Data.tz = val;
02111     return tmp;
02112 }
02113 
02114 inline
02115 CTime::ETimeZone CTime::SetTimeZoneFormat(ETimeZone val)
02116 {
02117     return SetTimeZone(val);
02118 }
02119 
02120 inline
02121 CTime::ETimeZonePrecision CTime::SetTimeZonePrecision(ETimeZonePrecision val)
02122 {
02123     ETimeZonePrecision tmp = m_Data.tzprec;
02124     m_Data.tzprec = val;
02125     return tmp;
02126 }
02127 
02128 inline
02129 CTime& CTime::ToLocalTime(void)
02130 {
02131     ToTime(eLocal);
02132     return *this;
02133 }
02134 
02135 inline
02136 CTime& CTime::ToGmtTime(void)
02137 {
02138     ToTime(eGmt);
02139     return *this;
02140 }
02141 
02142 inline
02143 bool CTime::x_NeedAdjustTime(void) const
02144 {
02145     return GetTimeZone() == eLocal  &&  GetTimeZonePrecision() != eNone;
02146 }
02147 
02148 
02149 //
02150 //  CTimeSpan
02151 //
02152 
02153 inline
02154 CTimeSpan::CTimeSpan(void)
02155 {
02156     Clear();
02157     return;
02158 }
02159 
02160 inline
02161 CTimeSpan::CTimeSpan(long seconds, long nanoseconds)
02162 {
02163     Set(seconds, nanoseconds);
02164 }
02165 
02166 inline
02167 CTimeSpan::CTimeSpan(double seconds)
02168 {
02169     Set(seconds);
02170 }
02171 
02172 inline
02173 CTimeSpan::CTimeSpan(const CTimeSpan& t)
02174 {
02175     m_Sec = t.m_Sec;
02176     m_NanoSec = t.m_NanoSec;
02177 }
02178 
02179 inline
02180 CTimeSpan& CTimeSpan::Clear(void) {
02181     m_Sec = 0;
02182     m_NanoSec = 0;
02183     return *this;
02184 }
02185 
02186 inline
02187 ESign CTimeSpan::GetSign(void) const
02188 {
02189     if ((m_Sec < 0) || (m_NanoSec < 0)) {
02190         return eNegative;
02191     }
02192     if (!m_Sec  &&  !m_NanoSec) {
02193         return eZero;
02194     }
02195     return ePositive;
02196 }
02197 
02198 inline
02199 int CTimeSpan::x_Hour(void) const { return int((m_Sec / 3600L) % 24); }
02200 
02201 inline
02202 int CTimeSpan::x_Minute(void) const { return int((m_Sec / 60L) % 60); }
02203 
02204 inline
02205 int CTimeSpan::x_Second(void) const { return int(m_Sec % 60L); }
02206 
02207 inline
02208 long CTimeSpan::GetCompleteDays(void) const { return m_Sec / 86400L; }
02209 
02210 inline
02211 long CTimeSpan::GetCompleteHours(void) const { return m_Sec / 3600L; }
02212 
02213 inline
02214 long CTimeSpan::GetCompleteMinutes(void) const { return m_Sec / 60L; }
02215 
02216 inline
02217 long CTimeSpan::GetCompleteSeconds(void) const { return m_Sec; }
02218 
02219 inline
02220 long CTimeSpan::GetNanoSecondsAfterSecond(void) const { return m_NanoSec; }
02221 
02222 inline
02223 double CTimeSpan::GetAsDouble(void) const
02224 {
02225     return m_Sec + double(m_NanoSec) / kNanoSecondsPerSecond;
02226 }
02227 
02228 inline
02229 void CTimeSpan::Set(long seconds, long nanoseconds)
02230 {
02231     m_Sec = seconds + nanoseconds/kNanoSecondsPerSecond;
02232     m_NanoSec = nanoseconds % kNanoSecondsPerSecond;
02233     x_Normalize();
02234 }
02235 
02236 inline
02237 bool CTimeSpan::IsEmpty(void) const
02238 { 
02239     return m_Sec == 0  &&  m_NanoSec == 0;
02240 }
02241 
02242 inline
02243 CTimeSpan& CTimeSpan::operator= (const CTimeSpan& t)
02244 {
02245     m_Sec = t.m_Sec;
02246     m_NanoSec = t.m_NanoSec;
02247     return *this;
02248 }
02249 
02250 inline
02251 CTimeSpan& CTimeSpan::operator= (const string& str)
02252 {
02253     x_Init(str, GetFormat());
02254     return *this;
02255 }
02256 
02257 inline
02258 CTimeSpan::operator string(void) const { return AsString(); }
02259 
02260 inline
02261 CTimeSpan& CTimeSpan::operator+= (const CTimeSpan& t)
02262 {
02263     m_Sec += t.m_Sec;
02264     m_NanoSec += t.m_NanoSec;
02265     x_Normalize();
02266     return *this;
02267 }
02268 
02269 inline
02270 CTimeSpan CTimeSpan::operator+ (const CTimeSpan& t) const
02271 {
02272     CTimeSpan tnew(0, 0, 0, m_Sec + t.m_Sec, m_NanoSec + t.m_NanoSec);
02273     return tnew;
02274 }
02275 
02276 inline
02277 CTimeSpan& CTimeSpan::operator-= (const CTimeSpan& t)
02278 {
02279     m_Sec -= t.m_Sec;
02280     m_NanoSec -= t.m_NanoSec;
02281     x_Normalize();
02282     return *this;
02283 }
02284 
02285 inline
02286 CTimeSpan CTimeSpan::operator- (const CTimeSpan& t) const
02287 {
02288     CTimeSpan tnew(0, 0, 0, m_Sec - t.m_Sec, m_NanoSec - t.m_NanoSec);
02289     return tnew;
02290 }
02291 
02292 inline
02293 const CTimeSpan CTimeSpan::operator- (void) const
02294 {
02295     CTimeSpan t;
02296     t.m_Sec     = -m_Sec;
02297     t.m_NanoSec = -m_NanoSec;
02298     return t;
02299 }
02300 
02301 inline
02302 void CTimeSpan::Invert(void)
02303 {
02304     m_Sec     = -m_Sec;
02305     m_NanoSec = -m_NanoSec;
02306 }
02307 
02308 inline
02309 bool CTimeSpan::operator== (const CTimeSpan& t) const
02310 {
02311     return m_Sec == t.m_Sec  &&  m_NanoSec == t.m_NanoSec;
02312 }
02313 
02314 inline
02315 bool CTimeSpan::operator!= (const CTimeSpan& t) const
02316 {
02317     return !(*this == t);
02318 }
02319 
02320 inline
02321 bool CTimeSpan::operator> (const CTimeSpan& t) const
02322 {
02323     if (m_Sec == t.m_Sec) {
02324         return m_NanoSec > t.m_NanoSec;
02325     }
02326     return m_Sec > t.m_Sec;
02327 }
02328 
02329 
02330 inline
02331 bool CTimeSpan::operator< (const CTimeSpan& t) const
02332 {
02333     if (m_Sec == t.m_Sec) {
02334         return m_NanoSec < t.m_NanoSec;
02335     }
02336     return m_Sec < t.m_Sec;
02337 }
02338 
02339 inline
02340 bool CTimeSpan::operator>= (const CTimeSpan& t) const
02341 {
02342     return !(*this < t);
02343 }
02344 
02345 inline
02346 bool CTimeSpan::operator<= (const CTimeSpan& t) const
02347 {
02348     return !(*this > t);
02349 }
02350 
02351 
02352 //
02353 // CTimeout
02354 //
02355 
02356 inline
02357 CTimeout::CTimeout(void) { Set(eDefault); }
02358 
02359 inline
02360 CTimeout::CTimeout(EType type) { Set(type); }
02361 
02362 inline
02363 CTimeout::CTimeout(const CTimeSpan& ts) { Set(ts); }
02364 
02365 inline
02366 CTimeout::CTimeout(unsigned int sec, unsigned int usec) { Set(sec, usec); }
02367 
02368 inline
02369 CTimeout::CTimeout(double sec) { Set(sec); }
02370 
02371 inline
02372 CTimeout::CTimeout(const CTimeout& t)
02373 {
02374     m_Type     = t.m_Type;
02375     m_HasValue = t.m_HasValue;
02376     m_Sec      = t.m_Sec;
02377     m_MicroSec = t.m_MicroSec;
02378 }
02379 
02380 inline
02381 bool CTimeout::IsDefault() const
02382 { 
02383     return m_Type == eDefault  &&  !m_HasValue;
02384 }
02385 
02386 inline
02387 bool CTimeout::IsInfinite() const
02388 {
02389     return m_Type == eInfinite  &&  !m_HasValue;
02390 }
02391 
02392 inline
02393 bool CTimeout::IsFinite() const
02394 {
02395     return m_HasValue;
02396 }
02397 
02398 inline
02399 bool CTimeout::operator!= (const CTimeout& t) const
02400 {
02401     return !(*this == t);
02402 }
02403 
02404 
02405 
02406 //
02407 //  CStopWatch
02408 //
02409 
02410 inline
02411 CStopWatch::CStopWatch(EStart state)
02412 {
02413     m_Total = 0;
02414     m_Start = 0;
02415     m_State = eStop;
02416     if ( state == eStart ) {
02417         Start();
02418     }
02419 }
02420 
02421 inline
02422 void CStopWatch::Start()
02423 {
02424     m_State = eStart;
02425     m_Start = GetTimeMark();
02426 }
02427 
02428 
02429 inline
02430 double CStopWatch::Elapsed() const
02431 {
02432     double total = m_Total;
02433     if ( m_State == eStop ) {
02434         return total;
02435     }
02436     // Workaround for -0 (negative zero) values,
02437     // that can occur at subtraction of very close doubles.
02438     double mark = GetTimeMark() - m_Start;
02439     if (mark > 0.0) {
02440         total += mark;
02441     }
02442     return total;
02443 }
02444 
02445 
02446 inline
02447 void CStopWatch::Stop()
02448 {
02449     if ( m_State == eStop ) {
02450         return;
02451     }
02452     double mark = GetTimeMark() - m_Start;
02453     if (mark > 0.0) {
02454         m_Total += mark;
02455     }
02456     m_State = eStop;
02457 }
02458 
02459 
02460 inline
02461 double CStopWatch::Restart()
02462 {
02463     double total   = m_Total;
02464     double current = GetTimeMark();
02465     if ( m_State == eStart ) {
02466         // Workaround for -0 (negative zero) values,
02467         // that can occur at subtraction of very close doubles.
02468         double mark = current - m_Start;
02469         if ( mark > 0.0 ) {
02470             total += mark;
02471         }
02472     }
02473     m_Total = 0;
02474     m_Start = current;
02475     m_State = eStart;
02476     return total;
02477 }
02478 
02479 inline
02480 bool CStopWatch::IsRunning(void)
02481 {
02482     return m_State == eStart;
02483 }
02484 
02485 
02486 inline
02487 CStopWatch::operator string(void) const
02488 {
02489     return AsString();
02490 }
02491 
02492 
02493 inline
02494 string CStopWatch::AsSmartString(
02495     CTimeSpan::ESmartStringPrecision precision,
02496     ERound                           rounding,
02497     CTimeSpan::ESmartStringZeroMode  zero_mode)
02498     const
02499 {
02500     return CTimeSpan(Elapsed()).AsSmartString(precision, rounding, zero_mode);
02501 }
02502 
02503 
02504 END_NCBI_SCOPE
02505 
02506 #endif /* CORELIB__NCBITIME__HPP */
02507 
02508 

Generated on Sun Dec 6 22:01:29 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Mon Dec 07 16:20:35 2009 by modify_doxy.py rev. 173732