libzypp: zypp/Date.cc Source File

libzypp 17.25.10

Date.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 //#include <zypp/base/Logger.h>
14
15 #include <zypp/base/String.h>
16 #include <zypp/base/Xml.h>
17
18 #include <zypp/Date.h>
19
20 using std::endl;
21
23 namespace zypp
24 {
26 namespace
27 {
32 struct LocaleGuard
33 {
34 LocaleGuard()
35 {
36 const char * tmp = ::setlocale( LC_TIME, NULL );
37 _mylocale = tmp ? tmp : "";
38
39 if ( _mylocale.find( "UTF-8" ) == std::string::npos
40 && _mylocale.find( "utf-8" ) == std::string::npos
41 && _mylocale != "POSIX"
42 && _mylocale != "C"
43 && _mylocale != "" )
44 {
45 // language[_territory][.codeset][@modifier]
46 // add/exchange codeset with UTF-8
47 std::string needLocale = ".UTF-8";
48 std::string::size_type loc = _mylocale.find_first_of( ".@" );
49 if ( loc != std::string::npos )
50 {
51 // prepend language[_territory]
52 needLocale = _mylocale.substr( 0, loc ) + needLocale;
53 loc = _mylocale.find_last_of( "@" );
54 if ( loc != std::string::npos )
55 {
56 // append [@modifier]
57 needLocale += _mylocale.substr( loc );
58 }
59 }
60 else
61 {
62 // append ".UTF-8"
63 needLocale = _mylocale + needLocale;
64 }
65 ::setlocale( LC_TIME, needLocale.c_str() );
66 }
67 else
68 {
69 // no need to change the locale
70 _mylocale.clear();
71 }
72 }
73
74 ~LocaleGuard()
75 {
76 if ( ! _mylocale.empty() )
77 ::setlocale( LC_TIME, _mylocale.c_str() );
78 }
79 private:
80 std::string _mylocale;
81 };
83
84 inline bool isDST( struct tm & tm )
85 {
86 time_t t = ::mktime( &tm );
87 struct tm *tm2 = ::localtime( &t );
88 return ( tm2 && tm2->tm_isdst > 0 );
89 }
90
91 inline const char * _dateFormat( Date::DateFormat dateFormat_r )
92 {
93 static const char * fmt[] = {
94 "",
95 "%Y-%m-%d",
96 "%Y-%m",
97 "%Y",
98 "%G-W%V",
99 "%G-W%V-%u",
100 "%Y-%j",
101 };
102 return fmt[dateFormat_r.asIntegral()];
103 }
104
105 inline const char * _timeFormat( Date::TimeFormat timeFormat_r )
106 {
107 static const char * fmt[] = {
108 "",
109 "%H:%M:%S",
110 "%H:%M",
111 "%H",
112 };
113 return fmt[timeFormat_r.asIntegral()];
114 }
115
116 inline const char * _timeZoneFormat( Date::TimeZoneFormat timeZoneFormat_r )
117 {
118 static const char * fmt[] = {
119 "",
120 " %Z",
121 "%z",
122 };
123 return fmt[timeZoneFormat_r.asIntegral()];
124 }
125
126 inline std::string doForm( const std::string & format_r, Date::TimeBase base_r, const Date::ValueType & date_r )
127 {
128 if ( ! date_r )
129 return "0";
130
131 LocaleGuard guard;
132 static char buf[512];
133 if ( ! strftime( buf, 512, format_r.c_str(), (base_r == Date::TB_UTC ? gmtime : localtime)( &date_r ) ) )
134 *buf = '\0';
135 else
136 {
137 // strip a trailing '00' in a timeZoneFormat
138 unsigned l = ::strlen( buf );
139 if ( l >= 5
140 && ( buf[l-1] == '0' )
141 && ( buf[l-2] == '0' )
142 && ( buf[l-5] == '+' || buf[l-5] == '-') )
143 buf[l-2] = '\0';
144 }
145 return buf;
146 }
147 } // namespace
149
150 const Date::ValueType Date::second;
151 const Date::ValueType Date::minute;
152 const Date::ValueType Date::hour;
153 const Date::ValueType Date::day;
154 const Date::ValueType Date::month28;
155 const Date::ValueType Date::month29;
156 const Date::ValueType Date::month30;
157 const Date::ValueType Date::month31;
158 const Date::ValueType Date::month;
159 const Date::ValueType Date::year365;
160 const Date::ValueType Date::year366;
161 const Date::ValueType Date::year;
162
163 Date::Date( const std::string & seconds_r )
164 { str::strtonum( seconds_r, _date ); }
165
166 Date::Date( const std::string & date_str, const std::string & format )
167 : _date( Date( date_str, format, TB_LOCALTIME ) )
168 {}
169
170 Date::Date( const std::string & date_str, const std::string & format, Date::TimeBase base_r )
171 : _date(0)
172 {
173 LocaleGuard guard;
174
175 struct tm tm = {0,0,0,0,0,0,0,0,0,0,0};
176 char * res = ::strptime( date_str.c_str(), format.c_str(), &tm );
177 if (res == NULL)
178 throw DateFormatException( str::form( "Invalid date format: '%s'", date_str.c_str() ) );
179
180 if ( isDST(tm) )
181 tm.tm_isdst = 1;
182 _date = (base_r == TB_UTC ? ::timegm : ::timelocal)( &tm );
183 }
184
185 std::string Date::form( const std::string & format_r, Date::TimeBase base_r ) const
186 { return doForm( format_r, base_r, _date ); }
187
188 std::string Date::print( DateFormat dateFormat_r, TimeFormat timeFormat_r, TimeZoneFormat timeZoneFormat_r, TimeBase base_r ) const
189 {
190 str::Str str;
191 if ( dateFormat_r != DateFormat::none )
192 str << _dateFormat( dateFormat_r );
193 if ( timeFormat_r != TimeFormat::none )
194 {
195 if ( dateFormat_r != DateFormat::none )
196 str << ' ';
197 str << _timeFormat( timeFormat_r );
198 if ( timeZoneFormat_r != TimeZoneFormat::none )
199 str << _timeZoneFormat( timeZoneFormat_r );
200 }
201 return doForm( str, base_r, _date );
202 }
203
204 std::string Date::printISO( DateFormat dateFormat_r, TimeFormat timeFormat_r, TimeZoneFormat timeZoneFormat_r, TimeBase base_r ) const
205 {
206 str::Str str;
207 if ( dateFormat_r != DateFormat::none )
208 str << _dateFormat( dateFormat_r );
209 if ( timeFormat_r != TimeFormat::none )
210 {
211 if ( dateFormat_r != DateFormat::none )
212 str << 'T';
213 str << _timeFormat( timeFormat_r );
214 switch ( timeZoneFormat_r.asEnum() )
215 {
216 case TimeZoneFormat::none:
217 break;
218 case TimeZoneFormat::name:
219 if ( base_r == TB_UTC )
220 {
221 str << 'Z';
222 break;
223 }
224 // else: FALLTHROUGH and print offset!
225 case TimeZoneFormat::offset:
226 str << _timeZoneFormat( TimeZoneFormat::offset );
227 break;
228 }
229 }
230 return doForm( str, base_r, _date );
231 }
232
233 std::ostream & dumpAsXmlOn( std::ostream & str, const Date & obj, const std::string & name_r )
234 {
235 return xmlout::node( str, name_r, {
236 { "time_t", Date::ValueType(obj) },
237 { "text", obj.printISO( Date::TB_UTC ) },
238 } );
239 }
240
241 } // namespace zypp
_mylocale
std::string _mylocale
Definition: Date.cc:80
Date.h
String.h
Xml.h
zypp::DateFormatException
Definition: Date.h:262
zypp::Date
Store and operate on date (time_t).
Definition: Date.h:33
zypp::Date::_date
ValueType _date
Calendar time.
Definition: Date.h:247
zypp::Date::print
std::string print(DateFormat dateFormat_r=DateFormat::calendar, TimeFormat timeFormat_r=TimeFormat::seconds, TimeZoneFormat timeZoneFormat_r=TimeZoneFormat::name, TimeBase base_r=TB_LOCALTIME) const
Default format is '2014-02-07 07:06:41 CET' The default is DateFormat::calendar, TimeFormat::seconds,...
Definition: Date.cc:188
zypp::Date::year365
static const ValueType year365
Definition: Date.h:50
zypp::Date::printISO
std::string printISO(DateFormat dateFormat_r=DateFormat::calendar, TimeFormat timeFormat_r=TimeFormat::seconds, TimeZoneFormat timeZoneFormat_r=TimeZoneFormat::name, TimeBase base_r=TB_LOCALTIME) const
Default ISO 8601 format is '2014-02-07T07:06:41+01'
Definition: Date.cc:204
zypp::Date::Date
Date()
Default ctor: 0.
Definition: Date.h:57
zypp::Date::hour
static const ValueType hour
Definition: Date.h:43
zypp::Date::day
static const ValueType day
Definition: Date.h:44
zypp::Date::month31
static const ValueType month31
Definition: Date.h:48
zypp::Date::TimeFormat
base::EnumClass< ETimeFormatDef > TimeFormat
'enum class TimeFormat'
Definition: Date.h:151
zypp::Date::minute
static const ValueType minute
Definition: Date.h:42
zypp::Date::DateFormat
base::EnumClass< EDateFormatDef > DateFormat
'enum class DateFormat'
Definition: Date.h:142
zypp::Date::TimeBase
TimeBase
Definition: Date.h:54
zypp::Date::TB_UTC
@ TB_UTC
Definition: Date.h:54
zypp::Date::TimeZoneFormat
base::EnumClass< ETimeZoneFormatDef > TimeZoneFormat
'enum class TimeZoneFormat'
Definition: Date.h:159
zypp::Date::month30
static const ValueType month30
Definition: Date.h:47
zypp::Date::month
static const ValueType month
Definition: Date.h:49
zypp::Date::year366
static const ValueType year366
Definition: Date.h:51
zypp::Date::ValueType
time_t ValueType
Definition: Date.h:38
zypp::Date::form
std::string form(const std::string &format_r) const
Return string representation according to format as localtime.
Definition: Date.h:112
zypp::Date::month28
static const ValueType month28
Definition: Date.h:45
zypp::Date::month29
static const ValueType month29
Definition: Date.h:46
zypp::Date::second
static const ValueType second
Definition: Date.h:41
zypp::Date::year
static const ValueType year
Definition: Date.h:52
zypp::LocaleGuard
Temorarily change a locale category value.
Definition: LocaleGuard.h:28
zypp::LocaleGuard::LocaleGuard
LocaleGuard(int category_r, const std::string &value_r="C")
Ctor saving the current locale category value.
Definition: LocaleGuard.h:34
zypp::LocaleGuard::~LocaleGuard
~LocaleGuard()
Dtor asserts the saved locale category value is restored.
Definition: LocaleGuard.h:47
str
String related utilities and Regular expression matching.
zypp::sat::detail::size_type
SolvableIdType size_type
Definition: PoolMember.h:126
zypp::str::form
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:36
zypp::str::strtonum
TInt strtonum(const C_Str &str)
Parsing numbers from string.
Definition: String.h:385
zypp::xmlout::node
std::ostream & node(std::ostream &out_r, const std::string &name_r, Node::Attr attr_r)
Definition: Xml.h:203
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
zypp::dumpAsXmlOn
std::ostream & dumpAsXmlOn(std::ostream &str, const Tp &obj, const std::string &name_r)
Definition: Xml.h:213
zypp::str::Str
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:209