如何打印时间格式:2009-08-10 18:17:54.811

Posted

技术标签:

【中文标题】如何打印时间格式:2009-08-10 18:17:54.811【英文标题】:How to print time in format: 2009‐08‐10 18:17:54.811 【发布时间】:2011-04-10 01:11:00 【问题描述】:

2009‐08‐10 
18:17:54.811 格式在 C 中打印时间的最佳方法是什么?

【问题讨论】:

【参考方案1】:

使用strftime()

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

int main()

    time_t timer;
    char buffer[26];
    struct tm* tm_info;

    timer = time(NULL);
    tm_info = localtime(&timer);

    strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
    puts(buffer);
 
    return 0;

对于毫秒部分,看看这个问题。 How to measure time in milliseconds using ANSI C?

【讨论】:

现在这是一个更好的答案,也是查找如何处理毫秒部分的道具。不过,我认为您的缓冲区现在比它需要的要长一些。 越长越好 :-) 绝妙的答案。我可以用 php 做各种各样的事情,但我知道这一切都已经在 C 中了。谢谢。 也许time(&amp;timer) 应该是timer = time(NULL);,至少对于Linux 而言。 The tloc argument is obsolescent and should always be NULL in new code. When tloc is NULL, the call cannot fail. 至少在一种情况下(Linux),答案肯定是错误的,因为 localtime() 使用的“struct tm”不包含任何秒以下的时间信息。相反,gettimeofday() 使用的“struct timeval”具有微秒,除以 1000 将产生毫秒。所有这些赞成票都是错误的和误导性的!除非有人报告您使用“struct tm”在哪种架构下获得低于秒的时间详细信息。【参考方案2】:

您可以使用strftime,但struct tm 在几秒钟内没有分辨率。我不确定这对于您的目的是否绝对需要。

struct tm tm;
/* Set tm to the correct time */
char s[20]; /* strlen("2009-08-10 18:17:54") + 1 */
strftime(s, 20, "%F %H:%M:%S", &tm);

【讨论】:

【参考方案3】:

time.h 定义了一个 strftime 函数,该函数可以为您提供 time_t 的文本表示,使用如下:

#include <stdio.h>
#include <time.h>
int main (void) 
    char buff[100];
    time_t now = time (0);
    strftime (buff, 100, "%Y-%m-%d %H:%M:%S.000", localtime (&now));
    printf ("%s\n", buff);
    return 0;

但这不会为您提供亚秒级分辨率,因为 time_t 无法提供该分辨率。它输出:

2010-09-09 10:08:34.000

如果您确实受到规范的限制并且不想在日期和小时之间留出空格,只需将其从格式字符串中删除即可。

【讨论】:

+1 用于将显示填充到毫秒的权宜之计。我曾经有一个客户希望我这样做,但数字不是零,所以看起来那里很重要。我说服了他,但同意输入零。 我的一个朋友(当然不是我)曾经使用过类似的技巧 - 他们保留包含最后一秒和“毫秒”的静态数据。如果第二个与上次相比没有变化,他们只是在毫秒之间添加了一个 1 到 200 之间的随机值(当然要确保它没有超过 999 - rand() 的实际最大值始终是最小值200 和 999 距离的一半)。第二个确实发生了变化,他们只是在添加之前将毫秒设置为 0。漂亮的看似随机但正确排序的毫秒,客户并不聪明:-)【参考方案4】:

以上答案并未完全回答问题(特别是毫秒部分)。我对此的解决方案是在 strftime 之前使用 gettimeofday。请注意避免将毫秒四舍五入为“1000”。这是基于 Hamid Nazari 的回答。

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

int main() 
  char buffer[26];
  int millisec;
  struct tm* tm_info;
  struct timeval tv;

  gettimeofday(&tv, NULL);

  millisec = lrint(tv.tv_usec/1000.0); // Round to nearest millisec
  if (millisec>=1000)  // Allow for rounding up to nearest second
    millisec -=1000;
    tv.tv_sec++;
  

  tm_info = localtime(&tv.tv_sec);

  strftime(buffer, 26, "%Y:%m:%d %H:%M:%S", tm_info);
  printf("%s.%03d\n", buffer, millisec);

  return 0;

