【问题标题】:Using strftime in C, how can I format time exactly like a Unix timestamp?在 C 中使用 strftime,我怎样才能像 Unix 时间戳一样格式化时间?
【发布时间】:2012-11-09 02:52:15
【问题描述】:

这是我所追求的时间格式:

2009-10-08 04:31:33.918700000 -0500

我目前正在使用这个:

strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", ts);

这给出了:

2009-10-11 13:42:57 CDT

这很接近,但不准确。我似乎在最后显示 -0500 时找不到任何东西。另外,我得到了 int 的秒数。

如何解决这两个问题?

【问题讨论】:

    标签: c strftime


    【解决方案1】:

    我想出了这个:

        char            fmt[64], buf[64];
        struct timeval  tv;
        struct tm       *tm;
    
        gettimeofday(&tv, NULL);
        if((tm = localtime(&tv.tv_sec)) != NULL)
        {
                strftime(fmt, sizeof fmt, "%Y-%m-%d %H:%M:%S.%%06u %z", tm);
                snprintf(buf, sizeof buf, fmt, tv.tv_usec);
                printf("'%s'\n", buf); 
        }
    

    解决您遇到的问题:

    • 使用gettimeofday()struct timeval,它有一个微秒成员以实现更高的精度。
    • 使用两步法,我们首先构建一个字符串,其中包含除微秒以外的所有数据。
    • 使用小写的“z”作为时区偏移量。这似乎是一个 GNU 扩展。

    我尝试通过gettimeofday() 的第二个struct timezone * 参数手动重新创建时区偏移量,但在我的机器上它返回的偏移量为0,这是不正确的。 gettimefday()manual page 对 Linux(我测试过的操作系统)下的时区处理有很多话要说。

    【讨论】:

    • %z 仍然是非标准 =)
    • 谢谢,这是迄今为止我得到的最接近的。 '%%06u' 现在只是在向我扔垃圾数据,但其余的运行良好。 P.S 是的,我知道 %z 是非标准的,但我会接受 :)
    • @aditya:这很奇怪......上面的代码应该可以工作。确保为第二个 snprintf() 调用提供正确的无符号微秒值以用于 %06u 格式。您可以尝试在 strftime() 调用之后打印结果,您应该会看到最终输出,除了句点之后的 %06u 序列。
    • 看来这里的每个人都忽略了 %z 是完全标准的 C99 的事实。它在(免费提供的)n1256(tc3 工作文件)草案以及官方标准文档中,也在 POSIX (pubs.opengroup.org/onlinepubs/9699919799/functions/…) 中指定。
    • tv.tv_usecsuseconds_t 类型。还没有找到它的 % 修饰符。也许转换为(无符号长)并使用%06lu。 (或转换为 (uintmax_t) 并使用 PRIuMAX。
    【解决方案2】:

    "%Y-%m-%d %T %z",但似乎%z 是 GNU 扩展。

    【讨论】:

    • %T 没有给出问题中要求的亚秒级数字。
    【解决方案3】:

    %z(小写 z)。

    但是,这不会出现在Posix specification 中。谷歌带我转了一圈back here

    【讨论】:

      猜你喜欢
      • 2021-02-26
      • 1970-01-01
      • 2014-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-13
      • 2020-06-20
      • 2015-09-10
      相关资源
      最近更新 更多