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>
答案 0 :(得分:1)
使用VariantTimeToSystemTime
将CSC 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