[C++] time_t 타입 및 tm 구조체 설명과 관련 함수들(mktime, localtime, gmtime...) 사용 방법과 UTC 변환
본문 바로가기
프로그래밍/C++ \ C#

[C++] time_t 타입 및 tm 구조체 설명과 관련 함수들(mktime, localtime, gmtime...) 사용 방법과 UTC 변환

by [아마군] 2020. 3. 30.
반응형

 

1. time_t 소개

C++ 에서는 UTC 1970년 1월 1일 00:00:00로부터 시간을 초(second)단위로 카운트하여 time_t 라는 타입으로 제공한다. (time_t 타입은 int64 를 typedef 으로 정의하고 있다.)

 

즉, 1970년 1월 1일 자정을 기준으로 시스템의 타임 서비스에서 가져온 time_t 값은 0이며 이후 초당 1씩 추가로 카운트 된다.

 

이 외에 time_t 형식을 년월일시분초 형태로 분할한 일시(struct tm 형식)로 변환하는 gmtime(gmtime_s)localtime(localtime_s) 함수가 있다.

 

또한 struct tm 형식을 time_t 형식으로 변환하는 mktime(_mkgmtime, timegm)이 있다.

 


2. tm 구조체

위에서 설명한 tm 구조체는 1970년 1월 1일 자정 이후로 누적된 초(second) 를 표현하는 time_t 의 경우 컴퓨터가 아닌 사람이 직접 사용하기에는 매우 불편하다.

 

struct tm 의 경우 년월일시분초 단위로 멤버변수를 가지고 있어 실제로 사람이 사용하는 날짜의 개념을 적용한 구조체 이다.

 

struct tm
{
int tm_sec; // seconds after the minute - [0, 60] including leap second
int tm_min; // minutes after the hour - [0, 59]
int tm_hour; // hours since midnight - [0, 23]
int tm_mday; // day of the month - [1, 31]
int tm_mon; // months since January - [0, 11]
int tm_year; // years since 1900
int tm_wday; // days since Sunday - [0, 6]
int tm_yday; // days since January 1 - [0, 365]
int tm_isdst; // daylight savings time flag
};
view raw tm hosted with ❤ by GitHub

사용자가 이 tm 구조체를 원하는 날짜와 시간으로 채워서 타임 시스템 함수들에 인자로 전달해 주면 컴퓨터가 사용하는 time_t 값으로 전환 할 수 있으며 반대의 경우도 가능하다.

 


3. time_t -> struct tm

 

time_t 로 가져온 현재 시간을 tm 구조체로 변경 합니다.

 

gmtime(gmtime_s) 과 localtime(localtime_s) 함수를 통해 각각 UTC(세계협정시) 나 시스템의 타임존에 맞는 시간으로 바꿀 수 있다.

 

현재 MS Visual C++ 2019 기준으로 gmtime 과 localtime 은 deprecate 되었으며 버퍼 배열을 사용하는 gmtime_s 와 localtime_s 를 사용해야 한다.

 

include <iostream>
include <stdio.h>
include <time.h>
int main()
{
time_t curTime;
time(&curTime); //현재 시스템의 시간에 해당하는 time_t 값을 가져옴)
//////////////////////////////////////////////////////
//현재 시스템의 타임존 기준(local time) 가져오기
//////////////////////////////////////////////////////
struct tm localTM;
localTime_s(&localTM, &curTime); //time_t -> struct tm
char buff[256];
asctime_s(buff, sizeof(localBuff), &localTM); //struct tm 을 문자열로 바꿔줌.
printf("tm : %s\n", buff); //"Mon Mar 30 12:00:00 2020"
//////////////////////////////////////////////////////
//UTC 기준 시간(GMT) 정보 time_t 가져오기
//////////////////////////////////////////////////////
struct tm gmTM;
gmtime_s(&gmTM, &curTime); //time_t -> struct tm
asctime_s(buff, sizeof(buff), &gmTM); //struct tm 을 문자열로 바꿔줌.
printf("tm : %s\n", buff); //"Mon Mar 30 03:00:00 2020"
}
view raw time.cpp hosted with ❤ by GitHub

4. struct tm -> time_t

 

반대로 사용자가 tm 구조체에 원하는 날짜와 시간을 입력한 후 컴퓨터가 사용하는 time_t 로 변환 하는것도 가능하다.

 

다만 어째서인지 C/C++ 표준 라이브러리에는 시스템이 속한 타임존의 시간인 local time 으로 바꾸는 함수인 mktime 은 존재 하지만 UTC(세계협정시) tm 구조체를  time_t 로 바꾸는 함수는 지원하지 않는다.

 

어쩔 수 없이 비표준 함수를 찾아봤는데 유닉스 기반 시스템에서는 timegm 함수를, MS Visual C++ 에서는 _mkgmtime 함수를 사용할 수 있다.

 

아래 예제에서는 MS Visual C++ 기반의 _mkgmtime 을 사용했다.

 

#include <iostream>
#include <stdio.h>
#include <time.h>
time_t MakeLocalTime_t(int YYYY, int MM, int DD, int hh, int mi, int ss); //현지 시각 tm -> time_t
time_t MakeUTCTime_t(int YYYY, int MM, int DD, int hh, int mi, int ss); //UTC(GMT) 시각 tm -> time_t
int main()
{
//time_t 값으로 변환할 날짜
int year = 2020;
int mon = 12;
int day = 25;
int hour = 0;
int min = 0;
int sec = 0;
time_t localTime = MakeLocalTime_t(year, mon, day, hour, min, sec);
printf("2020 x-mas local time_t : %n\n", localTime);
time_t utcTime = MakeUTCTime_t(year, mon, day, hour, min, sec);
printf("2020 x-mas UTC time_t : %n\n", utcTime);
////////////////////////////////////////////////////
//응용
////////////////////////////////////////////////////
//현재부터 2020년 크리스마스 까지 남은 초
time_t curTime;
time(&curTime);
printf("time remaining until 2020 x-mas : %n\n", localTime - curTime);
//2020년 크리스마스 이후인지 검사
if (curTime >= localTime)
{
printf("Merry X-mas");
}
}
time_t MakeLocalTime_t(int YYYY, int MM, int DD, int hh, int mi, int ss)
{
struct tm st_tm;
st_tm.tm_year = YYYY - 1900;
st_tm.tm_mon = MM - 1;
st_tm.tm_mday = DD;
st_tm.tm_hour = hh;
st_tm.tm_min = mi;
st_tm.tm_sec = ss;
return mktime( &st_tm );
}
time_t MakeUTCTime_t(int YYYY, int MM, int DD, int hh, int mi, int ss)
{
struct tm st_tm;
st_tm.tm_year = YYYY - 1900;
st_tm.tm_mon = MM - 1;
st_tm.tm_mday = DD;
st_tm.tm_hour = hh;
st_tm.tm_min = mi;
st_tm.tm_sec = ss;
return _mkgmtime( &st_tm );
}
view raw time.cpp hosted with ❤ by GitHub

 

보통 서비스 중에 특정 날짜, 시간에 자동 실행되야 하는 이벤트 등의 경우 미리 필요한 날짜를 time_t 값으로 구해서 테이블에 넣어두고 현재 time_t 값과 비교하면서 체크 하는 방식으로 자주 사용되곤 한다.

반응형

댓글