libzypp
10.5.0
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00012 #include <iostream> 00013 //#include "zypp/base/Logger.h" 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 // METHOD NAME : Date::Date 00054 // METHOD TYPE : Constructor 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 // METHOD NAME : Date::form 00086 // METHOD TYPE : std::string 00087 // 00088 std::string Date::form( const std::string & format_r, Date::TimeBase base_r ) const 00089 { 00090 static char buf[1024]; 00091 std::string thisLocale = adjustLocale(); 00092 00093 if ( ! strftime( buf, 1024, format_r.c_str(), (base_r == TB_UTC ? gmtime : localtime)( &_date ) ) ) 00094 *buf = '\0'; 00095 00096 restoreLocale(thisLocale); 00097 00098 return buf; 00099 } 00100 00101 static std::string adjustLocale() 00102 { 00103 const char * tmp = ::setlocale( LC_TIME, NULL ); 00104 std::string thisLocale( tmp ? tmp : "" ); 00105 00106 if ( thisLocale.find( "UTF-8" ) == std::string::npos 00107 && thisLocale.find( "utf-8" ) == std::string::npos 00108 && thisLocale != "POSIX" 00109 && thisLocale != "C" 00110 && thisLocale != "" ) 00111 { 00112 // language[_territory][.codeset][@modifier] 00113 // add/exchange codeset with UTF-8 00114 std::string needLocale = ".UTF-8"; 00115 std::string::size_type loc = thisLocale.find_first_of( ".@" ); 00116 if ( loc != std::string::npos ) 00117 { 00118 // prepend language[_territory] 00119 needLocale = thisLocale.substr( 0, loc ) + needLocale; 00120 loc = thisLocale.find_last_of( "@" ); 00121 if ( loc != std::string::npos ) 00122 { 00123 // append [@modifier] 00124 needLocale += thisLocale.substr( loc ); 00125 } 00126 } 00127 else 00128 { 00129 // append ".UTF-8" 00130 needLocale = thisLocale + needLocale; 00131 } 00132 ::setlocale( LC_TIME, needLocale.c_str() ); 00133 } 00134 else 00135 { 00136 // no need to change the locale 00137 thisLocale.clear(); 00138 } 00139 00140 return thisLocale; 00141 } 00142 00143 static void restoreLocale(const std::string & locale) 00144 { 00145 if ( ! locale.empty() ) 00146 ::setlocale( LC_TIME, locale.c_str() ); 00147 } 00148 00150 } // namespace zypp