这里记录的是对时间的操作,因为项目中用到了duilib的CDateTime控件,然后还有封装了win32的时间控件在项目中,下面记录的是对时间的转换,包括比较时间大小、Js和C++交互的时候时间数据类型的选择、时间的转换等
1.时间的设置
//win32时间控件设置时间和获取时间
SYSTEMTIME m_DateTime;
//获取时间
::SendMessage(m_TimeHwnd, MCM_GETCURSEL, NULL, (LPARAM)&m_DateTime);
//设置时间
::SendMessage(m_TimeHwnd, DTM_SETSYSTEMTIME, 0, (LPARAM)&m_DateTime);
m_TimeHwnd是win32时间控件的句柄(不知道怎么获取的,看我《封装win32控件》的博文)
duilib的时间控件的设置就不多说了,SetTime和GetTime
2.时间的转换
我在项目中主要使用的是SYSTEMTIME 的时间格式
__int64 SystemTimeToInt64(const SYSTEMTIME& itime)
{
FILETIME ft;
SystemTimeToFileTime(&itime, &ft);
ULARGE_INTEGER ularge;
ularge.LowPart = ft.dwLowDateTime;
ularge.HighPart = ft.dwHighDateTime;
__int64 int64 = ularge.QuadPart;
return int64;
}
SYSTEMTIME Int64ToSystemTime(const __int64& itime)
{
FILETIME ft;
SYSTEMTIME st;
ULARGE_INTEGER ularge;
__int64 tmptimeA, tmptimeB;
tmptimeA = itime;
tmptimeB = itime;
ularge.HighPart = (DWORD)(tmptimeA >> 32);
ularge.LowPart = (DWORD)((tmptimeB << 32) >> 32);
ft.dwLowDateTime = ularge.LowPart;
ft.dwHighDateTime = ularge.HighPart;
FileTimeToSystemTime(&ft, &st);
return st;
}
SYSTEMTIME 转成__int64,__int64就是long long数据类型,这样的话我们再转成字符串什么的就好办多了。
3.比较时间大小
BOOL CClockDlg::IsSaveData()
{
SYSTEMTIME sTime1; //系统时间
GetLocalTime(&sTime1);
SYSTEMTIME sTime2;
::SendMessage(m_TimeHwnd, MCM_GETCURSEL, NULL, (LPARAM)&sTime2);
SYSTEMTIME chooseTime = m_pDateTimeUI->GetTime();
chooseTime.wHour = sTime2.wHour;
chooseTime.wMinute = sTime2.wMinute;
chooseTime.wSecond = sTime2.wSecond;
/*CDuiString str;
str.Format(L"%d %d %d %d %d %d", chooseTime.wYear, chooseTime.wMonth, chooseTime.wDay, chooseTime.wHour, chooseTime.wMinute, chooseTime.wSecond);
MessageBox(NULL, str, L":wwwww", NULL);*/
ULARGE_INTEGER fTime1;/*FILETIME*/
ULARGE_INTEGER fTime2;/*FILETIME*/
SystemTimeToFileTime(&sTime1, (FILETIME*)&fTime1);
SystemTimeToFileTime(&chooseTime, (FILETIME*)&fTime2);
//两个时间相等,就返回零;如lpFileTime1小于lpFileTime2,返回 - 1;如lpFileTime2小于lpFileTime1,返回1
if (CompareFileTime((FILETIME*)&fTime1, (FILETIME*)&fTime2) == -1)
{
MessageBox(NULL, L"1<2", L"sss", NULL);
m_DateTime = chooseTime;
return TRUE;
}
if (CompareFileTime((FILETIME*)&fTime1, (FILETIME*)&fTime2) == 1)
{
MessageBox(NULL, L"1>2", L"sss", NULL);
return FALSE;
}
return FALSE;
}
主要是要把SYSTEMTIME类型转换成FILETIME类型,才能比较大小
4.与js交互时间类型的选择
在因为需要程序和网页交互,网页那边主要是和js交互,js传过来时间,一开始叫网页那边传过来准确时间的字符串,C++拿到手之后在进行拆分,发现不容易控制,因为会月、时、分、秒都有小于的0的情况,这种太麻烦了。最终选择了Unix时间戳的方式。
我这获取的时间戳单位是秒,不过还有毫秒的,这里用把__int64类型转成struct tm,然后再把数据给SYSTEMTIME ,多了一步
struct tm tm = *localtime((time_t *)&m_DateTimeFromLine);
m_DateTime.wYear = tm.tm_year + 1900; //__int64转成正常时间年要+1900,月要+1
m_DateTime.wMonth = tm.tm_mon + 1;
m_DateTime.wDay = tm.tm_mday;
m_DateTime.wHour = tm.tm_hour;
m_DateTime.wMinute = tm.tm_min;
m_DateTime.wSecond = tm.tm_sec;
这里要强调的是时间戳是从1970年开始的,转换的时候要年要+1900,月+1,才会对。(m_DateTimeFromLine是__int64类型,m_DateTime是SYSTEMTIME 类型)
从js那里获取的时间是毫秒
std::tm* gettm(int64 timestamp)
{
int64 milli = timestamp+ (int64)8*60*60*1000;//此处转化为东八区北京时间,如果是其它时区需要按需求修改
auto mTime = std::chrono::milliseconds(milli);
auto tp=std::chrono::time_point<std::chrono::system_clock,std::chrono::milliseconds>(mTime);
auto tt = std::chrono::system_clock::to_time_t(tp);
std::tm* now = std::gmtime(&tt);
printf("%4d年%02d月%02d日 %02d:%02d:%02d\n",now->tm_year+1900,now->tm_mon+1,now->tm_mday,now->tm_hour,now->tm_min,now->tm_sec);
return now;
}
5.C++获取时间戳
std::time_t getTimeStamp()
{
std::chrono::time_point<std::chrono::system_clock,std::chrono::milliseconds> tp = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
auto tmp=std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
std::time_t timestamp = tmp.count();
//std::time_t timestamp = std::chrono::system_clock::to_time_t(tp);
return timestamp;
}
struct tm时间戳
虽然SYSTEMTIME和struct tm都可以跟__int64相互转换,但是两者的数据却不能互通,SYSTEMTIME的时间转成__int64 并不是时间戳了.这是是写下将格式化好的时间(2017-11-16 18:00:00)转成__int64形式的
struct tm *sTime = new struct tm;
swscanf(Datetime.GetData(), L"%d-%d-%d %d:%d:%d", &sTime->tm_year, &sTime->tm_mon, &sTime->tm_mday, &sTime->tm_hour, &sTime->tm_min, &sTime->tm_sec);
sTime->tm_year -= 1900; /*年份值减去1900,得到tm结构中保存的年份序数*/
sTime->tm_mon -= 1; /*月份值减去1,得到tm结构中保存的月份序数*/
__int64 datetime = mktime(sTime);//mktime转换时间
delete sTime; //注意delete
以上就是我对时间的操作,有什么问题留言或者QQ:839505138.