实现了64位时间戳,可以表示公元1年1月1日零时至9999年12月31日末时之间的时刻,精确到毫秒。
/*-----------------------------------------------------
Author: http://blog.csdn.net/xinghongduo
E-Mail: 317358117@qq.com
Description: 64位时间戳,可以表示的时间范围是
(0001-01-01 00:00:00:000 ~ 9999-12-31 23:59:59:999)
精确到毫秒
------------------------------------------------------*/
#ifndef MY_TIME_H_
#define MY_TIME_H_
#include <windows.h>
typedef __int64 time64;
#define MilSecondPerDay 86400000
class MyTimestamp
{
private:
void parseDateString(char* ,time64**);
time64 transformToTimestamp(time64 ,time64 ,time64 ,time64 ,time64 ,time64 ,time64);
void transformToDate(time64 ,time64**);
time64 getDateTimestamp(int ,int ,int);
public:
time64 getCurrentTimestamp();
time64 transformToTimestamp(char*);
void transformToDateString(time64 ,char*);
long time64ToUnixTime(time64);
time64 unixTimeToTime64(long);
int dateFunction(char* ,char*);
int dateFunction(char* ,time64);
time64 dateAdd(char* ,char* ,int ,char*);
MyTimestamp(){};
~MyTimestamp(){};
};
/*
获得当前时间的时间戳
*/
time64 MyTimestamp::getCurrentTimestamp()
{
SYSTEMTIME t;
time64 year ,month ,day ,hour ,min ,sec ,mil;
GetLocalTime(&t);
year = t.wYear;
month = t.wMonth;
day = t.wDay;
hour = t.wHour;
min = t.wMinute;
sec = t.wSecond;
mil = t.wMilliseconds;
return transformToTimestamp(year ,
month ,day ,
hour ,min ,
sec ,mil );
}
/*
将时间格式字符串转化为时间戳
*/
time64 MyTimestamp::transformToTimestamp(char *dateString)
{
time64 year ,month ,day ,hour ,minute ,second ,milliSecond;
time64 *intp[] = {&year ,&month ,&day ,&hour ,
&minute ,&second ,&milliSecond };
parseDateString(dateString ,intp );
return transformToTimestamp(year ,
month ,day ,
hour ,minute ,
second ,milliSecond );
}
/*
转化为时间戳(内部调用)
*/
time64 MyTimestamp::transformToTimestamp(time64 year ,
time64 month ,time64 day ,
time64 hour ,time64 min ,
time64 sec ,time64 mil )
{
time64 ret;
static time64 daySum[] = {0 ,31 ,59 ,90 ,120 ,151 ,181 ,212 ,243 ,273 ,304 ,334 };
ret = ((year-1)*365 + (year-1)/4 - (year-1)/100 + (year-1)/400) * 24 * 3600;
ret += daySum[month-1] * 24 * 3600;
if(month > 2 && (( (year&3)==0 && year%100!=0) || year%400==0))
ret += 24 * 3600;
ret += ((day-1) * 24 + hour) * 3600 + min * 60 + sec;
return ret * 1000 + mil;
}
/*
将64位时间戳转化为时间字符串
*/
void MyTimestamp::transformToDateString(time64 timeStamp ,char *dateString)
{
time64 year ,month ,day ,hour ,minute ,second ,milliSecond;
time64 *intp[] = {&year ,&month ,&day ,&hour ,
&minute ,&second ,&milliSecond };
transformToDate(timeStamp ,intp);
sprintf(dateString ,"%.4I64d-%.2I64d-%.2I64d %.2I64d:%.2I64d:%.2I64d:%.3I64d" ,
year ,month ,day+1 ,hour ,minute ,second ,milliSecond );
}
/*
将64位时间戳转化为时间数组
*/
void MyTimestamp::transformToDate(time64 timeStamp ,time64 **dateArry)
{
time64 low ,high ,mid ,t;
time64 year ,month ,day ,hour ,minute ,second ,milliSecond;
time64 daySum[] = {0 ,31 ,59 ,90 ,120 ,151 ,181 ,212 ,243 ,273 ,304 ,334 ,365};
time64 milOfDay = 24 * 3600 * 1000;
time64 milOfHour = 3600 * 1000;
/*防止超过9999-12-31 23:59:59:999*/
if(timeStamp > 315537897599999) {
timeStamp = 315537897599999;
}
low = 1;
high = 9999;
while(low <= high)
{
mid = (low+high)>>1;
t = ((mid-1) * 365 + (mid-1)/4 - (mid-1)/100 + (mid-1)/400) * milOfDay;
if(t == timeStamp)
{
low = mid + 1;
break;
}
else if(t < timeStamp)
low = mid + 1;
else
high = mid - 1;
}
year = low-1;
timeStamp -= ((year-1) * 365 + (year-1)/4 - (year-1)/100 + (year-1)/400) * milOfDay;
bool isLeapYear = ((year&3) == 0 && year%100!=0) || year%400 == 0;
for(month = 1 ;(daySum[month] + ((isLeapYear && month > 1) ? 1 : 0)) * milOfDay <= timeStamp && month < 13 ;month ++) {
if(isLeapYear && month > 1)
++daySum[month];
}
timeStamp -= daySum[month-1] * milOfDay;
day = timeStamp / milOfDay;
timeStamp -= day * milOfDay;
hour = timeStamp / milOfHour;
timeStamp -= hour * milOfHour;
minute = timeStamp / 60000;
timeStamp -= minute * 60000;
second = timeStamp / 1000;
milliSecond = timeStamp % 1000;
*dateArry[0] = year;
*dateArry[1] = month;
*dateArry[2] = day;
*dateArry[3] = hour;
*dateArry[4] = minute;
*dateArry[5] = second;
*dateArry[6] = milliSecond;
}
/*
解析形如2013-7-1 10:20:30:550的时间字符串
*/
void MyTimestamp::parseDateString(char *dateString ,time64 **arry)
{
int i;
time64 t;
const char *p = dateString;
for(i = 0 ; i < 7 ;i ++)
*arry[i] = i<3 ? 1 : 0;
for(i = 0 ; i < 7 ;i ++)
{
for(t = 0 ; *p >= '0' && *p <= '9' && *p != '\0' ;++p)
t = t * 10 + *p - 48;
*arry[i] = t;
while( (*p < '0' || *p > '9') && *p != '\0')
++p;
if('\0' == *p)
break;
}
}
/*
将64位时间戳转化为UNIX时间戳
*/
long MyTimestamp::time64ToUnixTime(time64 timeStamp)
{
time64 unixStart = 62135596800000;
if(timeStamp < unixStart) {
timeStamp = unixStart;
}
return (long)((timeStamp-unixStart)/1000);
}
/*
将UNIX时间戳转化为64位时间戳
*/
time64 MyTimestamp::unixTimeToTime64(long unix)
{
time64 unixStart = 62135596800000 ,t = unix;
unixStart += t * 1000;
return unixStart;
}
/*
功能类似SQL Server中的datename函数
type取值范围:
"weekDay" 返回是周几
"weekYear" 返回该年有多少周
*/
int MyTimestamp::dateFunction(char *type ,char *dateString)
{
int cmp_res;
time64 timeStamp = transformToTimestamp(dateString);
return dateFunction(type ,timeStamp);
}
/*
获得year年month月day日0:0:0:0的时间戳
*/
time64 MyTimestamp::getDateTimestamp(int year ,int month ,int day)
{
char dateString[30];
sprintf_s(dateString ,30 ,"%d-%d-%d" ,year ,month ,day);
return transformToTimestamp(dateString);
}
int MyTimestamp::dateFunction(char *type ,time64 timeStamp)
{
int cmp_res;
time64 year ,month ,day ,hour ,minute ,second ,milliSecond;
time64 *intp[] = {&year ,&month ,&day ,&hour ,
&minute ,&second ,&milliSecond };
transformToDate(timeStamp ,intp);
cmp_res = stricmp(type ,"weekday");
if(0 == cmp_res) {
return (timeStamp/MilSecondPerDay)%7+1;
} else {
time64 yStart ,yEnd;
int days ,sWeekday ,eWeekday;
yStart = getDateTimestamp(year ,1 ,1);
yEnd = getDateTimestamp(year ,12 ,31 );
sWeekday = dateFunction("weekday" ,yStart);
eWeekday = dateFunction("weekday" ,yEnd);
days = (yEnd-yStart)/MilSecondPerDay+1;
days -= 8-sWeekday;
return days/7+1;
}
}
/*
时间计算,dateString时间加上add后的日期
type值
DAY
HOUR
MICROSECOND
MINUTE
SECOND
WEEK
*/
time64 MyTimestamp::dateAdd(char *dateString ,char* newDateString ,int add ,char* type)
{
int i;
const char *allType[] = {"day" ,"hour" ,"microsecond" ,"minute" ,"second" ,"week"};
static const time64 addOfType[] = {MilSecondPerDay ,3600000 ,add ,60000 ,1000 ,7*MilSecondPerDay};
time64 timeStamp = 0;
for(i = 0 ;stricmp(allType[i] ,type) && i < 6 ;i ++);
if(i == 6) {
strcpy_s(newDateString ,sizeof("type类型错误!") ,"type类型错误!");
} else {
timeStamp = transformToTimestamp(dateString);
timeStamp += add * addOfType[i];
transformToDateString(timeStamp ,newDateString);
}
return timeStamp;
}
#endif
#include <iostream>
#include "MyTimestamp.h"
using namespace std;
int main(int argc ,char **argv)
{
char dateString[30];
MyTimestamp s;
time64 currentTime ,t2038;
currentTime = s.getCurrentTimestamp();
s.transformToDateString(currentTime ,dateString);
cout<<"当前时间 "<<dateString<<endl;
cout<<"当前时间戳"<<currentTime<<endl;
cout<<"当前时间的UNIX时间戳 "<<s.time64ToUnixTime(currentTime)<<endl;
s.dateAdd(dateString ,dateString ,30 ,"day");
cout<<"当前时间后30天的时间为"<<dateString<<endl;
//2038年问题
t2038 = s.unixTimeToTime64(0x7FFFFFFF);
s.transformToDateString(t2038 ,dateString);
cout<<"UNIX时间戳表示的最大时间 "<<dateString<<endl;
return 0;
}