如何在C语言中以毫秒数形式获取当前日期时间

5

我正在尝试编写一个程序,基于系统的内部时钟生成随机数,这样我就不需要种子或第一个值。 第一个值必须从内部时钟中获取,将年、月、日、小时、分钟、秒转换为毫秒,并将它们添加到当前毫秒中以获取唯一数字(时间戳)。 有什么帮助可以在 C 中获取这些值吗?


1
请注意,只要您不打算将其用于安全目的,使用当前时间作为随机数生成器的种子就可以。如果您想确保每次运行程序时获得不同的值,那么这样做是可以的。但是,如果您想要实现不可预测性,例如在密码学中,使用时间作为PRNG的种子是完全不安全的(它最多提供16位熵 - 我很慷慨;实际上更像是10位,甚至更少 - 而大多数密码学工作需要128位或更多的熵)。 - Jonathan Leffler
1
可能是如何使用ANSI C测量毫秒时间?和其他系统特定版本的重复问题,例如https://dev59.com/zm865IYBdhLWcg3wnP2a - Ciro Santilli OurBigBook.com
3个回答

6
您可以使用 clock_gettime()gettimeofday(),或者如果您处于非常贫困的环境中,则可以使用ftime()time()。请确保使用足够大的数据类型来存储毫秒级时间。
对于 clock_gettime(),结果是一个具有tv_sectv_nsec元素的struct timespec结构体。您可以使用以下方式:
#include <time.h>
#include <stdint.h>

struct timespec t;
clock_gettime(CLOCK_REALTIME, &t);
int64_t millitime = t.tv_sec * INT64_C(1000) + t.tv_nsec / 1000000;

使用gettimeofday()函数(虽然它已被正式弃用,但更为广泛地使用——例如Mac OS X具有gettimeofday()但没有clock_gettime()),您将获得一个具有tv_sectv_usec成员的struct timeval结构体:

#include <sys/time.h>
#include <stdint.h>

struct timeval t;
gettimeofday(&t, 0);
int64_t millitime = t.tv_sec * INT64_C(1000) + t.tv_usec / 1000;

请注意,ftime()在旧版本的POSIX中是标准函数,但现在不再是POSIX的一部分,尽管某些系统仍会提供它以实现向后兼容性。它作为第一个亚秒级时间处理工具出现在Unix的早期版本中,但并不早于第7版Unix。它被添加到POSIX(Single Unix规范)以实现向后兼容性,但如果可以,请使用clock_gettime(),如果不能,则使用gettimeofday()


就我个人经验而言,在Intel Xeon Linux系统上,我看到函数clock_gettime()总是返回四舍五入为250的纳秒值,因此如果使用结果的这部分,则可能需要除以1000000。[编辑-如下所指出,除以1000会产生微秒] - 6EQUJ5
@AndrewMcDonnell:你需要将纳秒值除以一百万以获得毫秒。 - Jonathan Leffler
当然,你是正确的;我只是指出如果你需要更大的范围,那么最后三位数字就没有用了。 - 6EQUJ5
@chux: 是的,你说得对;在赋值之前应该将结果强制转换为 int64_t。使用 LL 后缀是一种方法,如果 millitime 的类型是 long long,那么我会使用这种方法。但由于我使用了 int64_t,因此最好使用 <stdint.h> 中定义的 INT64_C() 宏(以及 int64_t)。 - Jonathan Leffler
我该如何插入 #include <sys/time.h>?我被告知这个库未定义。 - El GaGa
@ElGaGa:(a) 这不是一个库,而是一个头文件;(b) 如果你没有它,就无法使用它;(c) 你在哪个平台上没有它?Windows 是一个独立的操作系统,与 POSIX 标准并不兼容。 - Jonathan Leffler

0

标准C不能保证时间精度高于一秒。如果您使用的是POSIX系统,请尝试时钟*函数


@ElGaGa:我不知道。我想,就像C语言一样,C++不能保证时间精度高于一秒。我不知道除了C++标准之外还有哪些函数是广泛可用的。 - pmg

0

如果你在Windows上进行这个操作,你可以使用:

unsigned int rand = GetTickCount() % A_PRIME_NUMBER_FOR_EXAMPLE;

[编辑:强调取模运算符在您的情况下适当的使用]


这可能需要一个非常精确的系统时钟。请参见此处的文档。它指出典型分辨率为10-16毫秒。另外,您可能是指65535。 - FRob
我只是指任意数字。也许我在解释问题时有些过于宽泛了... 有些数字比其他数字更随机,等等... - 6EQUJ5
使用质数相对于魔术数字65531会有更多的好处。 - chux - Reinstate Monica
GetTickCount() 包含在哪个库中? - El GaGa
请查看@FRob的帖子中的链接。 - 6EQUJ5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接