시간을 형식으로 인쇄하는 방법 : 2009‐08‐10 18 : 17 : 54.811


96

C 형식으로 시간을 인쇄하는 가장 좋은 방법은 무엇입니까 2009‐08‐10 
18:17:54.811?

답변:


108

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를 사용하여 시간을 밀리 초 단위로 측정하는 방법은 무엇입니까?


지금은 훨씬 더 나은 대답이며 밀리 초 부분을 처리하는 방법을 찾는 소품입니다. 하지만 이제 버퍼가 필요한 것보다 조금 더 길다고 생각합니다.
Jack Kelly

14
더 나은 긴 짧은 :-)보다합니다
paxdiablo

훌륭한 대답입니다. 나는 PHP에서 모든 종류의 일을 할 수 있었지만 이미 C에서 모든 것이 있다는 것을 알고 있었다. 감사합니다.
Vijay Kumar Kanta 2014 년

1
아마도 적어도 Linux의 경우 라인 time(&timer)은이어야합니다 timer = time(NULL);. The tloc argument is obsolescent and should always be NULL in new code. When tloc is NULL, the call cannot fail.
Antonin Décimo 2016

5
localtime ()에서 사용하는 "struct tm"은 초 미만의 시간 정보를 보유하지 않기 때문에 적어도 한 가지 경우 (Linux)에서 대답은 확실히 잘못되었습니다. 대신 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;
}

gettimeofdayWindows 구현에서는 사용할 수 없습니다.
Mendes

빌드 할 때 '-lm'옵션을 추가하십시오.
skysign

3
buffer [24]는 충분하다고 생각합니다. 이유는 아래와 같습니다. YYYY : MM : DD HH : MM : SS.mmm + '\ 0'은 24입니다.
skysign

@Mendes, 왜 Windows를 언급합니까? 질문은 평범한 C 언어에 관한 것입니다. 모든 잘못된 찬성 투표에도 불구하고 이것은 더 나은 답변입니다 (올바른 것은 아니지만)!
EnzoR

2
user3624334 : 아니요, 코드를 이해하지 못합니다. 시간에 대한 요청은 하나뿐입니다. 나는 당신이 localtime 호출을 의미한다고 가정합니다-그것은 단지 gettimeofday의 출력을 재구성합니다.
Chris

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

하지만 .NET Framework에서 사용할 수 없기 때문에 1 초 미만의 해상도를 제공하지 않습니다 time_t. 다음을 출력합니다.

2010-09-09 10:08:34.000

사양의 제약을 받고 있고 요일과 시간 사이의 공백을 원하지 않는 경우 형식 문자열에서 제거하면됩니다.


밀리 초 단위로 화면을 채우는 편리한 트릭에 +1. 한때 저에게 그렇게하기를 원했던 고객이 있었지만 0이 아닌 숫자로 의미가있는 것처럼 보였습니다. 나는 그에게 말을 걸었지만 0을 넣기로 동의했습니다.
RBerteig

4
내 친구 (물론 내가 아님)는 비슷한 트릭을 사용했습니다. 그들은 마지막 초와 "밀리 초"를 포함하는 통계를 유지했습니다. 두 번째 값이 지난번에 변경되지 않은 곳에서 그들은 1에서 200 사이의 임의의 값을 millisec에 추가했습니다 (물론 999를 넘지 않았는지 확인합니다. rand ()의 실제 최대 값은 항상 최소값이었습니다. 200과 999까지의 거리의 절반). 두 번째가 변경된 곳에서는 추가하기 전에 millisec을 0으로 설정했습니다. 니스 겉으로는 무작위하지만 제대로 밀리 초 염기 서열과 고객이 아무도 현명 :-) 없었다
paxdiablo

5

다음 코드는 마이크로 초 정밀도로 인쇄됩니다. 우리가 할 일은 사용하는 것입니다 gettimeofdaystrftimetv_sec와 APPEND 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;
}

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, sizeof log_buff-time_len, "log var is = % s", logvar); int ret = write (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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.