通常在我们的程序中,需要使用到年月日类型的时间,也需要使用64位整型的时间,比如存储到数据库中(数据库中对应的时间字段的类型则为big int数据类型)。代码中会涉及到如何获取当前时间,以及年月日时间和64位时间之间的转换问题。下面就自己遇到的实际情况,做一个小的总结。
1、获取当前时间
获取当前时间的时间有多种,下面说说使用time函数,使用CTime类和使用SYSTEMTIME结构体这三种常见的获取当前时间的方法。
(1)使用time函数获取当前时间
使用该函数的时候应该包含time.h头文件,使用该函数获取当前的64位时间最为简单。
__time64_t curTime = ::time(NULL);
该方法在线程函数中比较实用,可以进行时间上的控制,通常线程函数都是一个循环体,在每次循环开始的时候,都获取一下当前的时间,比如:
(i)在客户端的一个线程中,一方面要定时地给服务器发送心跳包数据(假如每隔10秒),另一方面又要进行其他的数据收发工作,而这些数据又要实时的的收发,所以在该线程中不能等待10秒钟后发送心跳包,然后再收发其他的数据,这个时候我们就可以定义一个__time64_t类型的时间变量,记录最后一次发送心跳包的时间,这样在线程函数的循环中,每次循环只需要等待一个微小的时间就进入下一次循环,在实时收发数据的同时判断当前时间离最后一次发心跳包的时间间隔是否已经到达10秒,若到达则发送新的心跳包,并更新最后一次心跳包发送的时间。
(ii)在视频监控系统中,有计划录像的概念,那录像的计划是如何实现的呢?是如何进行调度的呢?这里就简要的说明一下,开启一个录像调度的线程,在该线程中遍历录像对象列表,对象中包含录像计划的开始时间和结束时间,当当前时间大于或等于开始录像时间时,就开始录像,当当前时间大于或等于结束录像时间时,就结束录像。
(2)使用CTime类获取当前时间
由于该方法使用到CTime MFC类,所以只能应用于MFC的工程中。首先定义一个CTime类对象,然后调CTime::GetCurrentTime()获取当前时间,最后利用GetYear( ),GetMonth( ),GetDay( ),GetHour( ),GetMinute( )和GetSecond( )等函数得到具体的年月日时分秒信息。
CTime curTime; curTime = CTime::GetCurrentTime(); CString strCurTime; strCurTime.Format( _T("%04d/%02d/%02d %02d:%02d:%02d"), curTime.GetYear(), curTime.GetMonth(), curTime.GetDay(), curTime.GetHour(), curTime.GetMinute(), curTime.GetSecond() ); ......//将时间显示出来
(3)使用SYSTEMTIME结构体获取当前时间
与CTime类处理的类似,先定义一个结构体对象,然后调用GetLocalTime函数来获取当前时间,结构体对象的成员中则包含有年月日信息。与CTime类不同的是,该方法可以应用与MFC工程中,也可以用于Win32工程中。
SYSTEMTIME curTime; GetLocalTime(&curTime); CString strCurTime; strCurTime.Format( _T("%04d/%02d/%02d %02d:%02d:%02d"), curTime.wYear, curTime.wMonth, curTime.wDay, curTime.wHour, curTime.wMinute, curTime.wSecond ); ......//将当前时间显示出来
2、年月日时间和64位时间的相互转化
64位时间保存到数据库是很方便的,之前也有很多人问过如何将年月日时间保存到数据库中,我觉得将他们转化为64位时间后在保存到数据库中比较好,数据库中只要有一个big int时间字段就可以了,这样不仅简化了时间的保存方法,还有利于数据表的排序查询。界面中数据要保存到数据库中,要将之转化为64为时间;从数据库中读出64为时间,要将之转化为年月日时间在界面上显示出来。
(1)使用CTime类实现年月日时间和64位时间的相互转化
(i)年月日时间转化为64位时间: 构造CTime类对象时,将年月日信息作为构造参数。
CTime thatTime(2010, 10, 06, 19, 22, 55); __time64_t thatTime_64t = thatTime.GetTime();
(ii)64位时间转化为年月日时间: 构造CTime类对象时,将64位时间作为构造参数。
__time64_t tahtTime; ......//中间处理,获取64位时间 CTime ctThatTime(tahtTime); CString strThatTime; strThatTime.Format( _T("%04d/%02d/%02d %02d:%02d:%02d"), ctThatTime.GetYear(), ctThatTime.GetMonth(), ctThatTime.GetDay(), ctThatTime.GetHour(), ctThatTime.GetMinute(), ctThatTime.GetSecond() ); ......
上述方法适用于MFC工程中,而在非MFC的工程中则要使用到tm结构体。
(2)使用tm结构体实现年月日时间和64位时间的相互转化
tm结构体的定义如下所示:
struct tm { int tm_sec; /* seconds after the minute - [0,59] */ int tm_min; /* minutes after the hour - [0,59] */ int tm_hour; /* hours since midnight - [0,23] */ int tm_mday; /* day of the month - [1,31] */ int tm_mon; /* months since January - [0,11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday - [0,6] */ int tm_yday; /* days since January 1 - [0,365] */ int tm_isdst; /* daylight savings time flag */ };
(i)年月日时间转化为64位时间: 首先使用SYSTEMTIME结构体来获取当前的时间,然后利用tm结构体将获得年月日时间转化为64位时间。
SYSTEMTIME curTime; GetLocalTime( &curTime ); struct tm tmTime; tmTime.tm_year = curTime.wYear - 1900; tmTime.tm_mon = curTime.wMonth; tmTime.tm_mday = curTime.wDay; tmTime.tm_hour = curTime.wHour; tmTime.tm_min = curTime.wMinute; tmTime.tm_sec = curTime.wSecond; __time64_t curTime_64t = _mktime64( &tmTime );
(ii)64位时间转化为年月日时间: 首先将64位时间转化为tm结构体时间,然后再转化成年月日时间。
__time64_t tahtTime; ......//获取64位时间 tm *tmThatTime = _localtime64( &thatTime ); char cThatTime[30]; memset( cThatTime, 0, 30 ); sprintf( cThatTime, "%04d/%02d/%02d %02d:%02d:%02d", tmThatTime->tm_year+1900, tmThatTime->tm_mon+1, tmThatTime->tm_mday, tmThatTime->tm_hour, tmThatTime->tm_min, tmThatTime->tm_sec ); ......