如何将 C 中的 unix 时间戳作为 int 获取?

Posted

技术标签:

【中文标题】如何将 C 中的 unix 时间戳作为 int 获取?【英文标题】:How do I get the unix timestamp in C as an int? 【发布时间】:2012-07-30 16:57:23 【问题描述】:

我想获取当前时间戳并使用fprintf 打印出来。

【问题讨论】:

有什么特别的原因为什么它需要特别是一个 int 吗? @DennisMeng 如果我不得不猜测,他可能想获取时间戳作为返回码并切断输出处理。 很抱歉,这个问题,但技术上所有这些答案都是不正确的,因为time 保证自 Unix 时代以来;根据***,它可以是供应商选择的任何时代。它还说有时使用1900。但是,我会假设它是从 Unix 时代开始的,甚至在所有远程健全的系统上。 【参考方案1】:

对于 32 位系统:

fprintf(stdout, "%u\n", (unsigned)time(NULL)); 

对于 64 位系统:

fprintf(stdout, "%lu\n", (unsigned long)time(NULL)); 

【讨论】:

如果我想在微秒内完成呢? 如果你想要微秒,你应该使用这个函数之一:clock_gettime 和 CLOCK_MONOTONIC 时钟 id 或 gettimeofday。但要注意 gettimeofday 可能会返回递减的时间值。 请注意,时间函数(以及带有 CLOCK_REALTIME id 的 clock_gettime)也可以返回挂钟时间,并且可以返回递减的时间戳。 您可以通过指定正确的转换规范来避免类型转换。您可以通过在 C 文件 (cpp main.c) 上运行预处理器来了解 time_t(由 time 返回)解析的内容。在我的 64 位系统上,time_tlong int,这导致了 %ld 转换规范。 #include <time.h>【参考方案2】:

只是转换time()返回的值

#include <stdio.h>
#include <time.h>

int main(void) 
    printf("Timestamp: %d\n",(int)time(NULL));
    return 0;

你想要什么?

$ gcc -Wall -Wextra -pedantic -std=c99 tstamp.c && ./a.out
Timestamp: 1343846167

要获得自纪元以来的微秒,从 C11 开始,可移植的方法是使用

int timespec_get(struct timespec *ts, int base)

不幸的是,C11 还没有在任何地方都可用,所以到目前为止,最接近可移植的方法是使用 POSIX 函数之一 clock_gettimegettimeofday(在 POSIX.1-2008 中标记为已过时,推荐使用 clock_gettime )。

这两个函数的代码几乎相同:

#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;

【讨论】:

如果我想在微秒内完成呢? 这意味着int 在几乎(?)所有常见系统上都不是合适的类型。对于典型的INT_MAX = 2147483647,如果你想要微秒,你可以在int 中放入不到 36 分钟。当然,那时你一般不能使用time()。便携的话,你必须使用timespec_get()。你想要什么? Unix 时间戳还是微秒(从纪元开始)? 自纪元以来的微秒将是最好的。 完成微秒,不幸的是我发现 timespec_get 是 C11 中的新内容,因此可移植性是一个问题。【参考方案3】:

使用第二个精度,您可以打印从gettimeofday() 函数获得的timeval 结构的tv_sec 字段。例如:

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

int main()

    struct timeval tv;
    gettimeofday(&tv, NULL);
    printf("Seconds since Jan. 1, 1970: %ld\n", tv.tv_sec);
    return 0;

编译运行示例:

$ gcc -Wall -o test ./test.c 
$ ./test 
Seconds since Jan. 1, 1970: 1343845834

但是,请注意,自纪元以来已经有一段时间了,因此 long int 用于这些天来适应几秒。

还有打印人类可读时间的功能。有关详细信息,请参阅this manual page。这是一个使用ctime()的例子:

#include <time.h>
#include <stdio.h>

int main()

    time_t clk = time(NULL);
    printf("%s", ctime(&clk));
    return 0;

示例运行和输出:

$ gcc -Wall -o test ./test.c 
$ ./test 
Wed Aug  1 14:43:23 2012
$ 

【讨论】:

gettimeofday 是实际的 Linux 系统调用。【参考方案4】:
#include <stdio.h>
#include <time.h>

int main ()

   time_t seconds;

   seconds = time(NULL);
   printf("Seconds since January 1, 1970 = %ld\n", seconds);

   return(0);

并且会得到类似的结果:Seconds since January 1, 1970 = 1476107865

【讨论】:

【参考方案5】:

重要的一点是要考虑您是否根据 2 个时间戳之间的差异执行任务,因为如果您使用 gettimeofday() 生成它,甚至在您将设置时间的那一刻 clock_gettime(CLOCK_REALTIME,..) 生成它,您会得到奇怪的行为。系统。

为防止此类问题,请改用clock_gettime(CLOCK_MONOTONIC_RAW, &amp;tms)

【讨论】:

以上是关于如何将 C 中的 unix 时间戳作为 int 获取?的主要内容,如果未能解决你的问题,请参考以下文章

你如何将一个非常大的 (>max(int64)) 纳秒 unix 时间戳转换为 time.Time

HSQLDB (HyperSQL) - 如何以毫秒精度将 UNIX 时间戳作为数字获取

c++中如何将unix时间戳转换为标准时间,有函数吗

如何通过将数据作为参数传递以过滤 unix 时间戳来查询具有聚合的 mongodb

如何在默认和更新时将 unix 时间戳存储为 int?

如何在 Clojure 中获取 Unix 时间戳?