获得开机时间精度问题

#include "stdafx.h"
#include <time.h>
#include <sys/timeb.h>
#include <Windows.h>


int _tmain(int argc, _TCHAR* argv[])
{
while(1)
{
Sleep(1);

long long time_last;
time_last = time(NULL);
struct timeb t1;
ftime(&t1);

long long lStartTime = t1.time * 1000 + t1.millitm;
unsigned long lTick = GetTickCount();
lStartTime = lStartTime - lTick;

//开机总毫秒数
printf(_T("lStartTime=%lld\n"), lStartTime);

}

return 0;

}


每次得到的值都会有+-10ms, 有什么好办法让lStartTime误差在1ms以下呢
...全文
182 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
勤奋的小游侠 2014-10-16
  • 打赏
  • 举报
回复
引用 2 楼 tuoerr 的回复:
[quote=引用 1 楼 lovesmiles 的回复:] 没看懂你的代码是怎么获得开机时间的。
//获得系统时间 long long lStartTime = t1.time * 1000 + t1.millitm; //获得系统运行时间 unsigned long lTick = GetTickCount(); //得到开机时间 lStartTime = lStartTime - lTick; [/quote] GetTickCount();的精度是毫秒级的,用它来做运算应该达不到毫秒级的。 你应该考虑一下更高精度的函数
赵4老师 2014-10-16
  • 打赏
  • 举报
回复
Windows计时精度≈15ms
#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
//
  • 打赏
  • 举报
回复
引用 1 楼 lovesmiles 的回复:
没看懂你的代码是怎么获得开机时间的。
//获得系统时间 long long lStartTime = t1.time * 1000 + t1.millitm; //获得系统运行时间 unsigned long lTick = GetTickCount(); //得到开机时间 lStartTime = lStartTime - lTick;
勤奋的小游侠 2014-10-16
  • 打赏
  • 举报
回复
没看懂你的代码是怎么获得开机时间的。

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