⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wydate.cpp

📁 一个不错
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* Copyright is licensed under GNU LGPL.                 by I.J.Wang 2003*/#define WYLIB_SOURCE#include "wydate.h"#include "wystr.h"#include "wymutex.h"#include "wy_atdestroy.h"#include <cstdlib>#include <new>        // new and bad_alloc// For mktime, localtime_r// #include <ctime>#include <time.h>     // for externalsextern char *tzname[2];extern long timezone;extern int daylight;static const char ENVNAME_TZ[]="TZ";const char WyDate::class_name[]="WyDate";const char WyDate::TIMEZONE_UTC[]="UTC";// for speeding up copy/convert/compare of TIMEZONE_UTC//static const WyStr::size_type wy_TZLEN= sizeof(WyDate::TIMEZONE_UTC)-1;class Wy__static_check__ {  public:    Wy__static_check__ ()               {               // Impl assertions               if(WyTimeSpec()!=WyTimeSpec( Wy_Second(0),                                            Wy_Nano(0))) {                 WY_TERMINATE("");   // assertion fail               }               if((std::numeric_limits<Wy_Second>::max()!=                   std::numeric_limits<std::time_t>::max())||                  (std::numeric_limits<Wy_Second>::min()!=                   std::numeric_limits<std::time_t>::min())||                  (std::numeric_limits<Wy_Nano>::max()!=                   std::numeric_limits<signed long int>::max())||                  (std::numeric_limits<Wy_Nano>::min()!=                   std::numeric_limits<signed long int>::min())) {                 WY_TERMINATE("");   // assertion fail               }               if(wy_TZLEN>WyStr::min_capacity()) {                 WY_TERMINATE("");   // Impl::reset() may fail               }              };} static const wy_do_not_use_me__;// Class of environment variable// (for temporary use, rrid-like)//class TmpEnvVar {    const char* _vname;    bool  _has_value;   // _value available    WyStr _value;       // value of _vname indicated environment variable    // Hidden    TmpEnvVar();    TmpEnvVar(const TmpEnvVar&);    const TmpEnvVar& operator =(const TmpEnvVar&);    bool operator ==(const TmpEnvVar&);  public:    // Construct object to contain value of name (restore at destruction)    //    // Note: argument name pointed string should be const through    //       object life time    //    //   has_value= true, if name defined in the environment variable    //              false otherwise    //       value= string value of name defined environment variable    //              undefined if has_value is false    //    // [Throw] WyStr::Reply    //       Wym_ENOMEM    //    TmpEnvVar(const char* name) WY__TSPC(WyStr::Reply);    // Restore environment variable with value in *this and destruct *this    //    ~TmpEnvVar();    bool has_value(void) const WY__TSPC()         { return _has_value; };    const WyStr& value(void) const WY__TSPC()         { return _value; };};TmpEnvVar::TmpEnvVar(const char* name) WY__TSPC(WyStr::Reply) : _vname(name),_has_value(false),_value(){ const char* cptr=::getenv(name); if(cptr==NULL) {   return; } _has_value=true; _value=WyCSeg(cptr);};TmpEnvVar::~TmpEnvVar(){ if(_has_value) {   if(::setenv(_vname,_value.c_str(),1)!=0) {     WY_THROW( WyRet() );  // recovering the change failed                           // (insufficient environment space)                           // Changed from WY_TERMINATE to WY_THROW   } } else {   ::unsetenv(_vname); }};// Mutex for accessing environment TZ//static WyMutex& wy_tzmutex(void) WY__TSPC(){ static WyMutex _tzmtx; return(_tzmtx);};// [Internal] Get the value of environment TZ//// [Ret] Ok //         defined=  true, value is set to the value of environment TZ//         defined= false, TZ not in the environment, value intact//       Wym_ENOMEM//static WyRet getenv_tz(bool& defined, WyStr& value)try { WyLock aa( wy_tzmutex() ); WyRet r; const char *vp( ::getenv(ENVNAME_TZ) ); if(vp==NULL) {   defined=false; } else {   if((r=value.reset(WyCSeg(vp)))!=Ok) {  // ctor of WyCSeg wont throw     WY_RETURN(r);   }   defined=true; } return(Ok);}catch(const WyLock::Reply& e) {  WY_THROW( WyRet(e) );}catch(const WyRet& e) { WY_NDEBUG_MSG(e);  WY_THROW( WyRet(e) );};class WyDate::Impl {  public:    // zone = TIMEZONE_UTC    // year = 1970    // month= 1    [1-12]    // mday = 1    [1-31]    // hour = 0    [0-23]    // min  = 0    [0-59]    // sec  = 0    [0-61]    // wday = 4    [0-6]    // isdst= 0    //    // [Throw] WyDate::Reply    //             Wym_ENOMEM    //    Impl() WY__TSPC(WyDate::Reply);    // [Throw] WyDate::Reply    //             Wym_ENOMEM    //    Impl(const Impl&) WY__TSPC(WyDate::Reply);    // [Syn] Construct object of time zone tzval, UTC time ucs    //    // [Throw] WyDate::Reply    //       Wym_EFAULT    //       Wym_EINVAL  unrecognized tzval    //       Wym_ERANGE  conversion failed    //       Wym_ENOMEM     //    Impl(const char* tzval,const WyTimeSpec& ttm);    // [Syn] Construct object of time zone tzval, argument given date    //    // [Throw] WyDate::Reply    //       Wym_EFAULT    //       Wym_EINVAL  unrecognized tzval    //       Wym_ERANGE  conversion failed    //       Wym_ENOMEM     //    Impl(const char* tzval,int year,int month,int mday, int hour,int min, int sec);    bool is_default(void) const WY__NOTHROW__;        // [Syn] Reconstruct *this to WyDate()    //    void reset(void) WY__NOTHROW__;    // [Syn] Reconstruct *this to WyDate(const Impl&)    //    // [Ret] Ok    //       Wym_ENOMEM    //    WyRet reset(const Impl& src) WY__TSPC();    // [Syn] Reconstruct *this to WyDate(const WyStr&,const WyTimeSpec&)    //    // [Ret] Ok    //       Wym_EFAULT    //       Wym_EINVAL  unrecognized tzval    //       Wym_ERANGE  conversion failed    //       Wym_ENOMEM     //    WyRet reset(const char* tzval, const WyTimeSpec& ucs);    // [Syn] Reconstruct *this to WyDate(const WyStr&,int,int,int,int,int,int)    //    // [Ret] Ok    //       Wym_EFAULT    //       Wym_EINVAL  unrecognized tzval    //       Wym_ERANGE  conversion failed    //       Wym_ENOMEM     //    WyRet reset(const char* tzv,int year,int month,int mday, int hour,int min, int sec);    void swap(Impl& another) WY__TSPC();    // [Ret] Time zone value (as for the environment string)    //    // Note: _SC_TZNAME_MAX is defined on this Linux machine (=6)    //       this may be problem with the design of this class (too short)    //    const WyStr& time_zone(void) const WY__NOTHROW__              { return _tzv; };    int year(void) const WY__NOTHROW__              { return _year; };    // [Syn] Get the month of a year of the object    //     // [Ret] Month of the object [1-12]    //     int month(void) const WY__NOTHROW__              { return _month; };    // [Syn] Get the day of the month    //     // [Ret] Day of the month [1-31]    //     int mday(void) const WY__NOTHROW__              { return _mday; };    // [Syn] Get the hour in a day    //     // [Ret] The hour [0-23]    //     int hour(void) const WY__NOTHROW__              { return _hour; };    // [Syn] Get the minute in an hour    //     // [Ret] Minute [0-59]    //     int min(void) const WY__NOTHROW__              { return _min; };    // [Syn] Get the second in a minute.    //    // [Ret] Second [0-61]    //     int sec(void) const WY__NOTHROW__              { return _sec; };    // [Syn] Get the day of the week    //     // [Ret] Day of the week [0-6]    //     int wday(void) const WY__NOTHROW__              { return _wday; };    // [Syn] Get the day of the year    //     // [Ret] Day of the year [0-365]    //     int yday(void) const WY__NOTHROW__              { return _yday; };    int isdst(void) const WY__NOTHROW__              { return _isdst; };    // [Syn] Get the UTC time of *this    //     // [Ret] UTC time of *this    //    WyTimeSpec utc_time(void) const WY__NOTHROW__              { return _wyt; };    // [Syn] Synchronize date to UTC second ucs    //    // [Ret] Ok    //       Wym_ERANGE  conversion failed    //       Wym_ENOMEM     //    WyRet set_utc(const WyTimeSpec& ucs);    // [Syn] Set date as the arguments indicate    //    // [Ret] Ok    //       Wym_EINVAL  invalid argument    //       Wym_ERANGE  conversion failed    //       Wym_ENOMEM     //    WyRet set_date(int year,int month,int mday, int hour,int min, int sec);    // [Syn] Add linear time to *this    //    // [Ret] Ok        //       Wym_ERANGE result not representable    //       Wym_ENOMEM     //    WyRet add(const WyTimeSpec& tm);    // [Syn] Reconstruct date as by Impl(const Impl&)    //     // [Throw] WyDate::Reply    //       Wym_ENOMEM    //     // [Ret] const Reference of this object    //    const Impl& operator =(const Impl& rhs) WY__TSPC(WyDate::Reply);    // [Syn] Convert *this to text representation according to the format, and    //       reset res with the result    //    // Note: This member is the conversion for ::strftime. resultant timezone    //       string may not be what WyDate otherwise uses    //       (timezone issue is vague to me).    //       Locale may be involved.    //     // [Ret] Ok    //       Wym_EFBIG    //       Wym_ENOMEM     //    WyRet _strftime(WyStr& str, const char* format) const;    // [Syn] Add time by rhs    //    // [Throw] WyDate::Reply    //       Wym_ERANGE result not representable    //       Wym_ENOMEM     //    // [Ret] const reference of this object    //    // [Refer] WyTimeSpec::operator+ , reset    //    const Impl& operator +=(const WyTimeSpec& rhs);    // [Syn] Equivalence test    //    // [Ret] bool result of the equivalence    //    bool operator ==(const Impl& rhs) const WY__NOTHROW__         { return( (_wyt==rhs._wyt)&&(_tzv==rhs._tzv) ); };    bool operator !=(const Impl& rhs) const WY__NOTHROW__         { return( (_wyt!=rhs._wyt)||(_tzv!=rhs._tzv) ); };  private:    WyStr _tzv;               // time zone string    int _isdst;               // daylight saving time    int _year;                // [A.D. year]    int _month;               // [1,12]    int _mday;                // [1,31]    int _hour;                // [0,23]    int _min;                 // [0,59]    int _sec;                 // [0,61]    // The following members are redundant, but useful.    //     int _wday;                // [0-6] week day    int _yday;                // [0,365] Days since January 1st    // Corresopnding UTC time (of the date)     //    WyTimeSpec _wyt;};WyDate::Impl::Impl() WY__TSPC(WyDate::Reply)try : _tzv( WyCSeg(TIMEZONE_UTC,wy_TZLEN) ),_isdst(0),      _year(Default_Year),_month(Default_Month),_mday(Default_MDay),     _hour(Default_Hour),_min(Default_Min),_sec(Default_Sec),     _wday(Default_WDay),_yday(Default_YDay), _wyt(){}catch(const WyStr::Reply& e) {  WY_THROW( WyDate::Reply(e) );};WyDate::Impl::Impl(const WyDate::Impl& src) WY__TSPC(WyDate::Reply)try : _tzv(src._tzv),_isdst(src._isdst),      _year(src._year),_month(src._month),_mday(src._mday),     _hour(src._hour),_min(src._min),_sec(src._sec),     _wday(src._wday),_yday(src._yday), _wyt(src._wyt){}catch(const WyStr::Reply& e) {  WY_THROW( WyDate::Reply(e) );};WyDate::Impl::Impl(const char* tzval,const WyTimeSpec& tm){ WyRet r=this->reset(tzval,tm); if(r!=Ok) {   WY_THROW( WyDate::Reply(r) ); }};WyDate::Impl::Impl(const char* tzval,int year,int month,int mday, int hour,int min, int sec){ WyRet r=this->reset(tzval,year,month,mday,hour,min,sec); if(r!=Ok) {   WY_THROW( WyDate::Reply(r) ); }};bool WyDate::Impl::is_default(void) const WY__NOTHROW__{ return(_wyt.is_default()        &&(_tzv.cseg()==WyCSeg(TIMEZONE_UTC,wy_TZLEN)));};void WyDate::Impl::reset(void) WY__NOTHROW__{ if(_tzv.reset( WyCSeg(TIMEZONE_UTC,wy_TZLEN) )!=Ok) {   WY_TERMINATE("");   // asserted not to fail (enough capacity) } _isdst=0; _wyt.reset(); _year=Default_Year; _month=Default_Month; _mday=Default_MDay; _hour=Default_Hour; _min=Default_Min; _sec=Default_Sec; _wday=Default_WDay; _yday=Default_YDay;};WyRet WyDate::Impl::reset(const WyDate::Impl& src) WY__TSPC(){ WyRet r=_tzv.reset(src._tzv); if(r!=Ok) {   WY_RETURN(r); } _isdst=src._isdst; _wyt.reset(src._wyt); _year=src._year; _month=src._month; _mday=src._mday; _hour=src._hour; _min=src._min; _sec=src._sec; _wday=src._wday; _yday=src._yday; return(Ok);};WyRet WyDate::Impl::reset(const char* tzval,const WyTimeSpec& ucs)try {struct tm tm;std::time_t tt;  if(tzval==0) {    WY_RETURN(Wym_EFAULT);  }  // Warning: Not all unrecognized tzval can be reported  if(tzval[0]==0) {    WY_RETURN(Wym_EINVAL);  // empty string not accepted for now  }  tt=ucs.second();  {    WyLock aa(wy_tzmutex());    TmpEnvVar rr_tz(ENVNAME_TZ);    if(::setenv(ENVNAME_TZ,tzval,1)!=0) {      WY_RETURN(Wym_ENOMEM);  // man. indicates no errno and only this reason    }    ::tzset();  // man. indicated this can be saved, call it however.    if(::localtime_r(&tt,&tm)==NULL) {      WY_RETURN(Wym_ERANGE);    }    _tzv=tzval;   // WyCSeg(tzval) wont throw  } _wyt.reset(ucs); _isdst=tm.tm_isdst; _year=tm.tm_year+1900; _month=tm.tm_mon+1; _mday=tm.tm_mday; _hour=tm.tm_hour; _min=tm.tm_min; _sec=tm.tm_sec; _wday=tm.tm_wday; _yday=tm.tm_yday; return(Ok);}catch(const WyStr::Reply& e) { return(e);}catch(const WyRet& e) { WY_NDEBUG_MSG(e); WY_THROW( WyRet(e) );};WyRet WyDate::Impl::reset(const char* tzval,int year,int month,int mday, int hour,int min, int sec)try {  if((month<1)||(mday<1)||(hour<0)||(min<0)||(sec<0)) {    WY_RETURN(Wym_EINVAL);  }  if(tzval==0) {    WY_RETURN(Wym_EFAULT);  }  // Warning: Not all unrecognized tzval can be reported  if(tzval[0]==0) {    WY_RETURN(Wym_EINVAL);  // empty string not accepted for now  }  struct std::tm tm;  std::time_t tt;  tm.tm_year=year-1900;  tm.tm_mon=month-1;  tm.tm_mday=mday;  tm.tm_hour=hour;  tm.tm_min=min;  tm.tm_sec=sec;  tm.tm_isdst=-1;  if(tm.tm_year>=year) {    WY_RETURN(Wym_ERANGE);  // value conversion failed  }  {    WyLock aa(wy_tzmutex());    TmpEnvVar rr_tz(ENVNAME_TZ);    if(::setenv(ENVNAME_TZ,tzval,1)!=0) {      WY_RETURN(Wym_ENOMEM);  // man. indicates no errno and only this reason    }    ::tzset();    tt=std::mktime(&tm);    if(tt==static_cast<std::time_t>(-1)) {      WY_RETURN(Wym_ERANGE);    }    _tzv=tzval;   // WyCSeg(tzval) wont throw  }  _wyt.reset(tt,Wy_Nano(0));  _isdst=tm.tm_isdst;  _year=year;  _month=month;  _mday=mday;  _hour=hour;  _min=min;  _sec=sec;  _wday=tm.tm_wday;  _yday=tm.tm_yday;  return(Ok);}catch(const WyStr::Reply& e) { return(e);}catch(const WyRet& e) { WY_NDEBUG_MSG(e); WY_THROW( WyRet(e) );};void WyDate::Impl::swap(Impl& another) WY__TSPC(){ _tzv.swap(another._tzv); _wyt.swap(another._wyt); Wy__Base::vswap(_isdst,another._isdst); Wy__Base::vswap(_year,another._year); Wy__Base::vswap(_month,another._month); Wy__Base::vswap(_mday,another._mday); Wy__Base::vswap(_hour,another._hour); Wy__Base::vswap(_min,another._min); Wy__Base::vswap(_sec,another._sec); Wy__Base::vswap(_wday,another._wday); Wy__Base::vswap(_yday,another._yday);};WyRet WyDate::Impl::set_utc(const WyTimeSpec& rhs)try {struct tm tm;const std::time_t tt( rhs.second() );  {    WyLock aa(wy_tzmutex());    TmpEnvVar rr_tz(ENVNAME_TZ);    if(::setenv(ENVNAME_TZ,_tzv.c_str(),1)!=0) {      WY_RETURN(Wym_ENOMEM);  // man. indicates no errno and only this reason    }    ::tzset();  // man. indicated this can be saved, call it however.    if(::localtime_r(&tt,&tm)==NULL) {      WY_RETURN(Wym_ERANGE);    }  } _wyt.reset(rhs); _isdst=tm.tm_isdst; _year=tm.tm_year+1900; _month=tm.tm_mon+1; _mday=tm.tm_mday; _hour=tm.tm_hour; _min=tm.tm_min; _sec=tm.tm_sec; _wday=tm.tm_wday; _yday=tm.tm_yday; return(Ok);}catch(const WyStr::Reply& e) { return(e);}catch(const WyRet& e) { WY_NDEBUG_MSG(e); WY_THROW( WyRet(e) );};WyRet WyDate::Impl::set_date(int year,int month,int mday, int hour,int min, int sec)try {  if((month<1)||(mday<1)||(hour<0)||(min<0)||(sec<0)) {    WY_RETURN(Wym_EINVAL);  }  struct std::tm tm;  std::time_t tt;  tm.tm_year=year-1900;  tm.tm_mon=month-1;  tm.tm_mday=mday;  tm.tm_hour=hour;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -