如何将Windows DATE转换为c ++中的Unix时间

时间:2016-10-24 04:35:59

标签: c++ date winapi com unix-timestamp

Windows使用DATE类型来表示日期。这是一个double值,表示自1899年12月30日午夜以来的天数。

如何将DATE转换为Unix时间戳(自1970年1月1日以来的秒数)值?

具体来说,如何仅使用c ++标准库以及MinGW为其分发头文件的Windows库来实现这一目标?

例如,我可以从IShellFolder2获取日期属性:

void MyFunc(IShellFolder2 *folder, PCUITEMID_CHILD pidl, const SHCOLUMNID *columnid) {
    VARIANT* v = (VARIANT*) malloc(sizeof(VARIANT));
    DATE d;
    HRESULT hr = folder->GetDetailsEx(pidl, colid, v);
    if (SUCCEEDED(hr)) {
        hr = VariantChangeType(v, v, 0, VT_DATE);
        if (SUCCEEDED(hr)) {
             d = v->date;
        }
        VariantClear(v);
    }
    free(v);
    // process date here
}

如何转换此值以用于使用Unix时间戳格式的软件?

当前使用的头文件(与此特定问题无关):

#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <propkey.h>
#include <wchar.h>
#include <shlguid.h>
#include <string>
#include <vector>

1 个答案:

答案 0 :(得分:1)

使用VariantTimeToSystemTimeCSC 101 A转换为DATE

SYSTEMTIME转换为unix时间是一项简单的任务。

在Visual Studio中,您可以使用SYSTEMTIME,但在MinGW中不可用

COleDateTime

用法:

#include <Windows.h>
#include <stdio.h>
#include <time.h>
#include <OleAuto.h>

unsigned int unix_stamp_of_DATE(DATE date)
{
    //convert DATE to SYSTEMTIME
    SYSTEMTIME st;
    VariantTimeToSystemTime(date, &st);

    //convert SYSTEMTIME to FILETIME 
    FILETIME ft;
    SystemTimeToFileTime(&st, &ft);

    //convert FILETIME to ULARGE_INTEGER
    //then QuadPart is 64bit timestamp
    ULARGE_INTEGER ul{ ft.dwLowDateTime, ft.dwHighDateTime };
    return (unsigned int)((ul.QuadPart - 116444736000000000ULL)/10000000);
}

说明:int main() { DATE dt = 25569.000000f; //1970, 1, 1 time_t rawtime = unix_stamp_of_DATE(dt); tm *timeinfo = gmtime(&rawtime); //DATE was UTC! char buf[50]; strftime(buf, sizeof(buf), "%c", timeinfo); printf("%s\n", buf); return 0; } unix_epoch,计算方式为

116444736000000000U

替代方法

ULARGE_INTEGER unix_epoch{ 0 };
FILETIME ft;
SYSTEMTIME st = { 0 };
st.wDay = 1;
st.wMonth = 1;
st.wYear = 1970;
SystemTimeToFileTime(&st, &ft);
unix_epoch = ULARGE_INTEGER{ ft.dwLowDateTime, ft.dwHighDateTime };
//=116444736000000000U