【讨论】:

gettimeofday 在 Windows 实现中不可用 构建时请添加'-lm'选项。 我觉得buffer[24]就够了,原因如下,YYYY:MM:DD HH:MM:SS.mmm + '\0', 是24。 @Mendes,为什么要提到 Windows?问题是关于纯 C 语言的。这是一个更好的答案(尽管不是正确的答案),尽管所有这些错误的赞成票! user3624334 :不,您不了解代码。只有一个时间要求。我假设您的意思是本地时间调用 - 它只是重新格式化 gettimeofday 的输出。【参考方案5】:

以下代码以微秒精度打印。我们所要做的就是在tv_sec 上使用gettimeofdaystrftime 并将tv_usec 附加到构造的字符串中。

#include <stdio.h>
#include <time.h>
#include <sys/time.h>
int main(void) 
    struct timeval tmnow;
    struct tm *tm;
    char buf[30], usec_buf[6];
    gettimeofday(&tmnow, NULL);
    tm = localtime(&tmnow.tv_sec);
    strftime(buf,30,"%Y:%m:%dT%H:%M:%S", tm);
    strcat(buf,".");
    sprintf(usec_buf,"%dZ",(int)tmnow.tv_usec);
    strcat(buf,usec_buf);
    printf("%s",buf);
    return 0;

【讨论】:

【参考方案6】:

技巧:

    int time_len = 0, n;
    struct tm *tm_info;
    struct timeval tv;

    gettimeofday(&tv, NULL);
    tm_info = localtime(&tv.tv_sec);
    time_len+=strftime(log_buff, sizeof log_buff, "%y%m%d %H:%M:%S", tm_info);
    time_len+=snprintf(log_buff+time_len,sizeof log_buff-time_len,".%03ld ",tv.tv_usec/1000);

【讨论】:

请详细说明为什么这样做。以及到底发生了什么。 和上面的例子一样,但是更有效。 ` time_len+=snprintf(log_buff+time_len,sizeof log_buff-time_len,"log var is=%s",logvar); int ret = write(log_fd, log_buff, time_len); ` 从哪里导入 gettimeofday?【参考方案7】:

此页面上的所有解决方案都不适合我,我将它们混合起来,让它们与 Windows 和 Visual Studio 2019 一起使用,方法如下:

#include <Windows.h>
#include <time.h> 
#include <chrono>

static int gettimeofday(struct timeval* tp, struct timezone* tzp) 
    namespace sc = std::chrono;
    sc::system_clock::duration d = sc::system_clock::now().time_since_epoch();
    sc::seconds s = sc::duration_cast<sc::seconds>(d);
    tp->tv_sec = s.count();
    tp->tv_usec = sc::duration_cast<sc::microseconds>(d - s).count();
    return 0;


static char* getFormattedTime() 
    static char buffer[26];

    // For Miliseconds
    int millisec;
    struct tm* tm_info;
    struct timeval tv;

    // For Time
    time_t rawtime;
    struct tm* timeinfo;

    gettimeofday(&tv, NULL);

    millisec = lrint(tv.tv_usec / 1000.0);
    if (millisec >= 1000) 
    
        millisec -= 1000;
        tv.tv_sec++;
    

    time(&rawtime);
    timeinfo = localtime(&rawtime);

    strftime(buffer, 26, "%Y:%m:%d %H:%M:%S", timeinfo);
    sprintf_s(buffer, 26, "%s.%03d", buffer, millisec);

    return buffer;


结果:

2020:08:02 06:41:59.107

2020:08:02 06:41:59.196

【讨论】:

以上是关于如何打印时间格式:2009-08-10 18:17:54.811的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 golang 在网络打印机上打印文件或格式化文本

如何使用表格格式打印实数矩阵

如何以UTC格式打印DateTime?

如何将格式正确的表格打印到控制台?

问:如何以横向格式打印 EXCEL / VBA 用户表单? [关闭]

如何打印格式化的 BigDecimal 值?