我需要以最快的方式来获取本地时间(因此考虑当前时区)至少以毫秒为单位的精度,如果可以在十分之一毫秒内获得更好的效果。
我想避免使用gettimeofday()
,因为它现在是一个过时的功能。
所以,似乎我需要使用clock_gettime(CLOCK_REALTIME, ...)
并将小时调整到当前时区,但是如何?最好的点在哪里?在使用clock_gettime存储时间戳之前,或者之前在当前时区的格里高利历中转换它?
编辑:我的原始样本加入了get_clock和localtime - 有更好的方法可以达到这个目标吗?
#include <time.h>
#include <stdio.h>
int main() {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
struct tm* ptm;
ptm = localtime(&(ts.tv_sec));
// Tenths of milliseconds (4 decimal digits)
int tenths_ms = ts.tv_nsec / (100000L);
printf("%04d-%02d-%02d %02d:%02d:%02d.%04d\n",
1900 + ptm->tm_year, ptm->tm_mon + 1, ptm->tm_mday,
ptm->tm_hour, ptm->tm_min, ptm->tm_sec, tenths_ms);
}
答案 0 :(得分:3)
我认为没有比clock_gettime()
和localtime()
更好的方法了。但是,您需要正确舍入返回的纳秒,并考虑将时间舍入到下一秒的情况。要格式化时间,您可以使用strftime()
而不是手动格式化tm
结构:
#include <time.h>
#include <stdio.h>
int main(void) {
struct timespec ts;
long msec;
int err = clock_gettime(CLOCK_REALTIME, &ts);
if (err) {
perror("clock_gettime");
return 1;
}
// round nanoseconds to milliseconds
if (ts.tv_nsec >= 999500000) {
ts.tv_sec++;
msec = 0;
} else {
msec = (ts.tv_nsec + 500000) / 1000000;
}
struct tm* ptm = localtime(&ts.tv_sec);
if (ptm == NULL) {
perror("localtime");
return 1;
}
char time_str[sizeof("1900-01-01 23:59:59")];
time_str[strftime(time_str, sizeof(time_str),
"%Y-%m-%d %H:%M:%S", ptm)] = '\0';
printf("%s.%03li\n", time_str, msec);
}
答案 1 :(得分:2)
是的,这可以使用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_in_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
printf("Current time: %"PRIdMAX".%03ld seconds since the Epoch\n",
(intmax_t)s, ms);
}
如果您的目标是测量经过的时间,并且您的系统支持&#34;单调时钟&#34;选项,那么您应该考虑使用CLOCK_MONOTONIC
而不是CLOCK_REALTIME
。
还有一点,记得在尝试编译代码时包含-lm
标志。
要获取时区,请执行以下操作:
#define _GNU_SOURCE /* for tm_gmtoff and tm_zone */
#include <stdio.h>
#include <time.h>
int main(void)
{
time_t t = time(NULL);
struct tm lt = {0};
localtime_r(&t, <);
printf("Offset to GMT is %lds.\n", lt.tm_gmtoff);
printf("The time zone is '%s'.\n", lt.tm_zone);
return 0;
}
注意: time()
返回的纪元以来的秒数就像在GMT(格林威治标准时间)中一样进行衡量。