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