Linux의 C에서 현재 시간을 밀리 초 단위로 얻는 방법은 무엇입니까?


86

Linux에서 현재 시간을 밀리 초 단위로 가져 오려면 어떻게해야합니까?

답변:


100

이것은 POSIXclock_gettime 기능을 사용하여 달성 할 수 있습니다 .

현재 버전의 POSIX에서는 사용되지 않음gettimeofday 으로 표시 됩니다. 이는 향후 사양 버전에서 제거 될 수 있음을 의미합니다. 응용 프로그램 작성자는 clock_gettime대신 함수 를 사용하는 것이 좋습니다 gettimeofday.

다음은 사용 방법의 예입니다 clock_gettime.

#define _POSIX_C_SOURCE 200809L

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

void print_current_time_with_ms (void)
{
    long            ms; // Milliseconds
    time_t          s;  // Seconds
    struct timespec spec;

    clock_gettime(CLOCK_REALTIME, &spec);

    s  = spec.tv_sec;
    ms = round(spec.tv_nsec / 1.0e6); // Convert nanoseconds to milliseconds
    if (ms > 999) {
        s++;
        ms = 0;
    }

    printf("Current time: %"PRIdMAX".%03ld seconds since the Epoch\n",
           (intmax_t)s, ms);
}

목표가 경과 시간 측정이고 시스템이 "단조 시계"옵션을 지원하는 경우 CLOCK_MONOTONIC대신을 사용하는 것이 좋습니다 CLOCK_REALTIME.


7
POSIXly 정확하다는 점에 +1 — 답변의 단위가 잘못되었습니다. 영업 시간 싶지 않습니다 밀리 초,하지만 시간 밀리 초.
pilcrow

5
좋은 해결책이지만 명령 에서 -lm 을 잊지 마십시오 gcc.
David Guyon

2
round에 대한 맨 페이지에 따르면 결과를 정수 (또는 long)에 할당 할 때 lround를 사용하려고합니다
hildred

2
round () 대신 floor ()를 사용해야 1000ms로 반올림되지 않습니다. 그렇지 않으면 s이런 일이 발생할 때 증분해야 합니다. 드문 경우 일 수 있지만 추가 숫자로 인해 문제가 발생할 수 있습니다.
Mike

1
@Mike 좋은 캐치. 2,000 명 중 1 명은 그렇게 드물지 않으므로 반드시 수정해야합니다. 오히려 사용 층보다 내가 좀 더 정확성을 유지하고 라운드를 계속하지만 1000 올림 경우 두 번째 카운터를 증가하는 것을 선호 거라고 생각
댄 성형

60

다음과 같이해야합니다.

struct timeval  tv;
gettimeofday(&tv, NULL);

double time_in_mill = 
         (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000 ; // convert tv_sec & tv_usec to millisecond

33

다음은 밀리 초 단위로 현재 타임 스탬프를 가져 오는 util 함수입니다.

#include <sys/time.h>

long long current_timestamp() {
    struct timeval te; 
    gettimeofday(&te, NULL); // get current time
    long long milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; // calculate milliseconds
    // printf("milliseconds: %lld\n", milliseconds);
    return milliseconds;
}

시간대 정보 :

gettimeofday () 지원하여 시간대를 지정 하고, 시간대를 무시하는 NULL을 사용 하지만 필요한 경우 시간대를 지정할 수 있습니다.


@Update-시간대

때문에 long정도로 설정 시간대 자체로 수행 할 시간 표현이 관련이 없다 tz()은 gettimeofday의 PARAM 그것을 어떤 차이가 나지 않을 것이기 때문에, 불필요하다.

그리고의 man 페이지에 따르면 구조 gettimeofday()의 사용 timezone이 더 이상 사용되지 않으므로 tz인수는 일반적으로 NULL로 지정되어야합니다. 자세한 내용은 man 페이지를 확인하십시오.


1
> gettimeofday () 지원하여 시간대를 지정하고, 시간대를 무시하는 NULL을 사용하지만 필요한 경우 시간대를 지정할 수 있습니다. 당신은 잘못. 시간대는 localtime () 호출을 통해 독점적으로 도입되어야합니다.
vitaly.v.ch

@ vitaly.v.ch 나는 테스트를했는데, as 의 tz매개 변수를 통과 해도 경고가 나오지 않으며, 결과에 영향을 미치지 않습니다. 시간 의 표현이 관련이 없거나 영향을받지 않기 때문입니다. 시간대 자체가 맞죠? gettimeofday()&(struct timezone tz = {480, 0})long
에릭 왕

테스트 할 이유가 없었습니다. Linux 커널에는 시간대에 대한 적절한 정보가 없으며 동시에이를 제공 할 방법이 없습니다. tz 인수가 매우 특정한 방식으로 처리되는 이유입니다. 긴 표현은 중요하지 않습니다.
vitaly.v.ch 2011

@ vitaly.v.ch 특정 시점에서 긴 표현은 시간대에 따라 달라지지 않습니다. 이것이 중요한 이유이며 일반적으로 NULL통과하기에 합당한 값입니다. 그리고 저는 테스트가 항상 사물을 증명하는 좋은 접근 방식이라고 믿습니다.
에릭 왕

13

gettimeofday()초 및 마이크로 초 단위로 시간을 가져 오는 데 사용 합니다. 결합하고 밀리 초로 반올림하는 것은 연습으로 남겨집니다.



0

Dan Moulding의 POSIX 답변에서 파생되었으며 다음과 같이 작동합니다.

#include <time.h>
#include <math.h>

long millis(){
    struct timespec _t;
    clock_gettime(CLOCK_REALTIME, &_t);
    return _t.tv_sec*1000 + lround(_t.tv_nsec/1.0e6);
}

또한 David Guyon이 지적한대로 : -lm으로 컴파일


0

이 버전은 수학 라이브러리가 필요하지 않으며 clock_gettime ()의 반환 값을 확인했습니다.

#include <time.h>
#include <stdlib.h>
#include <stdint.h>

/**
 * @return milliseconds
 */
uint64_t get_now_time() {
  struct timespec spec;
  if (clock_gettime(1, &spec) == -1) { /* 1 is CLOCK_MONOTONIC */
    abort();
  }

  return spec.tv_sec * 1000 + spec.tv_nsec / 1e6;
}

1
귀하의 답변이 6 개의 다른 답변 (특히 2 개의 다른 답변이 이미 의존하고 있다는 점을 감안할 때)에 대해 설명 clock_gettime하고 필요한 헤더를 추가하고 OP의 질문을 어떤 방식으로 처리하는지 추가하세요. 에 관해서 CLOCK_MONOTONIC는 리터럴 대신 표준 매크로를 직접 답변 (및 일반적으로 코드)에 사용하는 것이 좋습니다.
PiCTo

1
이 코드가 질문에 답할 수 있지만,이 코드가 질문에 답하는 이유 및 / 또는 방법에 대한 추가 컨텍스트를 제공하면 장기적인 가치가 향상됩니다.
Donald Duck
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.