如何在Linux上以毫秒为单位获取当前时间?
可以使用POSIX clock_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
。
你需要这样做:
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
#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,它会忽略时区,但如果需要,您可以指定一个时区。
@更新 - 时区
由于时间的long
表示与时区本身无关,因此设置gettimeofday()
的tz
参数是不必要的,因为它不会产生任何影响。
根据gettimeofday()
的man页面,使用timezone
结构已经过时,因此tz
参数通常应该指定为NULL,请参阅man页面获取更多详细信息。
gettimeofday()
函数的参数tz
设定为&(struct timezone tz = {480, 0})
不会报错,且不会影响结果,这是有道理的,因为时间的long
表示法与时区本身无关或不受其影响,对吗? - EricNULL
是合理的传递值。并且,我相信测试总是证明事情的好方法。 - EricC11 timespec_get
此函数返回精确到纳秒的时间,取决于实现的分辨率。
Ubuntu 15.10已经实现了该函数。API与 POSIX clock_gettime
相同。
#include <time.h>
struct timespec ts;
timespec_get(&ts, TIME_UTC);
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
此版本无需数学库,并检查clock_gettime()函数的返回值。
#include <time.h>
#include <stdlib.h>
#include <stdint.h>
/**
* @return milliseconds
*/
uint64_t get_now_time() {
struct timespec spec;
if (clock_gettime(1, &spec) == -1) { /* 1 is CLOCK_MONOTONIC */
abort();
}
return spec.tv_sec * 1000 + spec.tv_nsec / 1e6;
}
clock_gettime
),并说明它需要哪些头文件以及它如何回答OP的问题。关于CLOCK_MONOTONIC
,我建议直接在您的答案(以及您的代码)中使用标准宏,而不是字面量。 - PiCTo根据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/1e6);
}
#include <time.h>
long long millis () {
struct timespec t ;
clock_gettime ( CLOCK_REALTIME , & t ) ;
return t.tv_sec * 1000 + ( t.tv_nsec + 500000 ) / 1000000 ;
}
如果您要测量小于50天的时间,32位就足够了。数据类型int在大多数计算机上是32位或64位,因此数据类型可以是unsigned int。
gcc
命令中加入-lm
。 - David Guyons
。这可能是一个罕见事件,但额外的数字可能会引起麻烦。 - Mikespec.tv_nsec
始终小于10亿(因此在四舍五入后,ms永远不会超过1000)。 - Dan Moulding