1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
19 #include "zypp/base/Exception.h"
20 #include "zypp/base/EnumClass.h"
22 ///////////////////////////////////////////////////////////////////
24 { /////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////
30 /** Store and operate on date (time_t).
34 friend std::ostream & operator<<( std::ostream & str, const Date & obj );
38 typedef time_t ValueType;
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;
53 enum TimeBase { TB_LOCALTIME, TB_UTC };
55 /** Default ctor: 0 */
59 /** Ctor taking time_t value. */
60 Date( ValueType date_r )
63 /** Ctor taking time_t value as string. */
64 explicit Date( const std::string & seconds_r );
67 * Ctor from a \a date_str (in localtime) formatted using \a format.
69 * \throws DateFormatException in case \a date_str cannot be
70 * parsed according to \a format.
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 );
76 /** Return the current time. */
78 { return ::time( 0 ); }
81 /** Conversion to time_t. */
82 operator ValueType() const
85 /** \name Arithmetic operations. */
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; }
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; }
97 Date & operator++(/*prefix*/) { _date += 1; return *this; }
98 Date & operator--(/*prefix*/) { _date -= 1; return *this; }
100 Date operator++(int/*postfix*/) { return _date++; }
101 Date operator--(int/*postfix*/) { return _date--; }
105 /** Return string representation according to format as localtime.
106 * \see 'man strftime' (which is used internaly) for valid
107 * conversion specifiers in format.
109 * \return An empty string on illegal format, "0" if date is unspecified.
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;
116 /** Default string representation of Date.
117 * The preferred date and time representation for the current locale.
119 std::string asString() const
120 { return form( "%c" ); }
122 /** Convert to string representation of calendar time in
123 * numeric form (like "1029255142").
125 std::string asSeconds() const
126 { return form( "%s" ); }
129 /** \name Printing in various predefined formats */
131 /** Date formats for printing (use like 'enum class \ref DateFormat') */
132 struct _DateFormatDef { enum Enum {
134 calendar, ///< 2014-02-07
138 weekday, ///< 2014-W06-5 (1 is Monday)
139 ordinal, ///< 2014-038
141 typedef base::EnumClass<_DateFormatDef> DateFormat; ///< 'enum class DateFormat'
143 /** Time formats for printing (use like 'enum class \ref TimeFormat') */
144 struct _TimeFormatDef { enum Enum {
146 seconds, ///< 07:06:41
150 typedef base::EnumClass<_TimeFormatDef> TimeFormat; ///< 'enum class TimeFormat'
152 /** Timezone indicator for printing (use like 'enum class \ref TimeZoneFormat') */
153 struct _TimeZoneFormatDef { enum Enum {
155 name, ///< UTC, CET, ...
156 offset, ///< +00[:00]
158 typedef base::EnumClass<_TimeZoneFormatDef> TimeZoneFormat; ///< 'enum class TimeZoneFormat'
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.
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;
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 ); }
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 ); }
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 ); }
176 std::string print( TimeZoneFormat timeZoneFormat_r, TimeBase base_r = TB_LOCALTIME ) const
177 { return print( DateFormat::calendar, TimeFormat::seconds, timeZoneFormat_r, base_r ); }
179 std::string print( TimeFormat timeFormat_r, TimeBase base_r ) const
180 { return print( DateFormat::calendar, timeFormat_r, TimeZoneFormat::name, base_r ); }
182 std::string print( DateFormat dateFormat_r, TimeBase base_r ) const
183 { return print( dateFormat_r, TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
185 std::string print( TimeBase base_r ) const
186 { return print( DateFormat::calendar, TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
188 /** Convenience for printing the date only [<tt>'2014-02-07'</tt>]
189 * The default is \ref DateFormat::calendar and \ref TB_LOCALTIME
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 ); }
194 std::string printDate( TimeBase base_r ) const
195 { return printDate( DateFormat::calendar, base_r ); }
197 /** Convenience for printing the time only [<tt>'07:06:41 CET'</tt>]
198 * The default is \ref DateFormat::calendar and \ref TB_LOCALTIME
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 ); }
203 std::string printTime( TimeZoneFormat timeZoneFormat_r , TimeBase base_r = TB_LOCALTIME ) const
204 { return printTime( TimeFormat::seconds, timeZoneFormat_r, base_r ); }
206 std::string printTime( TimeFormat timeFormat_r , TimeBase base_r ) const
207 { return printTime( timeFormat_r, TimeZoneFormat::name, base_r ); }
209 std::string printTime( TimeBase base_r ) const
210 { return printTime( TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
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'.
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;
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 ); }
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 ); }
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 ); }
228 std::string printISO( TimeZoneFormat timeZoneFormat_r, TimeBase base_r = TB_LOCALTIME ) const
229 { return printISO( DateFormat::calendar, TimeFormat::seconds, timeZoneFormat_r, base_r ); }
231 std::string printISO( TimeFormat timeFormat_r, TimeBase base_r ) const
232 { return printISO( DateFormat::calendar, timeFormat_r, TimeZoneFormat::name, base_r ); }
234 std::string printISO( DateFormat dateFormat_r, TimeBase base_r ) const
235 { return printISO( dateFormat_r, TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
237 std::string printISO( TimeBase base_r ) const
238 { return printISO( DateFormat::calendar, TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
243 * The number of seconds elapsed since 00:00:00 on January 1, 1970,
244 * Coordinated Universal Time (UTC).
248 ///////////////////////////////////////////////////////////////////
250 /** \relates Date Stream output */
251 inline std::ostream & operator<<( std::ostream & str, const Date & obj )
252 { return str << obj.asString(); }
254 /** \relates Date XML output.
255 * Print \c time_t and \c text attribute. Allow alternate node name [date].
257 std::ostream & dumpAsXmlOn( std::ostream & str, const Date & obj, const std::string & name_r = "date" );
259 ///////////////////////////////////////////////////////////////////
260 class DateFormatException : public Exception
263 DateFormatException( const std::string & msg ) : Exception( msg )
267 /////////////////////////////////////////////////////////////////
269 ///////////////////////////////////////////////////////////////////
270 #endif // ZYPP_DATE_H