libzypp 17.31.0
Date.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12#include <iostream>
13//#include <zypp-core/base/Logger.h>
14
15#include <zypp-core/base/String.h>
16#include <zypp-core/base/Xml.h>
17
18#include <zypp-core/Date.h>
19
20using std::endl;
21
23namespace zypp
24{
26 namespace
27 {
32 struct LocaleGuard
33 {
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
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
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 {
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 {
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
std::string _mylocale
Definition: Date.cc:80
Store and operate on date (time_t).
Definition: Date.h:33
ValueType _date
Calendar time.
Definition: Date.h:247
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
static const ValueType year365
Definition: Date.h:50
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
Date()
Default ctor: 0.
Definition: Date.h:57
static const ValueType hour
Definition: Date.h:43
static const ValueType day
Definition: Date.h:44
static const ValueType month31
Definition: Date.h:48
base::EnumClass< ETimeFormatDef > TimeFormat
'enum class TimeFormat'
Definition: Date.h:151
static const ValueType minute
Definition: Date.h:42
base::EnumClass< EDateFormatDef > DateFormat
'enum class DateFormat'
Definition: Date.h:142
TimeBase
Definition: Date.h:54
@ TB_UTC
Definition: Date.h:54
base::EnumClass< ETimeZoneFormatDef > TimeZoneFormat
'enum class TimeZoneFormat'
Definition: Date.h:159
static const ValueType month30
Definition: Date.h:47
static const ValueType month
Definition: Date.h:49
static const ValueType year366
Definition: Date.h:51
time_t ValueType
Definition: Date.h:38
std::string form(const std::string &format_r) const
Return string representation according to format as localtime.
Definition: Date.h:112
static const ValueType month28
Definition: Date.h:45
static const ValueType month29
Definition: Date.h:46
static const ValueType second
Definition: Date.h:41
static const ValueType year
Definition: Date.h:52
Temorarily change a locale category value.
Definition: LocaleGuard.h:28
LocaleGuard(int category_r, const std::string &value_r="C")
Ctor saving the current locale category value.
Definition: LocaleGuard.h:34
~LocaleGuard()
Dtor asserts the saved locale category value is restored.
Definition: LocaleGuard.h:47
String related utilities and Regular expression matching.
SolvableIdType size_type
Definition: PoolMember.h:126
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:36
TInt strtonum(const C_Str &str)
Parsing numbers from string.
std::ostream & node(std::ostream &out_r, const std::string &name_r, Node::Attr attr_r)
Definition: Xml.h:203
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
std::ostream & dumpAsXmlOn(std::ostream &str, const Repository &obj)
Definition: Repository.cc:406
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition: String.h:212