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;
39 typedef time_t Duration;
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;
54 enum TimeBase { TB_LOCALTIME, TB_UTC };
56 /** Default ctor: 0 */
60 /** Ctor taking time_t value. */
61 Date( ValueType date_r )
64 /** Ctor taking time_t value as string. */
65 explicit Date( const std::string & seconds_r );
68 * Ctor from a \a date_str (in localtime) formatted using \a format.
70 * \throws DateFormatException in case \a date_str cannot be
71 * parsed according to \a format.
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 );
77 /** Return the current time. */
79 { return ::time( 0 ); }
82 /** Conversion to time_t. */
83 operator ValueType() const
86 /** \name Arithmetic operations. */
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; }
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; }
98 Date & operator++(/*prefix*/) { _date += 1; return *this; }
99 Date & operator--(/*prefix*/) { _date -= 1; return *this; }
101 Date operator++(int/*postfix*/) { return _date++; }
102 Date operator--(int/*postfix*/) { return _date--; }
106 /** Return string representation according to format as localtime.
107 * \see 'man strftime' (which is used internaly) for valid
108 * conversion specifiers in format.
110 * \return An empty string on illegal format, "0" if date is unspecified.
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;
117 /** Default string representation of Date.
118 * The preferred date and time representation for the current locale.
120 std::string asString() const
121 { return form( "%c" ); }
123 /** Convert to string representation of calendar time in
124 * numeric form (like "1029255142").
126 std::string asSeconds() const
127 { return form( "%s" ); }
130 /** \name Printing in various predefined formats */
132 /** Date formats for printing (use like 'enum class \ref DateFormat') */
133 struct EDateFormatDef { enum Enum {
135 calendar, ///< 2014-02-07
139 weekday, ///< 2014-W06-5 (1 is Monday)
140 ordinal, ///< 2014-038
142 typedef base::EnumClass<EDateFormatDef> DateFormat; ///< 'enum class DateFormat'
144 /** Time formats for printing (use like 'enum class \ref TimeFormat') */
145 struct ETimeFormatDef { enum Enum {
147 seconds, ///< 07:06:41
151 typedef base::EnumClass<ETimeFormatDef> TimeFormat; ///< 'enum class TimeFormat'
153 /** Timezone indicator for printing (use like 'enum class \ref TimeZoneFormat') */
154 struct ETimeZoneFormatDef { enum Enum {
156 name, ///< UTC, CET, ...
157 offset, ///< +00[:00]
159 typedef base::EnumClass<ETimeZoneFormatDef> TimeZoneFormat; ///< 'enum class TimeZoneFormat'
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.
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;
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 ); }
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 ); }
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 ); }
177 std::string print( TimeZoneFormat timeZoneFormat_r, TimeBase base_r = TB_LOCALTIME ) const
178 { return print( DateFormat::calendar, TimeFormat::seconds, timeZoneFormat_r, base_r ); }
180 std::string print( TimeFormat timeFormat_r, TimeBase base_r ) const
181 { return print( DateFormat::calendar, timeFormat_r, TimeZoneFormat::name, base_r ); }
183 std::string print( DateFormat dateFormat_r, TimeBase base_r ) const
184 { return print( dateFormat_r, TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
186 std::string print( TimeBase base_r ) const
187 { return print( DateFormat::calendar, TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
189 /** Convenience for printing the date only [<tt>'2014-02-07'</tt>]
190 * The default is \ref DateFormat::calendar and \ref TB_LOCALTIME
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 ); }
195 std::string printDate( TimeBase base_r ) const
196 { return printDate( DateFormat::calendar, base_r ); }
198 /** Convenience for printing the time only [<tt>'07:06:41 CET'</tt>]
199 * The default is \ref DateFormat::calendar and \ref TB_LOCALTIME
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 ); }
204 std::string printTime( TimeZoneFormat timeZoneFormat_r , TimeBase base_r = TB_LOCALTIME ) const
205 { return printTime( TimeFormat::seconds, timeZoneFormat_r, base_r ); }
207 std::string printTime( TimeFormat timeFormat_r , TimeBase base_r ) const
208 { return printTime( timeFormat_r, TimeZoneFormat::name, base_r ); }
210 std::string printTime( TimeBase base_r ) const
211 { return printTime( TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
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'.
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;
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 ); }
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 ); }
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 ); }
229 std::string printISO( TimeZoneFormat timeZoneFormat_r, TimeBase base_r = TB_LOCALTIME ) const
230 { return printISO( DateFormat::calendar, TimeFormat::seconds, timeZoneFormat_r, base_r ); }
232 std::string printISO( TimeFormat timeFormat_r, TimeBase base_r ) const
233 { return printISO( DateFormat::calendar, timeFormat_r, TimeZoneFormat::name, base_r ); }
235 std::string printISO( DateFormat dateFormat_r, TimeBase base_r ) const
236 { return printISO( dateFormat_r, TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
238 std::string printISO( TimeBase base_r ) const
239 { return printISO( DateFormat::calendar, TimeFormat::seconds, TimeZoneFormat::name, base_r ); }
244 * The number of seconds elapsed since 00:00:00 on January 1, 1970,
245 * Coordinated Universal Time (UTC).
249 ///////////////////////////////////////////////////////////////////
251 /** \relates Date Stream output */
252 inline std::ostream & operator<<( std::ostream & str, const Date & obj )
253 { return str << obj.asString(); }
255 /** \relates Date XML output.
256 * Print \c time_t and \c text attribute. Allow alternate node name [date].
258 std::ostream & dumpAsXmlOn( std::ostream & str, const Date & obj, const std::string & name_r = "date" );
260 ///////////////////////////////////////////////////////////////////
261 class DateFormatException : public Exception
264 DateFormatException( const std::string & msg ) : Exception( msg )
268 /////////////////////////////////////////////////////////////////
270 ///////////////////////////////////////////////////////////////////
271 #endif // ZYPP_DATE_H