如何在不将秒数乘以 1000 的情况下获得自 C 中的 unix 纪元以来经过的毫秒数?
How to get milliseconds passed since unix epoch in C without multiplying seconds by 1000?
我唯一知道的是 time(NULL)
,但自 1970 年以来已经 return 秒了。
如果 C 没有所需的函数,我可以使用 WinApi 函数。
我什至找到了 GetLocalTime
WinApi 函数,但它 return 当前日期时间作为结构...
我不想将秒乘以 1000 的原因是因为我将我的代码注入到某个程序中,并且我的代码用于从两个源捕获某些事件,我需要知道它们的确切时间,因为如果这两个事件自 1970 年以来发生在相同的秒数,但不同的毫秒数,然后对我来说它们似乎同时发生,并且很难确定先发生了什么(我稍后进行事件排序......)
这是 WinApi 确定自 1970 年以来经过的毫秒数的方法。
我做到了,因为没有人用原生 C 方式提供答案(也许根本没有原生方式)...
SYSTEMTIME unix_epoch;
unix_epoch.wYear = 1970;
unix_epoch.wMonth = 1;
unix_epoch.wDay = 1;
unix_epoch.wDayOfWeek = 4;
unix_epoch.wHour = 0;
unix_epoch.wMilliseconds = 0;
unix_epoch.wMinute = 0;
unix_epoch.wSecond = 0;
FILETIME curr_time_as_filetime;
GetSystemTimeAsFileTime(&curr_time_as_filetime);
FILETIME unix_epoch_as_filetime;
SystemTimeToFileTime(&unix_epoch, &unix_epoch_as_filetime);
ULARGE_INTEGER curr_time_as_uint64;
ULARGE_INTEGER unix_epoch_as_uint64;
curr_time_as_uint64.HighPart = curr_time_as_filetime.dwHighDateTime;
curr_time_as_uint64.LowPart = curr_time_as_filetime.dwLowDateTime;
unix_epoch_as_uint64.HighPart = unix_epoch_as_filetime.dwHighDateTime;
unix_epoch_as_uint64.LowPart = unix_epoch_as_filetime.dwLowDateTime;
ULARGE_INTEGER milliseconds_since_1970;
milliseconds_since_1970.QuadPart = (curr_time_as_uint64.QuadPart - unix_epoch_as_uint64.QuadPart) / 10000;
另一种方法是在程序开始时将 clock() 与 time(NULL) 结合使用
start_time = time(NULL)
....
clock() + start_time * CLOCKS_PER_SEC
这会给你一个更好的估计,也许足够精确以满足你的需要?
在 Unix 中,你有(可能你会得到其中一些 api 也可以在 windows 中工作)gettimeofday(2)
,这是 BSD 实现的时间,它基于 struct timeval
这是一个 struct
,有两个字段,tv_sec
(自纪元以来的秒数,由 time(2)
给出)和 tv_usec
(以微秒为单位的时间,作为整数,在 0
和 999999
)
之间
这足以满足您的要求,但今天,通常使用 Posix' 调用 clock_gettime(2)
,它允许您 select 您想要的时间类型(挂钟时间,cpu时间等)clock_gettime(2)
使用类似的struct timespec
(这次它有tv_sec
和tv_nsec
---nanosecond-- - 分辨率)
没有时钟可以保证获得纳秒分辨率(但有人可以),但至少你达到了微秒级别,这比你想要的要多)
为了能够以毫秒为单位给出时间,您只需将 tv_sec
乘以 1000
,然后加上 tv_usec
(如果使用 gettimeofday()
) 值除以 1000
。或者,如果您更喜欢使用 clock_gettime()
,您将添加 tv_sec
字段乘以 1000
,然后添加 tv_nsec
字段除以 1000000
。
如果只需要比较哪个时间戳早,可以只比较两个tv_sec
字段,如果正好相等,再比较tv_usec
字段。我所知道的每个 unix(SCO UNIX 除外)都实现了 gettimeofday()
微秒分辨率。
我唯一知道的是 time(NULL)
,但自 1970 年以来已经 return 秒了。
如果 C 没有所需的函数,我可以使用 WinApi 函数。
我什至找到了 GetLocalTime
WinApi 函数,但它 return 当前日期时间作为结构...
我不想将秒乘以 1000 的原因是因为我将我的代码注入到某个程序中,并且我的代码用于从两个源捕获某些事件,我需要知道它们的确切时间,因为如果这两个事件自 1970 年以来发生在相同的秒数,但不同的毫秒数,然后对我来说它们似乎同时发生,并且很难确定先发生了什么(我稍后进行事件排序......)
这是 WinApi 确定自 1970 年以来经过的毫秒数的方法。 我做到了,因为没有人用原生 C 方式提供答案(也许根本没有原生方式)...
SYSTEMTIME unix_epoch;
unix_epoch.wYear = 1970;
unix_epoch.wMonth = 1;
unix_epoch.wDay = 1;
unix_epoch.wDayOfWeek = 4;
unix_epoch.wHour = 0;
unix_epoch.wMilliseconds = 0;
unix_epoch.wMinute = 0;
unix_epoch.wSecond = 0;
FILETIME curr_time_as_filetime;
GetSystemTimeAsFileTime(&curr_time_as_filetime);
FILETIME unix_epoch_as_filetime;
SystemTimeToFileTime(&unix_epoch, &unix_epoch_as_filetime);
ULARGE_INTEGER curr_time_as_uint64;
ULARGE_INTEGER unix_epoch_as_uint64;
curr_time_as_uint64.HighPart = curr_time_as_filetime.dwHighDateTime;
curr_time_as_uint64.LowPart = curr_time_as_filetime.dwLowDateTime;
unix_epoch_as_uint64.HighPart = unix_epoch_as_filetime.dwHighDateTime;
unix_epoch_as_uint64.LowPart = unix_epoch_as_filetime.dwLowDateTime;
ULARGE_INTEGER milliseconds_since_1970;
milliseconds_since_1970.QuadPart = (curr_time_as_uint64.QuadPart - unix_epoch_as_uint64.QuadPart) / 10000;
另一种方法是在程序开始时将 clock() 与 time(NULL) 结合使用
start_time = time(NULL)
....
clock() + start_time * CLOCKS_PER_SEC
这会给你一个更好的估计,也许足够精确以满足你的需要?
在 Unix 中,你有(可能你会得到其中一些 api 也可以在 windows 中工作)gettimeofday(2)
,这是 BSD 实现的时间,它基于 struct timeval
这是一个 struct
,有两个字段,tv_sec
(自纪元以来的秒数,由 time(2)
给出)和 tv_usec
(以微秒为单位的时间,作为整数,在 0
和 999999
)
这足以满足您的要求,但今天,通常使用 Posix' 调用 clock_gettime(2)
,它允许您 select 您想要的时间类型(挂钟时间,cpu时间等)clock_gettime(2)
使用类似的struct timespec
(这次它有tv_sec
和tv_nsec
---nanosecond-- - 分辨率)
没有时钟可以保证获得纳秒分辨率(但有人可以),但至少你达到了微秒级别,这比你想要的要多)
为了能够以毫秒为单位给出时间,您只需将 tv_sec
乘以 1000
,然后加上 tv_usec
(如果使用 gettimeofday()
) 值除以 1000
。或者,如果您更喜欢使用 clock_gettime()
,您将添加 tv_sec
字段乘以 1000
,然后添加 tv_nsec
字段除以 1000000
。
如果只需要比较哪个时间戳早,可以只比较两个tv_sec
字段,如果正好相等,再比较tv_usec
字段。我所知道的每个 unix(SCO UNIX 除外)都实现了 gettimeofday()
微秒分辨率。