1. 程式人生 > >duilib+win32:對時間的操作

duilib+win32:對時間的操作

這裡記錄的是對時間的操作,因為專案中用到了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.