1 /*
2  * ptime.h
3  *
4  * Time and date class.
5  *
6  * Portable Windows Library
7  *
8  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25  * All Rights Reserved.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Revision: 26282 $
30  * $Author: rjongbloed $
31  * $Date: 2011-08-08 02:09:32 -0500 (Mon, 08 Aug 2011) $
32  */
33 
34 #ifndef PTLIB_TIME_H
35 #define PTLIB_TIME_H
36 
37 #ifdef P_USE_PRAGMA
38 #pragma interface
39 #endif
40 
41 
42 ///////////////////////////////////////////////////////////////////////////////
43 // System time and date class
44 
45 class PTimeInterval;
46 
47 
48 /**This class defines an absolute time and date. It has a number of time and
49    date rendering and manipulation functions. It is based on the standard C
50    library functions for time. Thus it is based on a number of seconds since
51    1 January 1970.
52  */
53 class PTime : public PObject
54 {
55   PCLASSINFO(PTime, PObject);
56 
57   public:
58   /**@name Construction */
59   //@{
60     /** Time Zone special codes. The value for a time zone is usually in minutes
61         from UTC, this enum are special values for specific areas.
62       */
63     enum {
64       /// Universal Coordinated Time.
65       UTC   = 0,
66       /// Greenwich Mean Time, effectively UTC.
67       GMT   = UTC,
68       /// Local Time.
69       Local = 9999
70     };
71 
72     /**Create a time object instance.
73        This initialises the time with the current time in the current time zone.
74      */
PTime()75     PTime() { SetCurrentTime(); }
76 
77     /**Create a time object instance.
78        This initialises the time to the specified time.
79      */
80     PTime(
81       time_t tsecs,     ///< Time in seconds since 00:00:00 1/1/70 UTC
82       long usecs = 0    ///< microseconds part of time.
83     ) { theTime = tsecs; microseconds = usecs; }
84 
85     /**Create a time object instance.
86        This initialises the time to the specified time, parsed from the
87        string. The string may be in many different formats, for example:
88           "5/03/1999 12:34:56"
89           "15/06/1999 12:34:56"
90           "15/06/01 12:34:56 PST"
91           "5/06/02 12:34:56"
92           "5/23/1999 12:34am"
93           "5/23/00 12:34am"
94           "1999/23/04 12:34:56"
95           "Mar 3, 1999 12:34pm"
96           "3 Jul 2004 12:34pm"
97           "12:34:56 5 December 1999"
98           "10 minutes ago"
99           "2 weeks"
100      */
101     PTime(
102       const PString & str   ///< Time and data as a string
103     );
104 
105     /**Create a time object instance.
106        This initialises the time to the specified time.
107      */
108     PTime(
109       int second,           ///< Second from 0 to 59.
110       int minute,           ///< Minute from 0 to 59.
111       int hour,             ///< Hour from 0 to 23.
112       int day,              ///< Day of month from 1 to 31.
113       int month,            ///< Month from 1 to 12.
114       int year,             ///< Year from 1970 to 2038
115       int tz = Local        ///< local time or UTC
116     );
117   //@}
118 
119   /**@name Overrides from class PObject */
120   //@{
121     /**Create a copy of the time on the heap. It is the responsibility of the
122        caller to delete the created object.
123 
124        @return
125        pointer to new time.
126      */
127     PObject * Clone() const;
128 
129     /**Determine the relative rank of the specified times. This ranks the
130        times as you would expect.
131 
132        @return
133        rank of the two times.
134      */
135     virtual Comparison Compare(
136       const PObject & obj   ///< Other time to compare against.
137     ) const;
138 
139     /**Output the time to the stream. This uses the <code>AsString()</code> function
140        with the <code>ShortDateTime</code> parameter.
141      */
142     virtual void PrintOn(
143       ostream & strm    ///< Stream to output the time to.
144     ) const;
145 
146     /**Input the time from the specified stream. If a parse error occurs the
147        time is set to the current time. The string may be in many different
148        formats, for example:
149           "5/03/1999 12:34:56"
150           "15/06/1999 12:34:56"
151           "15/06/01 12:34:56 PST"
152           "5/06/02 12:34:56"
153           "5/23/1999 12:34am"
154           "5/23/00 12:34am"
155           "1999/23/04 12:34:56"
156           "Mar 3, 1999 12:34pm"
157           "3 Jul 2004 12:34pm"
158           "12:34:56 5 December 1999"
159           "10 minutes ago"
160           "2 weeks"
161      */
162     virtual void ReadFrom(
163       istream & strm    ///< Stream to input the time from.
164     );
165   //@}
166 
167   /**@name Access functions */
168   //@{
169     /**Determine if the timestamp is valid.
170        This will return true if the timestamp can be represented as a time
171        in the epoch. The epoch is the 1st January 1970.
172 
173        In practice this means the time is > 13 hours to allow for time zones.
174       */
175     PBoolean IsValid() const;
176 
177     /**Get the total microseconds since the epoch. The epoch is the 1st
178        January 1970.
179 
180        @return
181        microseconds.
182      */
183     PInt64 GetTimestamp() const;
184 
185     /**Set the the objects time with the current time in the current time zone.
186       */
187     void SetCurrentTime();
188 
189     /**Set the time in seconds and microseconds.
190       */
191     void SetTimestamp(
192       time_t seconds,
193       long usecs = 0
194     );
195 
196     /**Get the total seconds since the epoch. The epoch is the 1st
197        January 1970.
198 
199        @return
200        seconds.
201      */
202     time_t GetTimeInSeconds() const;
203 
204     /**Get the microsecond part of the time.
205 
206        @return
207        integer in range 0..999999.
208      */
209     long GetMicrosecond() const;
210 
211     /**Get the second of the time.
212 
213        @return
214        integer in range 0..59.
215      */
216     int GetSecond() const;
217 
218     /**Get the minute of the time.
219 
220        @return
221        integer in range 0..59.
222      */
223     int GetMinute() const;
224 
225     /**Get the hour of the time.
226 
227        @return
228        integer in range 0..23.
229      */
230     int GetHour() const;
231 
232     /**Get the day of the month of the date.
233 
234        @return
235        integer in range 1..31.
236      */
237     int GetDay() const;
238 
239     /// Month codes.
240     enum Months {
241       January = 1,
242       February,
243       March,
244       April,
245       May,
246       June,
247       July,
248       August,
249       September,
250       October,
251       November,
252       December
253     };
254 
255     /**Get the month of the date.
256 
257        @return
258        enum for month.
259      */
260     Months GetMonth() const;
261 
262     /**Get the year of the date.
263 
264        @return
265        integer in range 1970..2038.
266      */
267     int GetYear() const;
268 
269     /// Days of the week.
270     enum Weekdays {
271       Sunday,
272       Monday,
273       Tuesday,
274       Wednesday,
275       Thursday,
276       Friday,
277       Saturday
278     };
279 
280     /**Get the day of the week of the date.
281 
282        @return
283        enum for week days with 0=Sun, 1=Mon, ..., 6=Sat.
284      */
285     Weekdays GetDayOfWeek() const;
286 
287     /**Get the day in the year of the date.
288 
289        @return
290        integer from 1..366.
291      */
292     int GetDayOfYear() const;
293 
294     /**Determine if the time is in the past or in the future.
295 
296        @return
297        true if time is before the current real time.
298      */
299     PBoolean IsPast() const;
300 
301     /**Determine if the time is in the past or in the future.
302 
303        @return
304        true if time is after the current real time.
305      */
306     PBoolean IsFuture() const;
307   //@}
308 
309   /**@name Time Zone configuration functions */
310   //@{
311     /**Get flag indicating daylight savings is current.
312 
313        @return
314        true if daylight savings time is active.
315      */
316     static PBoolean IsDaylightSavings();
317 
318     /// Flag for time zone adjustment on daylight savings.
319     enum TimeZoneType {
320       StandardTime,
321       DaylightSavings
322     };
323 
324     /// Get the time zone offset in minutes.
325     static int GetTimeZone();
326     /**Get the time zone offset in minutes.
327        This is the number of minutes to add to UTC (previously known as GMT) to
328        get the local time. The first form automatically adjusts for daylight
329        savings time, whilst the second form returns the specified time.
330 
331        @return
332        Number of minutes.
333      */
334     static int GetTimeZone(
335        TimeZoneType type  ///< Daylight saving or standard time.
336     );
337 
338     /**Get the text identifier for the local time zone .
339 
340        @return
341        Time zone identifier string.
342      */
343     static PString GetTimeZoneString(
344        TimeZoneType type = StandardTime ///< Daylight saving or standard time.
345     );
346   //@}
347 
348   /**@name Operations */
349   //@{
350     /**Add the interval to the time to yield a new time.
351 
352        @return
353        Time altered by the interval.
354      */
355     PTime operator+(
356       const PTimeInterval & time   ///< Time interval to add to the time.
357     ) const;
358 
359     /**Add the interval to the time changing the instance.
360 
361        @return
362        reference to the current time instance.
363      */
364     PTime & operator+=(
365       const PTimeInterval & time   ///< Time interval to add to the time.
366     );
367 
368     /**Calculate the difference between two times to get a time interval.
369 
370        @return
371        Time intervale difference between the times.
372      */
373     PTimeInterval operator-(
374       const PTime & time   ///< Time to subtract from the time.
375     ) const;
376 
377     /**Subtract the interval from the time to yield a new time.
378 
379        @return
380        Time altered by the interval.
381      */
382     PTime operator-(
383       const PTimeInterval & time   ///< Time interval to subtract from the time.
384     ) const;
385 
386     /**Subtract the interval from the time changing the instance.
387 
388        @return
389        reference to the current time instance.
390      */
391     PTime & operator-=(
392       const PTimeInterval & time   ///< Time interval to subtract from the time.
393     );
394   //@}
395 
396   /**@name String conversion functions */
397   //@{
398     /// Standard time formats for string representations of a time and date.
399     enum TimeFormat {
400       /// Internet standard format. (eg. Wed, 09 Feb 2011 11:25:58 +01:00)
401       RFC1123,
402       /// Another Internet standard format. (eg. 2011-02-09T11:14:41ZZ)
403       RFC3339,
404       /// Short form ISO standard format. (eg. 20110209T111108Z)
405       ShortISO8601,
406       /// Long form ISO standard format. (eg. 2011-02-09 T 11:13:06 Z)
407       LongISO8601,
408       /// Date with weekday, full month names and time with seconds.
409       LongDateTime,
410       /// Date with weekday, full month names and no time.
411       LongDate,
412       /// Time with seconds.
413       LongTime,
414       /// Date with abbreviated month names and time without seconds.
415       MediumDateTime,
416       /// Date with abbreviated month names and no time.
417       MediumDate,
418       /// Date with numeric month name and time without seconds.
419       ShortDateTime,
420       /// Date with numeric month and no time.
421       ShortDate,
422       /// Time without seconds.
423       ShortTime,
424       /// Epoch format (e.g. 1234476388.123456)
425       EpochTime,
426       NumTimeStrings
427     };
428 
429     /** Convert the time to a string representation. */
430     PString AsString(
431       TimeFormat formatCode = RFC1123,  ///< Standard format for time.
432       int zone = Local                  ///< Time zone for the time.
433     ) const;
434 
435     /** Convert the time to a string representation. */
436     PString AsString(
437       const PString & formatStr, ///< Arbitrary format string for time.
438       int zone = Local           ///< Time zone for the time.
439     ) const;
440     /* Convert the time to a string using the format code or string as a
441        formatting template. The special characters in the formatting string
442        are:
443        <table border=0>
444        <tr><td>h         <td>hour without leading zero
445        <tr><td>hh        <td>hour with leading zero
446        <tr><td>m         <td>minute without leading zero
447        <tr><td>mm        <td>minute with leading zero
448        <tr><td>s         <td>second without leading zero
449        <tr><td>ss        <td>second with leading zero
450        <tr><td>u         <td>tenths of second
451        <tr><td>uu        <td>hundedths of second with leading zero
452        <tr><td>uuu       <td>millisecond with leading zeros
453        <tr><td>uuuu      <td>microsecond with leading zeros
454        <tr><td>a         <td>the am/pm string
455        <tr><td>w/ww/www  <td>abbreviated day of week name
456        <tr><td>wwww      <td>full day of week name
457        <tr><td>d         <td>day of month without leading zero
458        <tr><td>dd        <td>day of month with leading zero
459        <tr><td>M         <td>month of year without leading zero
460        <tr><td>MM        <td>month of year with leading zero
461        <tr><td>MMM       <td>month of year as abbreviated text
462        <tr><td>MMMM      <td>month of year as full text
463        <tr><td>y/yy      <td>year without century
464        <tr><td>yyy/yyyy  <td>year with century
465        <tr><td>z         <td>the time zone description ('GMT' for UTC)
466        <tr><td>Z         <td>the time zone description ('Z' for UTC)
467        <tr><td>ZZ        <td>the time zone description (':' separates hour/minute)
468        </table>
469 
470        All other characters are copied to the output string unchanged.
471 
472        Note if there is an 'a' character in the string, the hour will be in 12
473        hour format, otherwise in 24 hour format.
474 
475        @return empty string if time is invalid.
476      */
477     PString AsString(
478       const char * formatPtr,    ///< Arbitrary format C string pointer for time.
479       int zone = Local           ///< Time zone for the time.
480     ) const;
481 
482     /**Parse a string representation of time.
483        This initialises the time to the specified time, parsed from the
484        string. The string may be in many different formats, for example:
485           "5/03/1999 12:34:56"
486           "15/06/1999 12:34:56"
487           "15/06/01 12:34:56 PST"
488           "5/06/02 12:34:56"
489           "5/23/1999 12:34am"
490           "5/23/00 12:34am"
491           "1999/23/04 12:34:56"
492           "Mar 3, 1999 12:34pm"
493           "3 Jul 2004 12:34pm"
494           "12:34:56 5 December 1999"
495           "10 minutes ago"
496           "2 weeks"
497      */
498     bool Parse(
499       const PString & str
500     );
501   //@}
502 
503   /**@name Internationalisation functions */
504   //@{
505     /**Get the internationalised time separator.
506 
507        @return
508        string for time separator.
509      */
510     static PString GetTimeSeparator();
511 
512     /**Get the internationalised time format: AM/PM or 24 hour.
513 
514        @return
515        true is 12 hour, false if 24 hour.
516      */
517     static PBoolean GetTimeAMPM();
518 
519     /**Get the internationalised time AM string.
520 
521        @return
522        string for AM.
523      */
524     static PString GetTimeAM();
525 
526     /**Get the internationalised time PM string.
527 
528        @return
529        string for PM.
530      */
531     static PString GetTimePM();
532 
533     /// Flag for returning language dependent string names.
534     enum NameType {
535       FullName,
536       Abbreviated
537     };
538 
539     /**Get the internationalised day of week day name (0=Sun etc).
540 
541        @return
542        string for week day.
543      */
544     static PString GetDayName(
545       Weekdays dayOfWeek,       ///< Code for day of week.
546       NameType type = FullName  ///< Flag for abbreviated or full name.
547     );
548 
549     /**Get the internationalised date separator.
550 
551        @return
552        string for date separator.
553      */
554     static PString GetDateSeparator();
555 
556     /**Get the internationalised month name string (1=Jan etc).
557 
558        @return
559        string for month.
560      */
561     static PString GetMonthName(
562       Months month,             ///< Code for month in year.
563       NameType type = FullName  ///< Flag for abbreviated or full name.
564     );
565 
566     /// Possible orders for date components.
567     enum DateOrder {
568       MonthDayYear,   ///< Date is ordered month then day then year.
569       DayMonthYear,   ///< Date is ordered day then month then year.
570       YearMonthDay    ///< Date is ordered year then day month then day.
571     };
572 
573     /**Return the internationalised date order.
574 
575        @return
576        code for date ordering.
577      */
578     static DateOrder GetDateOrder();
579   //@}
580 
581     static struct tm * os_localtime(const time_t * clock, struct tm * t);
582     static struct tm * os_gmtime(const time_t * clock, struct tm * t);
583     /*
584       Threadsafe version of localtime library call.
585       We could make these calls non-static if we could put the struct tm inside the
586       instance. But these calls are usually made with const objects so that's not possible,
587       and we would require per-thread storage otherwise. Sigh...
588     */
589 
590   protected:
591     // Member variables
592     /// Number of seconds since 1 January 1970.
593     time_t theTime;
594     long   microseconds;
595 
596 
597 // Include platform dependent part of class
598 #ifdef _WIN32
599 #include "msos/ptlib/ptime.h"
600 #else
601 #include "unix/ptlib/ptime.h"
602 #endif
603 };
604 
605 
606 #endif // PTLIB_TIME_H
607 
608 
609 // End Of File ///////////////////////////////////////////////////////////////
610