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


Answers:


107

使用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;
}

在毫秒部分,请看一下这个问题。如何使用ANSI C测量时间(以毫秒为单位)?


现在,这是一个更好的答案,并且是查找如何处理毫秒部分的道具。我认为您的缓冲区现在比需要的要长一些。
杰克·凯利2010年

14
最好长于短:-)
paxdiablo

极好的答案。我可以用PHP做各种各样的事情,但是知道C.THanks已经存在了。
Vijay Kumar Kanta 2014年

1
也许至少time(&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.
AntoninDécimo'16

5
答案在至少一种情况下(Linux)肯定是错误的,因为localtime()使用的“ struct tm”不包含秒以下的任何时间信息。取而代之的是,gettimeofday()使用的“ struct timeval”具有微秒,除以1000会得到毫秒。所有这些批评确实是错误和误导的!除非有人报告使用哪种架构,否则您将使用“ struct tm”获得第二个以下的时间详细信息。
EnzoR

30

上面的答案不能完全回答问题(特别是Millisec部分)。我的解决方案是在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实现上不可用
Mendes

构建它时,请添加“ -lm”选项。
skysign

3
我认为buffer [24]足够,原因如下,YYYY:MM:DD HH:MM:SS.mmm +'\ 0',为
24。– skysign

@Mendes,为什么要提到Windows?问题是关于普通的C语言。尽管有所有错误的投票,这是一个更好的答案(尽管不是正确的答案)!
EnzoR

2
user3624334:不,您不了解该代码。只有一个时间要求。我假设您的意思是本地时间调用-它只是重新格式化了gettimeofday的输出。
克里斯,

12

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表示方便的技巧,用于将显示填充到毫秒。我曾经有一个客户想要我这样做,但是它的位数非零,所以看起来那里很重要。我拒绝了他,但同意置零。
RBerteig 2010年

4
我的一个朋友(当然不是我)曾经使用过类似的技巧-他们保留包含最后一秒和“毫秒”的静态变量。在第二次与上次没有变化的情况下,他们只是在Millisec中添加了一个介于1到200之间的随机值(确保当然不超过999-rand()的实际最大值始终是200到999的一半距离)。第二个确实发生了变化,他们只是在添加之前将millisec设置为0。尼斯看似随机,但顺序正确的毫秒数,客户都不是更明智的:-)
paxdiablo 2010年

5

以下代码以微秒精度打印。我们要做的就是在构造字符串上使用gettimeofday和并将其追加。strftimetv_sectv_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;
}

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

2

招:

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

1
请详细说明为什么这样做。以及到底发生了什么。
Raj Kamal

一切与上面的示例相同,但更有效。`time_len + = snprintf(log_buff + time_len,log_buff-time_len的大小,“ log var is =%s”,logvar); int ret =写(log_fd,log_buff,time_len); `
АндрейМельников

我从哪里导入gettimeofday?
AndreyP

1

此页面上的所有解决方案都不适用于我,我将它们混合在一起并使其与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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.