在vc6.0中,localtime只能转换1970到2038年的时间范围,在vc2005中,被扩展到了1970年到3000年,但如果想要转换更大的时间范围怎么办?比如SQLServer的datetime类型就可以表示1753年到9999年的范围,用localtime肯定是不行的。

 

经过网上大量搜索及个人研究,终于找到了一个方法,可以转换1601年到30827年的范围,够大了吧?

 

由于本人水平有限,无法太深入了解细节内容,但至少是可以实现转换了,以下就是实现过程:

 

输入:从1601/1/1 0:00:00开始的秒数(如果不是从这里开始的,可以自行转换,比如SQLServer就是从1900年开始的秒数,而c++一般是从1970年开始的秒数)

输出:常见的时间格式。

原理:利用FILETIME和SYSTEMTIME作为中间媒介。

 

以下是两个时间的结构:

typedef struct _FILETIME {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME, *PFILETIME, *LPFILETIME;

typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *LPSYSTEMTIME;

FILETIME和SYSTEMTIME都只是记录时间的结构。
GetLocalTime能够得到本地电脑设置时区的时间,得到的类型是SYSTEMTIME的类型。

关于SYSTEMTIME不用我多说,一看就明白,只是FILETIME的两个成员有点让人迷糊,其实是由于时间范围的扩大,32位表示不下,必须用64位整数,所以在32位系统中,需要拆分成高低各32位。具体我也不是很清楚哦,总之,看看下面的例子应该就能意会了,如果有能说清楚的大哥大姐,烦请告之,感激不尽。

 

#define PER_SECOND 1*10*1000*1000  /* filetime中代表1秒 */

string myTime2Str(INT64 nTime)

{

char str[100] = "";
ULARGE_INTEGER nTemp;  /* 利用该类型变量来获取高低32位的值 */
SYSTEMTIME tSysTime;
FILETIME tFileTime;
nTemp.QuadPart = nTime * PER_SECOND;
tFileTime.dwHighDateTime = nTemp.HighPart;  /* 赋值给filetime */
tFileTime.dwLowDateTime = nTemp.LowPart;
FileTimeToSystemTime(&tFileTime, &tSysTime);   /* 文件时间转成系统时间 */

sprintf(str, "%04d-%02d-%02d %02d:%02d:%02d",
tSysTime.wYear, tSysTime.wMonth, tSysTime.wDay,
tSysTime.wHour, tSysTime.wMinute, tSysTime.wSecond);
return str;

}

 

最后附上从其他地方看来的参考资料:(地址:http://blog.csdn.net/TracyZhongcf/archive/2009/01/05/3711684.aspx)

 

常用转换函数:
LONG WINAPI CompareFileTime(const FILETIME *lpft1, const FILETIME *lpft2);
BOOL WINAPI FileTimeToSystemTime(const FILETIME *lpft, LPSYSTEMTIME lpst);
BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME *lpst, LPFILETIME lpft);
BOOL WINAPI FileTimeToLocalFileTime(const FILETIME *lpft, LPFILETIME lpftLocal);
BOOL WINAPI LocalFileTimeToFileTime(const FILETIME *lpftLocal, LPFILETIME lpft);

那么,如果使用FILETIME来记录时间,需要加上n秒,如何进行累加计算呢?
#define PER_SECOND 1*10*1000*1000 //1秒

ULONGLONG ullSeconds = n* PER_SECOND;
FILETIME tTime;
ULARGE_INTEGER temp;
temp.QuadPart = ullSeconds;
tTime.dwHighDateTime = temp.HighPart;
tTime.dwLowDateTime = temp.LowPart;

依次类推,1小时就是36000000000;1天就是864000000000

说明:ULARGE_INTEGER 的结构定义如下
typedef union _ULARGE_INTEGER {
struct {
DWORD LowPart;
DWORD HighPart;
};
struct {
DWORD LowPart;
DWORD HighPart;
} u;
#endif //MIDL_PASS
ULONGLONG QuadPart;
} ULARGE_INTEGER;

typedef ULARGE_INTEGER *PULARGE_INTEGER;
可以看到,它是一个64位的联合体,它的空间大小就是64位,当使用QuadPart时等于是以64位的整体来使用的;
而若使用 LowPart和 HighPart时,等于是以高低32位来使用的。
因此,temp.QuadPart = ullSeconds;是给QuadPart赋值,实际上也就是给temp的内存空间赋值了,当然也可以通过LowPart和HighPart分别取出temp的低32位和高32位了。

posted on 2010-03-23 12:27  清豪  阅读(2004)  评论(0编辑  收藏  举报