e002c2c09ec584e03459ad1cf5319906f4d2591c
[platform/upstream/libzypp.git] / zypp / Date.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/Date.h
10  *
11 */
12 #ifndef ZYPP_DATE_H
13 #define ZYPP_DATE_H
14
15 #include <ctime>
16 #include <iosfwd>
17 #include <string>
18
19 #include "zypp/base/Exception.h"
20 #include "zypp/base/EnumClass.h"
21
22 ///////////////////////////////////////////////////////////////////
23 namespace zypp
24 { /////////////////////////////////////////////////////////////////
25
26   ///////////////////////////////////////////////////////////////////
27   //
28   //    CLASS NAME : Date
29   //
30   /** Store and operate on date (time_t).
31   */
32   class Date
33   {
34     friend std::ostream & operator<<( std::ostream & str, const Date & obj );
35
36   public:
37
38     typedef time_t ValueType;
39
40     static const ValueType second       = 1;
41     static const ValueType minute       = 60;
42     static const ValueType hour         = 3600;
43     static const ValueType day          = 86400;
44     static const ValueType month28      = 2419200;
45     static const ValueType month29      = 2505600;
46     static const ValueType month30      = 2592000;
47     static const ValueType month31      = 2678400;
48     static const ValueType month        = month30;
49     static const ValueType year365      = 31536000;
50     static const ValueType year366      = 31622400;
51     static const ValueType year         = year365;
52
53     enum TimeBase { TB_LOCALTIME, TB_UTC };
54
55     /** Default ctor: 0 */
56     Date()
57     : _date( 0 )
58     {}
59     /** Ctor taking time_t value. */
60     Date( ValueType date_r )
61     : _date( date_r )
62     {}
63     /** Ctor taking time_t value as string. */
64     explicit Date( const std::string & seconds_r );
65
66     /**
67      * Ctor from a \a date_str (in localtime) formatted using \a format.
68      *
69      * \throws DateFormatException in case \a date_str cannot be
70      *         parsed according to \a format.
71      */
72     Date( const std::string & date_str, const std::string & format );
73     /** \overload with explicitly given \ref TimeBase. */
74     Date( const std::string & date_str, const std::string & format, TimeBase base_r );
75
76     /** Return the current time. */
77     static Date now()
78     { return ::time( 0 ); }
79
80   public:
81     /** Conversion to time_t. */
82     operator ValueType() const
83     { return _date; }
84
85     /** \name Arithmetic operations. */
86     //@{
87     Date operator+( const time_t rhs ) const { return _date + rhs; }
88     Date operator-( const time_t rhs ) const { return _date - rhs; }
89     Date operator*( const time_t rhs ) const { return _date * rhs; }
90     Date operator/( const time_t rhs ) const { return _date / rhs; }
91
92     Date & operator+=( const time_t rhs ) { _date += rhs; return *this; }
93     Date & operator-=( const time_t rhs ) { _date -= rhs; return *this; }
94     Date & operator*=( const time_t rhs ) { _date *= rhs; return *this; }
95     Date & operator/=( const time_t rhs ) { _date /= rhs; return *this; }
96
97     Date & operator++(/*prefix*/) { _date += 1; return *this; }
98     Date & operator--(/*prefix*/) { _date -= 1; return *this; }
99
100     Date operator++(int/*postfix*/) { return _date++; }
101     Date operator--(int/*postfix*/) { return _date--; }
102     //@}
103
104   public:
105     /** Return string representation according to format as localtime.
106      * \see 'man strftime' (which is used internaly) for valid
107      * conversion specifiers in format.
108      *
109      * \return An empty string on illegal format, "0" if date is unspecified.
110      **/
111     std::string form( const std::string & format_r ) const
112     { return form( format_r, TB_LOCALTIME ); }
113     /** \overload with explicitly given \ref TimeBase. */
114     std::string form( const std::string & format_r, TimeBase base_r ) const;
115
116     /** Default string representation of Date.
117      * The preferred date and time representation for the current locale.
118      **/
119     std::string asString() const
120     { return form( "%c" ); }
121
122     /** Convert to string representation of calendar time in
123      *  numeric form (like "1029255142").
124      **/
125     std::string asSeconds() const
126     { return form( "%s" ); }
127
128   public:
129     /** \name Printing in various predefined formats */
130     //@{
131     /** Date formats for printing (use like 'enum class \ref DateFormat') */
132     struct _DateFormatDef { enum Enum {
133       none,     ///< ""
134       calendar, ///< 2014-02-07
135       month,    ///< 2014-02
136       year,     ///< 2014
137       week,     ///< 2014-W06
138       weekday,  ///< 2014-W06-5 (1 is Monday)
139       ordinal,  ///< 2014-038
140     };};
141     typedef base::EnumClass<_DateFormatDef> DateFormat; ///< 'enum class DateFormat'
142
143     /** Time formats for printing (use like 'enum class \ref TimeFormat') */
144     struct _TimeFormatDef { enum Enum {
145       none,     ///< ""
146       seconds,  ///< 07:06:41
147       minutes,  ///< 07:06
148       hours,    ///< 07
149     };};
150     typedef base::EnumClass<_TimeFormatDef> TimeFormat; ///< 'enum class TimeFormat'
151
152     /** Timezone indicator for printing (use like 'enum class \ref TimeZoneFormat') */
153     struct _TimeZoneFormatDef { enum Enum {
154       none,     ///< ""
155       name,     ///< UTC, CET, ...
156       offset,   ///< +00[:00]
157     };};
158     typedef base::EnumClass<_TimeZoneFormatDef> TimeZoneFormat; ///< 'enum class TimeZoneFormat'
159
160     /** Default format is <tt>'2014-02-07 07:06:41 CET'</tt>
161      * The default is \ref DateFormat::calendar, \ref TimeFormat::seconds, \ref TimeZoneFormat::name and
162      * \ref TB_LOCALTIME. For other formats you don't have to repeat all the defaults, just pass the
163      * values where you differ.
164      */
165     std::string print( DateFormat dateFormat_r = DateFormat::calendar, TimeFormat timeFormat_r = TimeFormat::seconds, TimeZoneFormat timeZoneFormat_r = TimeZoneFormat::name, TimeBase base_r = TB_LOCALTIME ) const;
166     /** \overload */
167     std::string print( TimeFormat timeFormat_r, TimeZoneFormat timeZoneFormat_r = TimeZoneFormat::name, TimeBase base_r = TB_LOCALTIME ) const
168     { return print( DateFormat::calendar, timeFormat_r, timeZoneFormat_r, base_r ); }
169     /** \overload */
170     std::string print( DateFormat dateFormat_r, TimeZoneFormat timeZoneFormat_r, TimeBase base_r = TB_LOCALTIME ) const
171     { return print( dateFormat_r, TimeFormat::seconds, timeZoneFormat_r, base_r ); }
172     /** \overload */
173     std::string print( DateFormat dateFormat_r, TimeFormat timeFormat_r, TimeBase base_r ) const
174     { return print( dateFormat_r, timeFormat_r, TimeZoneFormat::name, base_r ); }
175     /** \overload */
176     std::string print( TimeZoneFormat timeZoneFormat_r, TimeBase base_r = TB_LOCALTIME ) const
177     { return print( DateFormat::calendar, TimeFormat::seconds, timeZoneFormat_r, base_r ); }
178     /** \overload */
179     std::string print( TimeFormat timeFormat_r, TimeBase base_r ) const
180     { return print( DateFormat::calendar, timeFormat_r, TimeZoneFormat::name, base_r ); }
181     /** \overload */
182     std::string print( DateFormat dateFormat_r, TimeBase base_r ) const
183     { return print( dateFormat_r, TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
184     /** \overload */
185     std::string print( TimeBase base_r ) const
186     { return print( DateFormat::calendar, TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
187
188     /** Convenience for printing the date only [<tt>'2014-02-07'</tt>]
189      * The default is \ref DateFormat::calendar and \ref TB_LOCALTIME
190      */
191     std::string printDate( DateFormat dateFormat_r = DateFormat::calendar, TimeBase base_r = TB_LOCALTIME ) const
192     { return print( dateFormat_r, TimeFormat::none, TimeZoneFormat::none, base_r ); }
193     /** \overload */
194     std::string printDate( TimeBase base_r ) const
195     { return printDate( DateFormat::calendar, base_r ); }
196
197     /** Convenience for printing the time only [<tt>'07:06:41 CET'</tt>]
198      * The default is \ref DateFormat::calendar and \ref TB_LOCALTIME
199      */
200     std::string printTime( TimeFormat timeFormat_r = TimeFormat::seconds, TimeZoneFormat timeZoneFormat_r = TimeZoneFormat::name, TimeBase base_r = TB_LOCALTIME ) const
201     { return print( DateFormat::none, timeFormat_r, timeZoneFormat_r, base_r ); }
202     /** \overload */
203     std::string printTime( TimeZoneFormat timeZoneFormat_r , TimeBase base_r = TB_LOCALTIME ) const
204     { return printTime( TimeFormat::seconds, timeZoneFormat_r, base_r ); }
205     /** \overload */
206     std::string printTime( TimeFormat timeFormat_r , TimeBase base_r ) const
207     { return printTime( timeFormat_r, TimeZoneFormat::name, base_r ); }
208     /** \overload */
209     std::string printTime( TimeBase base_r ) const
210     { return printTime( TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
211
212     /** Default ISO 8601 format is <tt>'2014-02-07T07:06:41+01'</tt>
213      * \note As timezone names are not used in ISO, \ref TimeZoneFormat::name is the same as
214      * \ref TimeZoneFormat::offset when printing in \ref TB_LOCALTIME. When printing \ref TB_UTC
215      * it uses a \c 'Z' to indicate UTC (Zulu time) rather than printing \c '+00'.
216      */
217     std::string printISO( DateFormat dateFormat_r = DateFormat::calendar, TimeFormat timeFormat_r = TimeFormat::seconds, TimeZoneFormat timeZoneFormat_r = TimeZoneFormat::name, TimeBase base_r = TB_LOCALTIME ) const;
218     /** \overload */
219     std::string printISO( TimeFormat timeFormat_r, TimeZoneFormat timeZoneFormat_r = TimeZoneFormat::name, TimeBase base_r = TB_LOCALTIME ) const
220     { return printISO( DateFormat::calendar, timeFormat_r, timeZoneFormat_r, base_r ); }
221     /** \overload */
222     std::string printISO( DateFormat dateFormat_r, TimeZoneFormat timeZoneFormat_r, TimeBase base_r = TB_LOCALTIME ) const
223     { return printISO( dateFormat_r, TimeFormat::seconds, timeZoneFormat_r, base_r ); }
224     /** \overload */
225     std::string printISO( DateFormat dateFormat_r, TimeFormat timeFormat_r, TimeBase base_r ) const
226     { return printISO( dateFormat_r, timeFormat_r, TimeZoneFormat::name, base_r ); }
227     /** \overload */
228     std::string printISO( TimeZoneFormat timeZoneFormat_r, TimeBase base_r = TB_LOCALTIME ) const
229     { return printISO( DateFormat::calendar, TimeFormat::seconds, timeZoneFormat_r, base_r ); }
230     /** \overload */
231     std::string printISO( TimeFormat timeFormat_r, TimeBase base_r ) const
232     { return printISO( DateFormat::calendar, timeFormat_r, TimeZoneFormat::name, base_r ); }
233     /** \overload */
234     std::string printISO( DateFormat dateFormat_r, TimeBase base_r ) const
235     { return printISO( dateFormat_r, TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
236     /** \overload */
237     std::string printISO( TimeBase base_r ) const
238     { return printISO( DateFormat::calendar, TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
239     //@}
240
241  private:
242     /** Calendar time.
243      * The number of seconds elapsed since 00:00:00 on January 1, 1970,
244      * Coordinated Universal Time (UTC).
245      **/
246     ValueType _date;
247   };
248   ///////////////////////////////////////////////////////////////////
249
250   /** \relates Date Stream output */
251   inline std::ostream & operator<<( std::ostream & str, const Date & obj )
252   { return str << obj.asString(); }
253
254   /** \relates Date XML output.
255    * Print \c time_t and \c text attribute. Allow alternate node name [date].
256    */
257   std::ostream & dumpAsXmlOn( std::ostream & str, const Date & obj, const std::string & name_r = "date" );
258
259   ///////////////////////////////////////////////////////////////////
260   class DateFormatException : public Exception
261   {
262   public:
263     DateFormatException( const std::string & msg ) : Exception( msg )
264     {}
265   };
266
267   /////////////////////////////////////////////////////////////////
268 } // namespace zypp
269 ///////////////////////////////////////////////////////////////////
270 #endif // ZYPP_DATE_H