我需要获得一个毫秒级的时间戳。我发现了诸如使用timeval结构和调用gettimeofday之类的选项。问题在于所有结构中都包含长变量,而我只能使用32位变量。
如何仅使用32位变量获取时间戳(在c中)?
答案 0 :(得分:1)
This site 通常是与时间和时钟相关的编程的很好参考,包括函数原型,结构定义以及与您的请求相关的编程示例。你应该看看。
here 中有一些答案可能适合您的需求。可接受的答案是通用的:
对于32位系统:
fprintf(stdout, "%u\n", (unsigned)time(NULL)); )_
此 answer for the same question ,专门解决了我们的分辨率。但是,它是POSIX特定的,并且可能违反您的规范。 :
#include <stdio.h>
#include <time.h>
#include <stdint.h>
#include <inttypes.h>
int main(void) {
struct timespec tms;
/* The C11 way */
/* if (! timespec_get(&tms, TIME_UTC)) { */
/* POSIX.1-2008 way */
if (clock_gettime(CLOCK_REALTIME,&tms)) {
return -1;
}
/* seconds, multiplied with 1 million */
int64_t micros = tms.tv_sec * 1000000;
/* Add full microseconds */
micros += tms.tv_nsec/1000;
/* round up if necessary */
if (tms.tv_nsec % 1000 >= 500) {
++micros;
}
printf("Microseconds: %"PRId64"\n",micros);
return 0;
}
答案 1 :(得分:0)
如果struct timeval
字段是32位格式的long
整数格式(可以是或不能),则是因为您需要具有该大小。一些分析:我以NTP格式获取此时间戳,并在系统上将其转换为struct timeval
格式(用于 now 时间戳):
ntpts.c:120:process: NTP(dec): 3771731346.612550000
ntpts.c:121:process: NTP(hex): 0xe0d00d92.9cd013a9
ntpts.c:123:process: UNIX: 1562742546/0x5d258f12
ntpts.c:135:process: gmtime: 10/jul/2019, 07:09:06.612550000
ntpts.c:136:process: localtime: 10/jul/2019, 10:09:06.612550000
tv_sec ==> 1562742546
tv_usec ==> 612550
因此,要获得具有该分辨率的单个时间戳(自1970年1月1日00:00h起的秒数,以毫秒为单位),则至少需要52位(好,通常tv_sec
是{{1} }或long
long
64位字段,因为2038年2月将发生溢出,并且某些系统已经对此进行了修补),long
可能适合24位变量( usec从0到999999,因此它们至少需要20位),但是编译器填充将使其至少达到32位大小。
如果要保留32位的完整usec分辨率,则至少需要20位来表示几分之一秒,而只有12位来表示整数部分。在这种情况下,您将只能表示从0到4095的秒数,这表示一个多小时(01h8m16s)。这可以处理,但是要使该时间戳记为绝对值,则需要引用该时间戳记属于历史记录中的绝对小时数。
另一方面,如果将粒度减小到毫秒,则可以获得超过1000小时的参考窗口,您需要考虑这一点,以便最终决定下一步要做什么。
顺便说一下,tv_usec
系统调用实际上已被弃用。当今几乎所有正在使用的系统都使用gettimeofday(2)
系统调用,该系统调用具有纳秒级的分辨率,并允许您选择适当的系统时钟来获取时间戳。