69,374
社区成员
发帖
与我相关
我的任务
分享
BOOL TickCountToSystemTime(DWORD dwTickCount, SYSTEMTIME *lpst)
{
if (lpst != NULL) {
DWORD dwCurrTick = GetTickCount();
if (dwCurrTick >= dwTickCount) {
FILETIME ft = { 0 };
SYSTEMTIME st = { 0 };
GetLocalTime(&st);
if (SystemTimeToFileTime(&st, &ft)) {
ULARGE_INTEGER ullt = { 0 };
ULONGLONG ullElapsed = (ULONGLONG)(dwCurrTick - dwTickCount) * 10000ULL;
ullt.LowPart = ft.dwLowDateTime;
ullt.HighPart = ft.dwHighDateTime;
ullt.QuadPart -= ullElapsed;
ft.dwLowDateTime = ullt.LowPart;
ft.dwHighDateTime = ullt.HighPart;
return FileTimeToSystemTime(&ft, lpst);
}
}
}
return FALSE;
}
#pragma comment(lib,"ntdll")
#pragma comment(lib,"user32")
#include <afxdisp.h>
#include <windows.h>
#include <winnt.h>
#include <stdio.h>
#include <memory.h>
#include <math.h>
typedef struct tagLASTINPUTINFO {
UINT cbSize;
DWORD dwTime;
} LASTINPUTINFO, * PLASTINPUTINFO;
extern "C" BOOL WINAPI GetLastInputInfo(PLASTINPUTINFO plii);
LASTINPUTINFO lii;
BOOL r;
extern "C" NTSYSAPI NTAPI NtQuerySystemInformation(
IN UINT SystemInformationClass, // 信息类型
OUT PVOID SystemInformation, // 缓冲指针
IN ULONG SystemInformationLength, // 缓冲的字节大小
OUT PULONG ReturnLength OPTIONAL // 写入缓冲的字节数
);
//第一个参数是请求的信息类型。这个参数可以有许多值。为了得到系统启动时间,我们只用其中的一个值:SystemTimeInformation(3)。
//如果,第一个参数是SystemTimeInformation,则第二个参数必须是一个SYSTEM_TIME_INFORMATION结构指针。
typedef struct {
LARGE_INTEGER liKeBootTime;//系统被启动的时间(以1/10000毫秒计)。
LARGE_INTEGER liKeSystemTime;
LARGE_INTEGER liExpTimeZoneBias;
ULONG uCurrentTimeZoneId;
DWORD dwReserved;
} SYSTEM_TIME_INFORMATION;
SYSTEM_TIME_INFORMATION sti;
ULONG rl;
ULONG tk;
FILETIME ft;
//SYSTEMTIME lt;
//extern "C" ULONGLONG WINAPI GetTickCount64(void);
//ULONGLONG tk64;
ULONGLONG d497;
#define days_of_2_32ms 49.71026962962962962962962962963 //(2^32)/24/60/60/1000=49.71026962962962962962962962963
int main() {
lii.cbSize=sizeof(LASTINPUTINFO);
r=GetLastInputInfo(&lii);
if (r) {
// printf("OK to GetLastInputInfo:dwTime==%d ms\n",lii.dwTime);
NtQuerySystemInformation(3,&sti,sizeof(sti),&rl);//3==SystemTimeOfDayInformation
// printf("NtQuerySystemInformation(SystemTimeOfDayInformation,...) return liKeBootTime==%I64u ms\n",*((unsigned __int64 *)&sti.liKeBootTime)/10000ui64);
COleDateTime t,now;
COleDateTimeSpan ts;
CString s,fmt="%Y-%m-%d %H:%M:%S";
memcpy(&ft,&sti.liKeBootTime,sizeof(LARGE_INTEGER));
t=COleDateTime(ft);
now=COleDateTime::GetCurrentTime();
ts=now-t;
d497=(1ui64<<32)*(unsigned __int64)floor(ts.GetTotalDays()/days_of_2_32ms);
s=t.Format(fmt);
printf(" BootDateTime: %s.%03I64u\n",s,*((unsigned __int64 *)&ft)/10000ui64%1000ui64);
*((unsigned __int64 *)&ft)+=((unsigned __int64)(lii.dwTime)+d497)*10000ui64;
t=COleDateTime(ft);
s=t.Format(fmt);
printf("LastInputDateTime: %s.%03I64u\n",s,*((unsigned __int64 *)&ft)/10000ui64%1000ui64);
// 这样显示的当前时间的毫秒数不会大于LastInputDateTime;但开机超过49.7天时不精确。
// 但The elapsed time is stored as a DWORD value. Therefore, the time will wrap around to zero if the system is run continuously for 49.7 days.
// 如果系统支持的话(Windows Vista/Windows Server 2008),可以调用ULONGLONG GetTickCount64(void)
tk=GetTickCount();//tk64=GetTickCount64();
memcpy(&ft,&sti.liKeBootTime,sizeof(LARGE_INTEGER));
*((unsigned __int64 *)&ft)+=((unsigned __int64)tk+d497)*10000ui64;//tk64*10000ui64
t=COleDateTime(ft);
s=t.Format(fmt);
printf(" NowDateTime: %s.%03I64u\n",s,*((unsigned __int64 *)&ft)/10000ui64%1000ui64);
// 这样显示的当前时间的毫秒数会大于LastInputDateTime;但开机超过49.7天时不会不精确。
// GetLocalTime(<);
// printf(" NowDateTime: %4d-%02d-%02d %02d:%02d:%02d.%03d\n",lt.wYear,lt.wMonth,lt.wDay,lt.wHour,lt.wMinute,lt.wSecond,lt.wMilliseconds);
Sleep(15);//延迟15毫秒,方便在外部批处理脚本中循环调用
} else {
printf("Fail to GetLastInputInfo!\n");
return 1;
}
return 0;
}
// BootDateTime: 2014-04-17 08:45:30.375
//LastInputDateTime: 2014-04-17 17:18:38.843
// NowDateTime: 2014-04-17 17:18:38.859
//
// FILETIME 从1601年1月1日起的100纳秒数
// 100-nanosecond=100*1/1,000,000,000=1/10,000,000秒
// GetTickCount() 从系统启动后开始计算的毫秒数
// milisecond=1/1,000秒
BOOL TickCountToSystemTime(DWORD dwTickCount, SYSTEMTIME *lpst)
{
if (lpst != NULL) {
DWORD dwCurrTick = GetTickCount();
if (dwCurrTick >= dwTickCount) {
FILETIME ft = { 0 };
SYSTEMTIME st = { 0 };
GetLocalTime(&st);
if (SystemTimeToFileTime(&st, &ft)) {
ULARGE_INTEGER ullt = { 0 };
ULONGLONG ullElapsed = (ULONGLONG)(dwCurrTick - dwTickCount) * 10000ULL;
ullt.LowPart = ft.dwLowDateTime;
ullt.HighPart = ft.dwHighDateTime;
ullt.QuadPart -= ullElapsed;
return FileTimeToSystemTime(&ft, lpst);
}
}
}
return FALSE;
}
// 使用
SYSTEMTIME st = { 0 };
if (TickCountToSystemTime(msg.time, &st)) {
// MFC - CString
CString strDateTime;
strDateTime.Format("%04u-%02u-%02u %02u:%02u:%02u", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
// 或 C 字符串
char szDateTime[1024];
wsprintf(szDateTime, "%04u-%02u-%02u %02u:%02u:%02u", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
}
FILETIME ft;
GetSystemTimeAsFileTime(&ft); //前两行获得当前时间
*(ULONGLONG)&ft -= ULONGLONG(GetTickCount() - dwTime) * 10000;//用当前时间减去相当单位的TickCount-dwTime
这样的代码#include <stdio.h>
#include <string.h>
#include <time.h>
#include <time.h>
#include <sys/timeb.h>
struct tm st;
time_t tt;
char mon[4];
char mn[12][4]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
int i;
char timstr[27];
char tmpbuf[128];
struct _timeb tb;
int tz;
char c;
void main() {
strcpy(timstr,"08/Dec/2011:15:25:03 +0800");
sscanf(timstr,"%2d/%3s/%4d:%2d:%2d:%2d",&st.tm_mday,mon,&st.tm_year,&st.tm_hour,&st.tm_min,&st.tm_sec);
for (i=0;i<12;i++) if (0==stricmp(mn[i],mon)) {st.tm_mon=i; break;}
st.tm_year-=1900;
tt=mktime(&st);
if (-1!=tt) {
strftime(tmpbuf,128,"%Y-%m-%d %H:%M:%S\n",localtime(&tt));
printf(tmpbuf);//2011-12-08 15:25:03
} else {
printf("[%s] is Invalid time string!\n",timstr);
}
_ftime(&tb);
strftime(tmpbuf,128,"%m/%b/%Y:%H:%M:%S",localtime(&tb.time));
tz=-tb.timezone;
c=(tz>0)?'+':'-';
tz=(tz>0)?tz:-tz;
sprintf(tmpbuf,"%s %c%02d%02d\n",tmpbuf,c,tz/60,tz%60);
printf(tmpbuf);//12/Dec/2011:17:36:41 +0800
}