c中的时间戳,精度为毫秒

mor*_*ten 3 c windows datetime time.h

我对C编程比较陌生,而且我正在开展一个需要非常准确的项目; 因此我尝试写一些东西来创建一个毫秒精度的时间戳.

它似乎有效但我的问题是这种方式是否正确,还是有更简单的方法?这是我的代码:

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

void wait(int milliseconds)
{
    clock_t start = clock();
    while(1) if(clock() - start >= milliseconds) break;
}

int main()
{
    time_t now;
    clock_t milli;
    int waitMillSec = 2800, seconds, milliseconds = 0;
    struct tm * ptm;

    now = time(NULL);
    ptm = gmtime ( &now );
    printf("time before: %d:%d:%d:%d\n",ptm->tm_hour,ptm->tm_min,ptm->tm_sec, milliseconds );

    /* wait until next full second */
    while(now == time(NULL));

    milli = clock();
    /* DO SOMETHING HERE */
    /* for testing wait a user define period */
    wait(waitMillSec);
    milli = clock() - milli;

    /*create timestamp with milliseconds precision */
    seconds = milli/CLOCKS_PER_SEC;
    milliseconds = milli%CLOCKS_PER_SEC;
    now = now + seconds;
    ptm = gmtime( &now );
    printf("time after: %d:%d:%d:%d\n",ptm->tm_hour,ptm->tm_min,ptm->tm_sec, milliseconds );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Jos*_*sey 6

以下代码似乎可能提供毫秒粒度:

#include <windows.h>
#include <stdio.h>

int main(void) {
    SYSTEMTIME t;
    GetSystemTime(&t); // or GetLocalTime(&t)
    printf("The system time is: %02d:%02d:%02d.%03d\n", 
        t.wHour, t.wMinute, t.wSecond, t.wMilliseconds);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这基于http://msdn.microsoft.com/en-us/library/windows/desktop/ms724950%28v=vs.85%29.aspx.上面的代码片段在Windows 7上使用CYGWIN进行了测试.

对于Windows 8,有GetSystemTimePreciseAsFileTime,它"以尽可能高的精度(<1us)检索当前系统日期和时间."

您最初的方法可能是99.99%的时间(忽略一个小错误,如下所述).你的方法是:

  • 等待下一秒开始,重复调用time()直到值发生变化.
  • 保存该值time().
  • 保存值clock().
  • 使用当前值clock()和两个保存的值计算所有后续时间.

你的小错误是你前两步被逆转了.

但即使修复了这个问题,也不能保证100%工作,因为没有原子性.两个问题:

  • 你的代码循环time()直到你进入下一秒.但你到底有多远?它可能是1/2秒,甚至几秒钟(例如,如果您运行带有断点的调试器).

  • 然后你打电话clock().但是这个保存的值必须"匹配"保存的值time().如果这两个电话几乎是瞬间的,就像通常那样,那么这很好.但是Windows(和Linux)的时间片,等都没有保证.

另一个问题是粒度clock.如果CLOCKS_PER_SEC为1000,就像您的系统中的情况一样,那么当然您可以做的最好是1毫秒.但它可能比这更糟糕:在Unix系统上它通常是15毫秒.你可以通过更换改善这种clockQueryPerformanceCounter(),作为答案的timespec等同于Windows,但是这可能是没有用的,因为前两个问题.