如何在Linux中从C获取当前时间(以毫秒为单位)?


Answers:


100

这可以使用POSIXclock_gettime功能来实现。

在POSIX的当前版本,gettimeofday标记为已过时。这意味着它可能会从规范的将来版本中删除。鼓励应用程序编写者使用clock_gettime函数而不是gettimeofday

这是一个使用方法的例子clock_gettime

#define _POSIX_C_SOURCE 200809L

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

void print_current_time_with_ms (void)
{
    long            ms; // Milliseconds
    time_t          s;  // Seconds
    struct timespec spec;

    clock_gettime(CLOCK_REALTIME, &spec);

    s  = spec.tv_sec;
    ms = round(spec.tv_nsec / 1.0e6); // Convert nanoseconds to milliseconds
    if (ms > 999) {
        s++;
        ms = 0;
    }

    printf("Current time: %"PRIdMAX".%03ld seconds since the Epoch\n",
           (intmax_t)s, ms);
}

如果您的目标是测量经过的时间,并且系统支持“单调时钟”选项,则应考虑使用CLOCK_MONOTONIC而不是CLOCK_REALTIME


7
为POSIXly正确而+1,但是答案的单位错误。OP不需要时间(毫秒为单位),而是时间毫秒为单位。
pilcrow

5
良好的解决方案,但不要忘了-lm在你的gcc命令。
David Guyon 2014年

2
根据回合的联机帮助页,在将结果分配给整数(或长整数)时,您要使用lround
hildred

2
您需要使用floor()而不是round(),以便它永远不会舍入到1000毫秒。否则s,这种情况发生时您将需要增加。可能是罕见的事件,但多余的数字可能会引起麻烦。
Mike

1
@Mike不错。达到千分之一的比例并不是什么稀罕的事,因此一定要解决。而不是用楼,我想我宁愿保持多一点的准确性,继续圆的,而是递增第二计数器,如果它向上舍入为1000
丹成型

58

您必须执行以下操作:

struct timeval  tv;
gettimeofday(&tv, NULL);

double time_in_mill = 
         (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000 ; // convert tv_sec & tv_usec to millisecond

33

以下是util函数,以毫秒为单位获取当前时间戳:

#include <sys/time.h>

long long current_timestamp() {
    struct timeval te; 
    gettimeofday(&te, NULL); // get current time
    long long milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; // calculate milliseconds
    // printf("milliseconds: %lld\n", milliseconds);
    return milliseconds;
}

关于时区

gettimeofday()支持指定时区,我使用NULL,它忽略时区,但是如果需要,您可以指定时区。


@Update-时区

由于long时间的表示与时区本身无关或不受其影响,因此tz没有必要设置gettimeofday()的参数,因为它不会有任何区别。

并且,根据的手册gettimeofday(),该timezone结构的使用已过时,因此tz通常应将参数指定为NULL,有关详细信息,请检查手册页。


1
> gettimeofday()支持指定时区,我使用NULL,它会忽略时区,但是如果需要,您可以指定时区。你错了。时区应仅通过调用localtime()来引入。
vitaly.v.ch

@ vitaly.v.ch我做了一个测试,通过as的tz参数不会得到任何警告,并且它对结果没有任何影响,这是有道理的,因为时间的表示与时间无关或没有影响按时区本身,对吗?gettimeofday()&(struct timezone tz = {480, 0})long
艾瑞克·王

没有理由进行任何测试。Linux内核没有有关时区的适当信息,同时也没有提供该信息的方法。这就是为什么以非常特定的方式处理tz参数的原因。长时间代表并不重要。
vitaly.v.ch

@ vitaly.v.ch在特定的时间点,长时间表示不会因时区而变化,这就是为什么如此重要,并且通常NULL来说,合理的值是可以传递的。而且,我相信测试始终是证明事物的好方法。
Eric Wang



0

来自Dan Moulding的POSIX答案,这应该可以工作:

#include <time.h>
#include <math.h>

long millis(){
    struct timespec _t;
    clock_gettime(CLOCK_REALTIME, &_t);
    return _t.tv_sec*1000 + lround(_t.tv_nsec/1.0e6);
}

也正如David Guyon指出的那样:使用-lm进行编译

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.