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

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

【问题讨论】:

    标签: c time


    【解决方案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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-01-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多