시간 함수를 사용하면서 가장 힘들었던 점은 UTC , GMT 와 timezone 에 따른 시간의 편차이다.
1970년 01월 01일 00시 00분 00초 를 기점으로 흐르는 시간을 epoch time 이라고 한다.
바꾸어 말하면 0 epoch time 은 1970년 01월 01일 00시 00분 00초 이다.
strptime 함수는 날짜와 시간으로 이루어진 문자열을 struct tm 이라는 구조체로 바꾼다.
struct tm { int tm_sec; /* Seconds. [0-60] (1 leap second) */ int tm_min; /* Minutes. [0-59] */ int tm_hour; /* Hours. [0-23] */ int tm_mday; /* Day. [1-31] */ int tm_mon; /* Month. [0-11] */ int tm_year; /* Year - 1900. */ int tm_wday; /* Day of week. [0-6] */ int tm_yday; /* Days in year.[0-365] */ int tm_isdst; /* DST. [-1/0/1]*/ #ifdef __USE_BSD long int tm_gmtoff; /* Seconds east of UTC. */ __const char *tm_zone; /* Timezone abbreviation. */ #else long int __tm_gmtoff; /* Seconds east of UTC. */ __const char *__tm_zone; /* Timezone abbreviation. */ #endif }; |
strptime("1970-01-01 00:00:00","%Y-%m-%d %H:%M:%S",&tm); 이런 식으로 쓰인다.
mktime 은 struct tm 구조체를 통해 epoch time 을 구해내는 함수이다. 근데 이 함수는 epoch time 을 구할때 struct tm 의 날짜와 시간을 바로 사용하는 것이 아니라 현재 컴퓨터의 time zone에 따라 epoch time을 구한다.
예를 들어 strptime("1970-01-01 00:00:00","%Y-%m-%d %H:%M:%S",&tm) 를 통해 struct tm 구조체를 얻고
mktime(&tm) 을 통해 struct tm 구조체를 epoch time 으로 바꾸었다고 가정하자.
예상 epoch time 은 0 이어야 실제로는 -32400 값이 나온다. 이유는 현재 내 컴퓨터의 time zone 이 KST 즉 한국으로 되어있다.
한국은 UTC 시간보다 9시간 늦는다. 즉 UTC 시간이 1970-01-01 00:00:00 이라면 KST 시간은 1970-01-01 09:00:00 이다.
위의 mktime() 은 1970-01-01 00:00:00 이 시간을 한국시간이라 생각하고 -32400 epoch time 을 반환한 것이다.
내가 원하는 시간은 UTC 시간인데 전혀 다른 값이 나온것이다. 이럴때 time zone 을 바꾸는 방법이 있다.
Time zone 을 UTC로 바꾸는 방법 (mktime UTC ) |
setenv("TZ", "UTC", 1); |
또다른 방법으로 struct tm 의 tm_gmtoff 값을 이용하는 방법이다.
struct tm 의 tm_gmtoff 은 현재 Time Zone 에 대해 UTC와 차이를 말한다. Time zone 이 KST 즉 한국이면 tm_gmtoff는 32400 값을 나타낸다. 즉 UTC 보다 32400초 (9시간) 늦다는 것이다.
struct tm 의 tm_gmtoff 을 이용하여 mktime 의 반환값을 UTC 값으로 바꾸기 |
struct tm tm; strptime("1970-01-01 00:00:00","%Y-%m-%d %H:%M:%S",&tm) printf("epoch time = %lli", time + tm.tm_gmtoff); |
결과는 0 이다. 1970-01-01 00:00:00 을 mktime 하였을때 mktime 은 이 시간을 KST 즉 한국 시간이라 생각하고 UTC epoch time 을 구하기 위해 -32400 초를 뺀 값을 반환한다. (1970-01-01 00:00:00 이 0 epoch time 이므로 -32400 으로 뺀 -32400 반환) time + tm.tm_gmtoff 은 위의 결과만 보자면 -32400 + 32400 이다. 즉 0 을 출력한다. |
정리 |
mktime() 은 인자로 받은 struct tm 구조체의 시간을 Time Zone(컴퓨터의 지역시간)이라고 생각하고 이를 토대로 UTC epoch time 을 구한다. 다시 예를 들면 1970년 01월 01일 00시 00 분 00초 값을 갖는 struct tm 구조체값을 KST(한국 시간)이라고 생각하고 (한국 시간은 UTC 시간보다 9시간 늦다.) 9시간(32400초)을 뺀 값의 epoch time을 구한다. struct tm 의 tm_gmtoff 값은 struct tm 에 들어있는 값을 UTC 시간이라고 생각하고 현재 Time Zone 과의 시간차이를 나타낸다. 다시 예를 들면 KST(한국 시간)은 UTC 보다 9시간 늦으므로 32400 값을 갖는다. |
글은 정말 못 썼는데.. 이 문제로 골머리 썩은 사람들은 무슨 말인지 이해 할 것이다...
'학습자료(~2017) > C,C++' 카테고리의 다른 글
[C,C++] printf 사용시 포맷(fotmat) 지정에 관해 -(플래폼에 종속적이지 않은 printf) (0) | 2013.04.11 |
---|---|
Coroutines in C (코루틴) (0) | 2013.03.26 |
[MYSQL] 간단 사용법 예제코드 (0) | 2012.08.20 |
[GCC]gcc 컴파일 옵션 (0) | 2012.08.13 |
[C] #if 0 ,#if 1 의 사용의도 (0) | 2012.03.29 |