本站首页    管理页面    写新日志    退出


 

 

 


最新日志

练车
今天是2011年07月02号
温馨
CInternetSession 类
CHttpFile实现Get/Post
在MFC中加一个控制台DOS界面
strtol 函数
outputParam
有关CTime和ColeDateTime
variant_t ,_bstr_t 与

 


 

最近的评论

回复:CHttpFile实现Get/Po
回复:好久没有来了
回复:参数自整定的模糊PID
回复:电子设计大赛自由命题可参考的题目
回复:数字万用表使用方法
回复:公交车上巨搞笑的一幕
回复:电子设计大赛自由命题可参考的题目
回复:电子设计大赛自由命题可参考的题目
回复:电子设计大赛自由命题可参考的题目
回复:暑假回来

 


 

连接




    

有关CTime和ColeDateTime
sccwqiang 发表于 2009-7-12 15:47:59

[转]有关CTime和ColeDateTime 1、通用处理:time_t(win平台64位系列对应__time64_t,Linux暂无研究,以后补上)time_t=long int,范围从1970-1-1 0:0:0 到2038-1-18 19:14:07__time64_t=__int64,范围从1970-1-1 0:0:0 到3000-12-31 23:59:59这个变量每一秒增加1,精度很低。但是已经可以处理常用时间问题了:A、获取当前时间:time_t ttime=time(NULL);__time64_t ttime=_time64(NULL);B、转换time_t到可以识别的结构struct tm:struct tm *ptm=localtime(&ttime);或者 struct tm *ptm=gmtime(&ttime);struct tm *ptm=_localtime64(&ttime);或者 struct tm *ptm=_gmtime64(&ttime);C、获取时间差:double difftime(time_t tm1,time_t tm2);D、创建:time_t mktime(struct tm*ptm);__time64_t _mktime64(struct tm*ptm);E、拼装字符串:size_t strftime(char*strDest,size_t maxsize,const char*format,const struct tm*timeptr);size_t wcsftime(wchar_t*strDest,size_t maxsize,const wchar_t*format,const struct tm *timeptr);说明:time_t时间范围有限,到2038年将面临第2次千年虫危机struct tm结构要注意:tm_year从1900年计数,tm_mon月份从0计数对于struct tm *,由于是栈对象的直接使用,所以一次只能使用一个,即:struct tm *ptm1=_localtime(&ttime1);struct tm *ptm2=_localtime(&ttime2);即使ttime1和ttime2不是一个时间,得到的ptm1也是等于ptm2的! 2、Win32 Platform SDK:A、SYSTEMTIME结构:void GetSystemTime( LPSYSTEMTIME lpSystemTime);void GetLocalTime(LPSYSTEMTIME lpSystemTime);BOOL SetSystemTime(const SYSTEMTIME* lpSystemTime);B、FILETIME结构(由GetFileTime函数或者FindFirstFile函数获得),与SYSTEMTIME结构相互转换:BOOL FileTimeToSystemTime(const FILETIME* lpFileTime,LPSYSTEMTIME lpSystemTime);BOOL SystemTimeToFileTime(const SYSTEMTIME* lpSystemTime,LPFILETIME lpFileTime);3、Win32平台:DWORD GetTickCount(void);计数机器启动至今毫秒数,对于一般精度已经足够表示了。要注意:A、最多只能计数49.7天,如果windows这么长还未重启,计数失效B、这个是以5秒92下的机器计数为基础的,所以精度只能精确到百毫秒,需要更高精度,请看下面:4、终极精度时间函数:A、win32:LARGE_INTEGER li={0};QueryPerformanceCounter(&li);li.QuadPart返回的是机器计数微妙!B、linux:struct timeval tv={0};struct timezone tz={0};gettimeofday(&tv,&tz);其中tv.tv_sec存储秒信息,tv.tv_usec存储微妙信息C、对于select函数,参数timeval可以精确到微妙等待,本来以为所有平台都会因此有延时功能。实际中却发现,win2000及以下平台居然是精度不够立即返回!造成无间断循环导致CPU 100%!所以跨平台编程时,建议此函数慎用!5、win32的DATE类型其实DATE=double,整数部分保存1900-1-1以来天数,小数部分保存微妙数可以通过以下函数与SYSTEMTIME相互转换:INT VariantTimeToSystemTime(double vtime,LPSYSTEMTIME lpSystemTime);INT SystemTimeToVariantTime(LPSYSTEMTIME lpSystemTime,double*pvtime); 也可以通过COleDatetime类进行处理。使用中,COleDatetime便是以此类型作为基础处理,同时ADO数据库编程中,时间字段返回的也是这个类型但是这两种转换都存在重大数据丢失问题!最终都只能保留到秒信息,毫秒信息没了,而且还对毫秒做了四舍五入运算!如果是数据库编程设计这种高精度,就不能使用ADO了,只能用ODBC和OLE DB6、MFC中有两个类:COleDatetime(以DATE为基础),CTime(以__time64_t为基础)如果绑定的是日期型控件,一定要用COleDatetime!虽然CTime可以精确到3000年,但是超过这个范围,CTime是要抛出异常,让你程序崩溃的!=================================================== 在MFC中操作时间的类主要有两对:CTime和CTimeSpan与 COleDateTime和COleDateTimeSpan,CTime和CTimeSpan主要封装了ANSI time_t和关于time_t的Run-Time库的主要函数,CTime里面使用的成员变量是time_t类型,该类型是个long型,由于long 类型的原因,所以该类只能处理4294967296秒约68年的数据,所以用CTime只能处理1970年到2038年的日期。幸好,MFC同时提供了COleDateTime和COleDateTimeSpan类,使用该两个类完全可以代替CTime和 CTimeSpan,COleDateTime和COleDateTimeSpan类所使用的成员变量是DATE类型,该类型是个double类型,而且使用的单位是日,所以可以处理从100年1月1日到9999年12月31日的日期时间,COleDateTime类的日期计算主要是操作公有成员变量 COleDateTime::m_dt,该变量是DATE即double类型,该变量是为零时是1899年12月30日0时0分0秒,大于零时的日期比 1899年12月30日0时0分0秒大,反之亦然,例如:COleDateTime t;t.m_dt=0;AfxMessageBox(t.Format("%Y-%m-%d %H:%M:%S"));运行的结果是:1899-12-30 00:00:00 COleDateTime t;t.m_dt=39444.437731;AfxMessageBox(t.Format("%Y-%m-%d %H:%M:%S"));运行的结果是:2007-10-28 10:30:20 反过来以可以得到变量的值,例如:COleDateTime t(2004,12,28,22,22,22);CString str;str.Format("%f",t.m_dt);AfxMessageBox(str);运行的结果是:38349.932199 COleDateTimeSpan类是用于对COleDateTime类的两个时间的时间间隔的计算,COleDateTimeSpan类使用的成员变量COleDateTimeSpan::m_span是一个double类型是用于记录两个COleDateTime::m_dt的时间差,例如:COleDateTime t1(2006,1,1,0,0,0);COleDateTime t2(2007,1,1,0,0,0);COleDateTimeSpan ts=t2-t1;CString str;str.Format("%f",ts.m_span);AfxMessageBox(str);运行的结果是:365.000000 反过来也可以得到日期COleDateTime t1(2006,1,1,0,0,0);COleDateTimeSpan ts;ts.m_span=400.0;COleDateTime t2=t1+ts;AfxMessageBox(t2.Format("%c"));运行的结果是:02/05/07 00:00:00 可是在使用COleDateTimeSpan类中以下的几个函数可要小心,这不知道是不是MFC的一个Bug,double GetTotalDays( ) const;double GetTotalHours( ) const;double GetTotalMinutes( ) const;double GetTotalSeconds( ) const;几个函数的返回值都是double类型但是,如double GetTotalSeconds( ) const;在MFC内部的原形是:_AFXDISP_INLINE double COleDateTimeSpan::GetTotalSeconds() const{ ASSERT(GetStatus() == valid);long lReturns = (long)(m_span * 24 * 60 * 60 + AFX_OLE_DATETIME_HALFSECOND);return lReturns;}看到没有,它返回的实际是个long类型,并不是一个double类型,所以在使用这几个函数的时候计算两个时间的间隔不要太大,特别是 GetTotalSeconds( )函数,如计算两个时间的间隔大于68年时就会溢出,所以我建议直接读取COleDateTimeSpan::m_span变量的值,这是一个单位为日的时间间隔,例如:COleDateTime t1(2000,1,1,0,0,0);COleDateTime t2(2070,1,1,0,0,0);COleDateTimeSpan ts=t2-t1;CString str;str.Format("%f",ts.GetTotalSeconds());AfxMessageBox(str);运行的结果是:-2085892096.000000这个结果明显是一个溢出,如果使用str.Format("%f",ts.m_span*86400);则会得到2209075200.000000。 所以灵活使用COleDateTime类的m_dt变量和COleDateTimeSpan类的m_span变量操作会得到意想不到的收获

阅读全文(6937) | 回复(0) | 编辑 | 精华


发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)

 

 

 


站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.047 second(s), page refreshed 144326464 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号