Date.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013
00014
00015 #include "zypp/base/String.h"
00016
00017 #include "zypp/Date.h"
00018
00019 using std::endl;
00020
00022 namespace zypp
00023 {
00024
00025 static std::string adjustLocale();
00026 static void restoreLocale(const std::string & locale);
00027
00028 namespace
00029 {
00030 inline bool isDST( struct tm & tm )
00031 {
00032 time_t t = ::mktime( &tm );
00033 struct tm *tm2 = ::localtime( &t );
00034 return ( tm2 && tm2->tm_isdst > 0 );
00035 }
00036 }
00037
00038 const Date::ValueType Date::second;
00039 const Date::ValueType Date::minute;
00040 const Date::ValueType Date::hour;
00041 const Date::ValueType Date::day;
00042 const Date::ValueType Date::month28;
00043 const Date::ValueType Date::month29;
00044 const Date::ValueType Date::month30;
00045 const Date::ValueType Date::month31;
00046 const Date::ValueType Date::month;
00047 const Date::ValueType Date::year365;
00048 const Date::ValueType Date::year366;
00049 const Date::ValueType Date::year;
00050
00052
00053
00054
00055
00056 Date::Date( const std::string & seconds_r )
00057 { str::strtonum( seconds_r, _date ); }
00058
00059 Date::Date( const std::string & date_str, const std::string & format )
00060 : _date( Date( date_str, format, TB_LOCALTIME ) )
00061 {}
00062
00063 Date::Date( const std::string & date_str, const std::string & format, Date::TimeBase base_r )
00064 : _date(0)
00065 {
00066 struct tm tm = {0,0,0,0,0,0,0,0,0,0,0};
00067 std::string thisLocale = adjustLocale();
00068
00069 char * res = ::strptime( date_str.c_str(), format.c_str(), &tm );
00070 if ( isDST(tm) )
00071 tm.tm_isdst = 1;
00072 if ( res != NULL )
00073 _date = (base_r == TB_UTC ? ::timegm : ::timelocal)( &tm );
00074
00075 restoreLocale(thisLocale);
00076
00077 if (res == NULL)
00078 throw DateFormatException(
00079 str::form( "Invalid date format: '%s'", date_str.c_str() ) );
00080 }
00081
00082
00084
00085
00086
00087
00088 std::string Date::form( const std::string & format_r ) const
00089 { return form( format_r, TB_LOCALTIME ); }
00090
00091 std::string Date::form( const std::string & format_r, Date::TimeBase base_r ) const
00092 {
00093 static char buf[1024];
00094 std::string thisLocale = adjustLocale();
00095
00096 if ( ! strftime( buf, 1024, format_r.c_str(), (base_r == TB_UTC ? gmtime : localtime)( &_date ) ) )
00097 *buf = '\0';
00098
00099 restoreLocale(thisLocale);
00100
00101 return buf;
00102 }
00103
00104 static std::string adjustLocale()
00105 {
00106 const char * tmp = ::setlocale( LC_TIME, NULL );
00107 std::string thisLocale( tmp ? tmp : "" );
00108
00109 if ( thisLocale.find( "UTF-8" ) == std::string::npos
00110 && thisLocale.find( "utf-8" ) == std::string::npos
00111 && thisLocale != "POSIX"
00112 && thisLocale != "C"
00113 && thisLocale != "" )
00114 {
00115
00116
00117 std::string needLocale = ".UTF-8";
00118 std::string::size_type loc = thisLocale.find_first_of( ".@" );
00119 if ( loc != std::string::npos )
00120 {
00121
00122 needLocale = thisLocale.substr( 0, loc ) + needLocale;
00123 loc = thisLocale.find_last_of( "@" );
00124 if ( loc != std::string::npos )
00125 {
00126
00127 needLocale += thisLocale.substr( loc );
00128 }
00129 }
00130 else
00131 {
00132
00133 needLocale = thisLocale + needLocale;
00134 }
00135 ::setlocale( LC_TIME, needLocale.c_str() );
00136 }
00137 else
00138 {
00139
00140 thisLocale.clear();
00141 }
00142
00143 return thisLocale;
00144 }
00145
00146 static void restoreLocale(const std::string & locale)
00147 {
00148 if ( ! locale.empty() )
00149 ::setlocale( LC_TIME, locale.c_str() );
00150 }
00151
00153 }