duilib+win32:對時間的操作
阿新 • • 發佈:2019-01-02
這裡記錄的是對時間的操作,因為專案中用到了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.