메뉴 건너뛰기


Developer > Open Source

APR 6장. APR의 time관련 함수들

2013.11.12 22:06

푸우 조회 수:7629

오랫만에 다시 글을 적네요.
뭐 기다리신 분이 있다면 죄송합니다.
제가 잡다한 분야에 관심이 많아서 쫌 하다가 보면 다른 걸 하고 싶어서 ㅠㅠ
 
자 이번 강좌는 APR에서 제공하는 시간 관련 함수에 대해서 알아 보겠습니다.
 
1) time_t형과 apr_time_t형의 비교
 
사실 시간 관련 함수는 ANSI C에서도 제공하기 때문에 당장은 꼭 APR에서 제공하는 시간함수를 사용할 필요는 없을 것입니다. 여기서 당장이라고 말하는 것은 ANSI C에서 제공하는 시간 함수가 아직은 여유가 있어서 사용할 수 있다는 것입니다. 말이 더 애매한가요? ㅋㅋ
 
ANSI C에서 제공하는 time_t 데이터형은 long으로 선언되어 있습니다.
이 time_t는 "1970년 1월 1일 0시 0분 0초" 부터 지나온 초를 가지는 값인데...
현재 대부분의 컴파일러가 long형을 32비트 즉 4바이트로 정하고 있으므로 부호있는 long형의 제일 큰값인 0x7FFFFF(2147483647) 값으로 표현할 수 있는 최대의 시간은 "2038년 1월 19일 12시 14분 07초"입니다. 지금이 2007년이니깐 아직은 여유가 좀 있죠?
하지만 미래의 달력을 만든다던가 막연한 미래의 시간을 사용해야 하는 프로그램에서는 time_t형을 사용해서는 안될 것입니다.
아마 예상컨데 아마 2038년이 되면 전산 대란이 일어날지도 모르겠네요. (2000년이 되면서 문제가 생겼던 것 처럼...)
 
그래서 APR에서는 사용되는 시간 데이터형인 apr_time_t는 64비트 즉 8바이트 정수를 사용합니다.
게다가 의미도 "1970년 1월 1일 0시 0분 0초" 부터 지나온 마이크로초(1000000분의 1초)를 갖습니다.
보다 정밀하게 시간을 지정할 수 있겠죠? 이렇게 사용하더라도 부호있는 64비트 정수로 표현할 수 있는 최대값인 0x7FFFFFFFFFFFFFFF(576460752303423487)은 약 18279년 정도 됩니다. 정말 엄청난 시간이죠? 그러나 APR에서는 apr_time_t는 이 시간을 모두 사용할 수 있는 것은 아니고 "9999년 12월 31일 23시 59분 59초 999999마이크로초"에 해당하는 값인 0x0384440541429BFF(253402268399999999)까지 사용할 수 있습니다.
 
정리하자면 다음과 같습니다.

Data Type

최소

최대

정밀도

time_tThu Jan 01 09:00:00 1970Tue Jan 19 12:14:07 2038second
apr_time_tThu Jan 01 09:00:00 1970Fri Dec 31 23:59:59 9999microsecond
 
왜 시간 관련 함수가 별도 필요한지도 알아 봤으니깐.. 이제 본격적인 사용법을 알아보겠습니다.
 
우선 정해진 몇가지 메크로를 살펴보겠습니다. 참. 필요한 헤더는 "apr_time.h"입니다.
 
 
2) APR 시간관련 매크로들
 
#define  APR_TIME_C(val)   APR_INT64_C(val) 
#define  APR_TIME_T_FMT   APR_INT64_T_FMT 
#define  APR_USEC_PER_SEC   APR_TIME_C(1000000) 
#define  apr_time_sec(time)   ((time) / APR_USEC_PER_SEC) 
#define  apr_time_usec(time)   ((time) % APR_USEC_PER_SEC) 
#define  apr_time_msec(time)   (((time) / 1000) % 1000) 
#define  apr_time_as_msec(time)   ((time) / 1000) 
#define  apr_time_from_sec(sec)   ((apr_time_t)(sec) * APR_USEC_PER_SEC) 
#define  apr_time_make(sec, usec)   // 생략
#define  APR_RFC822_DATE_LEN   (30) 
#define  APR_CTIME_LEN   (25) 
 
- APR_TIME_C(val) 매크로 함수는 64비트 정수를 상수로 지정하여 apr_time_t형의 변수에 저장할 때 사용합니다. 지금의 C에서는 정수형 상수는 long형으로 처리하게 되어 있으므로 long의 범위를 넘어서는 정수형 상수는 64비트 정수라고 컴파일러에게 알려주어야 하는데... APR_TIME_C(val)이 그 역할을 합니다.
사용예)  apr_time_t maxtime = APR_TIME_C(253402268399999999);
APR_TIME_T_FMT 매크로는 printf와 같은 형식을 정의할 수있는 함수에서 64비트 정수를 받아 출력할 수 있는 형식문자를 정의합니다. %d로는 64비트 정수 모두를 출력할 수 없으니깐요.
사용예) printf("Max Value(64bit Integer) : %" APR_TIME_T_FMT "\n", APR_TIME_C(0xFFFFFFFFFFFFFFFF));
- APR_USEC_PER_SEC 매크로는 정의된 걸 보시면 아시겠지만 1초의 마이크로초 값을 갖습니다.
- apr_time_sec(time) 매크로 함수는 apr_time_t형의 time을 아큐먼트로 받아 time이 몇초인지를 돌려줍니다.
- apr_time_usec(time) 매크로 함수는 apr_time_t형의 time을 아큐먼트로 받아 마이크로초 값만을 돌려줍니다. 말이 어렵나요? 즉, time이 "2000년 1월 1일 10시 5분 12초 238921마이크로초"의 값을 갖는다면 238921를 돌려준다는 말입니다.
- apr_time_msec(time) 매크로 함수는 apr_time_t형의 time을 아큐먼트로 받아 밀리초 값만을 돌려줍니다. 즉, time이 "2000년 1월 1일 10시 5분 12초 23892마이크로초"의 값을 갖는다면 23892를 1000으로 나눈 238을 돌려준다는 말입니다.
apr_time_as_msec(time) 매크로 함수는 apr_time_t형의 time을 아큐먼트로 받아 time이 몇 밀리초인지를 돌려줍니다.
apr_time_from_sec(sec) 매크로 함수는 sec 아큐먼트로 초에 해당하는 값을 받아 1000000을 곱해 apr_time_t형인 마이크로초로 만들어 줍니다.
apr_time_make(sec, usec) 매크로 함수는 sec 아큐먼트로 초에 해당하는 값과 usec 아큐먼트로 마이크로초에 해당하는 값을 받아 apr_time_t형인 마이크로초로 만들어 줍니다.
APR_RFC822_DATE_LEN  매크로는 RFC822의 시간 형식 문자열에 필요한 버퍼의 크기를 갖습니다. (apr_rfc822_date함수 참조)
APR_CTIME_LEN 매크로는 C의 시간 형식 문자열에 필요한 버퍼의 크기를 갖습니다. (apr_ctime함수 참조)
 
 
3) APR 시간관련 함수
 
이번에는 APR에서 제공하는 시간 관련 함수들에 대해 알아보겠습니다.
 
apr_time_t  apr_time_now (void) 
apr_status_t  apr_time_ansi_put (apr_time_t *result, time_t input) 
apr_status_t  apr_time_exp_tz (apr_time_exp_t *result, apr_time_t input, apr_int32_t offs) 
apr_status_t  apr_time_exp_gmt (apr_time_exp_t *result, apr_time_t input) 
apr_status_t  apr_time_exp_lt (apr_time_exp_t *result, apr_time_t input) 
apr_status_t  apr_time_exp_get (apr_time_t *result, apr_time_exp_t *input) 
apr_status_t  apr_time_exp_gmt_get (apr_time_t *result, apr_time_exp_t *input) 
void  apr_sleep (apr_interval_time_t t) 
apr_status_t  apr_rfc822_date (char *date_str, apr_time_t t) 
apr_status_t  apr_ctime (char *date_str, apr_time_t t) 
apr_status_t  apr_strftime (char *s, apr_size_t *retsize, apr_size_t max, const char *format, apr_time_exp_t *tm) 
void  apr_time_clock_hires (apr_pool_t *p) 
위에서 사용된 데이터 형들은 다음과 같이 정의되어 있습니다.
 
typedef apr_int64_t  apr_time_t                           ==> 64비트 정수
typedef apr_int64_t  apr_interval_time_t                ==> 64비트 정수
typedef apr_int32_t  apr_short_interval_time_t       ==> 32비트 정수
typedef apr_time_exp_t  apr_time_exp_t              ==> 구조체입니다.
 
여기서 apr_time_exp_t형은 구조체로서 ANSI C의 struct tm 형과 유사합니다.
다음과 같습니다.
 
struct apr_time_exp_t {
    apr_int32_t tm_usec;      // tm_sec 후로 지난 마이크로 초
    apr_int32_t tm_sec;       // tm_min 후로 지난 초 (0-61)
    apr_int32_t tm_min;       // tm_hour 후로 지난 분 (0-59)
    apr_int32_t tm_hour;      // 자정(midnight) 후로 지난 시간(0-23)
    apr_int32_t tm_mday;      // 월의 일자(1-31)
    apr_int32_t tm_mon;       // 년의 월 (0-11)
    apr_int32_t tm_year;      // 1900년 부터의 년
    apr_int32_t tm_wday;      // 일요일 부터의 요일 (0-6) - 즉, 0이 일요일
    apr_int32_t tm_yday;      // 1월 1일 부터의 일 (0-365) - 즉, 0이 1월 1일
    apr_int32_t tm_isdst;     // 일광절약시간
    apr_int32_t tm_gmtoff;    // 협정세계시(UTC)와의 차이 초
};
 
위의 구조체를 직접 채워서 사용하기는 좀 부담이 갑니다.
뭐 직접 채워서 사용하셔도 무방합니다만은... 잘못하면 서로 맞지않는 값이 들어갈 수도 있겠죠?
예를 들면 윤년이 아닌데도 29일을 지정한다거나 요일을 잘못 계산한다거나 하는...
 
우선 APR에서 제공하는 시간 관련 함수들을 알아보도록 하죠.
 
apr_time_now() : 지금현재의 시간을 리턴합니다.
apr_ctime() : apr_time_t 값을 입력받아 C의 표준 날짜형식의 문자열을 돌려줍니다. 이 문자열의 길이는 APR_CTIME_LEN 크기(25바이트)로 고정되어 있습니다. ANSI C의 ctime()함수와 유사한 기능을 제공하지만 ctime()함수는 문자열뒤에 \n문자를 넣어주는 것에 비해 apr_ctime()함수는 \n은 넣어주지는 않습니다. 물론 64비트의 날짜를 처리할 수 있다는 것도 다른 점이겠죠?
apr_rfc822_date() : apr_time_t 값을 입력받아 RFC822의 표준 날짜형식의 문자열을 돌려줍니다. 이 문자열의 길이는 APR_RFC822_DATE_LEN 크기(30바이트)로 고정되어 있습니다.
 
우선 여기까지의 사용법을 한번 보도록 하겠습니다.
 
 
#include "apr_time.h" int main(int argc, char *argv[]) { apr_time_t now; char str_ctime[APR_CTIME_LEN]; char str_rfctime[APR_RFC822_DATE_LEN]; now = apr_time_now(); apr_ctime(str_ctime, now); printf("NOW(CTIME): %s\n", str_ctime); apr_rfc822_date(str_rfctime, now); printf("NOW(RFC) : %s\n", str_rfctime); return 0; }
 
예제 자체는 그냥 현재 시간을 얻어서 CTIME형식과 RFC형식으로 각각 출력해 보는 것 입니다. 
다음의 위의 소스를 실행한 결과입니다. 
 
NOW(CTIME): Sat Sep 22 03:50:05 2007 NOW(RFC) : Fri, 21 Sep 2007 18:50:05 GMT
 
주의깊게 보면 CTIM으로 출력한 시간은 22일 새벽 3시 50분 05초 인데 RFC로 출력한 시간은 GMT로 계산되서 21일 18시 50분 05초로 출력이 되네요. 이것은 한국시간이 GMT보다 9시간 빠르기 때문입니다.
 
apr_time_ansi_put() : ANSI C의 시간 데이터 형인 time_t를 입력받아 apr_time_t 로 변환하여 저장해 줍니다.
apr_sleep() : apr_interval_time_t 형의 값을 입력받아 해당 시간 만큼 sleep합니다. 여기서 단위는 마이크로초입니다. 즉 1초를 sleep시킬려면 1000000을 입력해야 한다는거...
 
예제를 만들어 볼까요?
 
#include "apr_time.h" int main(int argc, char *argv[]) { time_t ansi; apr_time_t now; char str_ctime[APR_CTIME_LEN]; char str_rfctime[APR_RFC822_DATE_LEN]; time(&ansi); apr_time_ansi_put(&now, ansi); apr_ctime(str_ctime, now); printf("NOW(CTIME): %s\n", str_ctime); printf("Sleep...\n"); apr_sleep(1000000); printf("Walk Up...\n"); time(&ansi); apr_time_ansi_put(&now, ansi); apr_rfc822_date(str_rfctime, now); printf("NOW(RFC) : %s\n", str_rfctime); return 0; }
 
 
예제 자체는 그냥 현재 시간을 얻어서 ANSI C함수인 time()함수에 의해 얻어 와서 apr_time_t로 변환하고 이를 통해 문자열로 출력하면서 중간에 1초 sleep을 시키는 것입니다.
다음의 위의 소스를 실행한 결과입니다. 
 
NOW(CTIME): Sat Sep 22 04:11:39 2007 Sleep... Walk Up... NOW(RFC) : Fri, 21 Sep 2007 19:11:40 GMT
 
 
 - apr_strftime() : 이 함수는 날짜와 시간을 지정하는 형식으로 출력하기 위한 함수입니다.
ANSI C에서 strftime()이라는 함수가 있는데 실제 이것과 사용법은 거의 같습니다.
차이점이라면 strftime()함수는 struct tm형의 구조체 주소를 입력으로 받는데 apr_strftime()에서는 apr_time_exp_t 형의 구조체 주소를 입력으로 받는 다는 것과 strftime()함수는 만들어진 문자열의 크기를 리턴하는 것에 비해 apr_strftime()함수는 아큐먼트로 문자열의 크기를 저장해 준다는 것이 다릅니다.
apr_strftime()함수의 format에 사용할 수 있는 형식 문자들은 다음과 같은 것들이 있습니다.
 
%a : 단축형 요일 이름
%A : 완전한 요일 이름
%b : 단축형 월별 이름
%B : 완전한 월별 이름
%c : 날짜와 시간 출력(예를 들어, 10:41:50. 30-Jun-91)
%d : 10진수 01-31을 사용한 1개월 내의 일(日)
%H : 10진수 00-23을 사용한 1일 내의 시(時) - 24시간제
%I : 10진수 00-11을 사용한 1일 내의 시(時) - 12시간제
%j : 10진수 001-366을 사용한 1년 내의 일(日)
%m : 10진수 00-12를 사용한 1년 내의 월(月)
%M : 10진수 00-59를 사용한 1시간 내의 분
%p : AM이나 PM
%S : 10진수 00-59를 사용한 1분 내의 초
%U : 10진수 00-53을 사용한 1년 내의 주(週)
%w : 10진수 0-6을 사용한 요일 - 일요일은 0이다.
%W : 10진수 00-53을 사용한 1년 내의 주(週)
         - 한 주의 첫 번째 요일은 월요일이다.
%x : 날짜 출력(예를 들어, 30-Jun-91)
%X : 시간 출력(예를 들어, 10:41:50)
%y : 10진수 00-99을 사용한 세기(century) 부분이 없는 연도(年)
%Y : 10진수를 사용한 세기(century) 부분을 포함한 연도(年)
%Z : 유효한 지역이라면 시간대(time zone)의 이름, 그렇지 않다면 빈줄
%% : 하나의 백분율 기호(%)
뭐 여기까지는 좋은데 입력으로 사용되는 값이 apr_time_t가 아니라 apr_time_exp_t형을 사용하고 있습니다. 그런데 이 구조체에 올바른 값을 모두 채우기가 쉽지가 않죠.
그래서 apr_time_exp_t와 apr_time_t간의 변환 함수들을 제공합니다.
그런데 한가지 생각해 봐야 할게 있는데... TIME ZONE에 의해 시간이 지역에 따라 계산이 되어야 한다는 것입니다.
 
apr_time_t 에는 TIME ZONE을 지정할 수는 없습니다. 단순히 1970년 1월 1일 0시 0분 부터의 지나온 마이크로초의 값을 갖는 것 뿐이니까요. 그러나 apr_time_exp_t에는 TIME ZONE에 관련된 정보를 가질 수 있습니다. 그래서 변환 중에 좀 복잡해집니다. 참고로 apr_time_now()함수는 GMT로 지금 현재의 시간을 리턴하는 함수입니다.
 
apr_time_exp_gmt() : apr_time_t를 입력으로 받아 apr_time_exp_t로 변환합니다. 변환시 GMT로 계산하여 저장하게 됩니다.
apr_time_exp_lt() : apr_time_t를 입력으로 받아 apr_time_exp_t로 변환합니다. 변환시 Local Time으로 계산하여 저장하게 됩니다.
aprt_time_exp_tz() : apr_time_t를 입력으로 받아 apr_time_exp_t로 변환합니다. 변환시 세번째 인자로 GMT와 Local Time 차이를 초로 제공하여 계산된 결과를 저장하게 합니다..
 
어떻게 되는 건지 좀 어렵죠?
예를 들어보죠.
 
apr_time_t now=apr_time_now();
 
이렇게 하면 now라는 변수에 현재의 시간을 GMT "1970년 1월 1일 0시 0분 0초" 부터 흘러온 마이크로초가 저장됩니다.
 
apr_time_exp_t exptime;
apr_time_exp_gmt(&exptime, now);
 
라고 하면 exptime에 now의 시간을 GMT형식으로 저장합니다.
즉 현재 시간을 "2007년 9월 22일 16시 42분 32초"라고 한다면..
위 코드에 의해 exptime에는 다음과 같은 값들이 저장됩니다.
 
exptime.tm_year ==> 107     ==> 정확한 연도는 1900에 이 값을 더하면 됨
exptime.tm_mon ==> 8        ==> 1월 0으로 표기 하기 때문에 실제 월은 1을 더해야함
exptime.tm_mday ==> 22
exptime.tm_hour ==> 7        ==> 한국의 시간이 GMT보다 9시간 빠르므로 16시에서 9를 뺀값 저장됨
exptime.tm_min ==> 42
exptime.tm_sec ==> 32
exptime.tm_gmtoff  ==> 0     ==> GMT로 저장하였기 때문에 0이 저장됨
 
apr_time_exp_lt(&exptime, now);
 
라고 하면 exptime에는 위의 값 중에 다음값들만 변화되어 저장됩니다.
 
exptime.tm_hour ==> 16        ==> 실제 한국에서의 시간을 저장합니다.
exptime.tm_gmtoff  ==> 32400     ==> GMT로 부터 9시간이 더해 졌음을 초로 계산하여 저장합니다.
 
apr_time_exp_tz (&exptime, now, -5*60*60);
 
미국 산간 일광절약 표준시인 MDT는 GMT와 -5시간의 차이를 갖습니다.
그래서 위의 코드는 MDT형식으로 exptime에 저장하겠다는 의미가 됩니다.
exptime에는 다음의 값들이 변경됩니다.
 
exptime.tm_hour ==> 2        ==> GMT시간으로 7시였으니 거기서 5를 빼면 2가 되겠죠?
exptime.tm_gmtoff  ==> -18000     ==> GMT로 부터 5시간이 줄었음을 초로 계산하여 저장합니다.
 
이제 이해가 가실런지.. ^^;
 
이번에는 반대로 변환하는 함수입니다.
 
apr_status_t  apr_time_exp_tz (apr_time_exp_t *result, apr_time_t input, apr_int32_t offs) 
apr_status_t  apr_time_exp_gmt (apr_time_exp_t *result, apr_time_t input) 
apr_status_t  apr_time_exp_lt (apr_time_exp_t *result, apr_time_t input) 
apr_status_t  apr_time_exp_get (apr_time_t *result, apr_time_exp_t *input) 
apr_status_t  apr_time_exp_gmt_get (apr_time_t *result, apr_time_exp_t *input) 
 
apr_time_exp_get() : apr_time_exp_t를 입력받아 apr_time_t로 변환하여 돌려줍니다. 변환시 tm_gmtoff를 사용하지 않고 변환합니다.
apr_time_exp_gmt_get() : apr_time_exp_t를 입력받아 apr_time_t로 변환하여 돌려줍니다. 변환시 tm_gmtoff를 이용하여 GMT로 변환합니다.
 
이것도 말이 넘 어렵죠? ㅎㅎ
위에서 이야기한 예를 이용해 다시 설명하겠습니다.
apr_time_exp_t의 값을 그냥 채우기는 힘들기 때문에 다시 위의 apr_time_t를 apr_time_exp_t로 변환하는 함수를 사용하도록 하겠습니다.
 
apr_time_t now=apr_time_now();
apr_time_exp_gmt (&exptime, now);
 
이 코드에 의해 exptime에는 다음과 같은 값이 저장되었겠죠?
 
exptime.tm_year ==> 107
exptime.tm_mon ==> 8
exptime.tm_mday ==> 22
exptime.tm_hour ==> 7
exptime.tm_min ==> 42
exptime.tm_sec ==> 32
exptime.tm_gmtoff  ==> 0
 
apr_time_t result;
apr_time_exp_gmt_get (&result, &exptime);
apr_time_exp_get (&result, &exptime);
 
 
위의 코드에 의해 apr_time_exp_t를 다시 apr_time_t로 변환시켜 보는데 위의 두번의 변환 후 result의 값은 사실 같습니다. 왜냐하면 exptime변수의 tm_gmtoff가 0이기 때문에 이를 적용해서 변환하나 안 하나 값이 같기 때문이죠.
그럼 다른 예로 서로 값의 변화가 생기는 경우를 보겠습니다.
 
apr_time_exp_lt (&exptime, now);
위의 코드에 의해 exptime이 다음과 같이 저장될 것입니다.
 
exptime.tm_year ==> 107
exptime.tm_mon ==> 8
exptime.tm_mday ==> 22
exptime.tm_hour ==> 16
exptime.tm_min ==> 42
exptime.tm_sec ==> 32
exptime.tm_gmtoff  ==> 32400

apr_time_exp_gmt_get (&result, &exptime);
 
위의 코드는 tm_hour의 16시를 GMT로 변환하기 위해 tm_gmtoff값을 이용하여 9시를 빼서 계산 하여 result에 저장합니다.

apr_time_exp_get (&result, &exptime);
 
위의 코드는 tm_hour의 16시 그대로를 계산 하여 result에 저장합니다.
 
그래서 위 코드의 각각의 result는 서로 다른 값을 갖게됩니다.
주의 할 것은 두번째로 변환시킨 result값은 GMT값이 아니기 때문에 주의하여 사용하지 않으면 잘못된 시간을 가지고 프로그램이 돌아 갈 수 있습니다.
 
결론 적으로 시간을 GMT 기준으로 바꾸지 않고 계속 변환만을 하다보면 결국 올바른 시간을 잃어 버릴 수도 있습니다.
 
이제 위에서 설명했던 코드를 실제 프로그래밍 예제와 결과를 보여드리면서 함수 설명을 마치도록 하겠습니다.
 
 
#include "apr_time.h" int main(int argc, char *argv[]) { apr_time_t now, result; char strtime[100]; apr_time_exp_t exptime; apr_size_t size; now=apr_time_now(); apr_time_exp_gmt (&exptime, now); apr_strftime(strtime, &size, 100, "GMT Time : 날짜[%Y/%m/%d %A] 시간[%X]", &exptime); printf("%s\n", strtime); apr_time_exp_lt (&exptime, now); apr_strftime(strtime, &size, 100, "Local Time: 날짜[%Y/%m/%d %A] 시간[%X]", &exptime); printf("%s\n", strtime); apr_time_exp_tz (&exptime, now, -5*60*60); apr_strftime(strtime, &size, 100, "MDT Time : 날짜[%Y/%m/%d %A] 시간[%X]", &exptime); printf("%s\n", strtime); // now를 GMT로 exptime에 저장 apr_time_exp_gmt (&exptime, now); apr_time_exp_gmt_get (&result, &exptime); apr_ctime(strtime, result); printf("%s [now: %" APR_TIME_T_FMT "] [result: %" APR_TIME_T_FMT "]\n", strtime, now, result); apr_time_exp_get (&result, &exptime); apr_ctime(strtime, result); printf("%s [now: %" APR_TIME_T_FMT "] [result: %" APR_TIME_T_FMT "]\n", strtime, now, result); // now를 Local Time으로 exptime에 저장 apr_time_exp_lt (&exptime, now); apr_time_exp_gmt_get (&result, &exptime); apr_ctime(strtime, result); printf("%s [now: %" APR_TIME_T_FMT "] [result: %" APR_TIME_T_FMT "]\n", strtime, now, result); apr_time_exp_get (&result, &exptime); apr_ctime(strtime, result); printf("%s [now: %" APR_TIME_T_FMT "] [result: %" APR_TIME_T_FMT "]\n", strtime, now, result); return 0; }
 
다음은 위 코드의 실행 결과입니다.
 
GMT Time : 날짜[2007/09/22 Saturday] 시간[08:40:42] Local Time: 날짜[2007/09/22 Saturday] 시간[17:40:42] MDT Time : 날짜[2007/09/22 Saturday] 시간[03:40:42] Sat Sep 22 17:40:42 2007 [now: 1190450442921875] [result: 1190450442921875] Sat Sep 22 17:40:42 2007 [now: 1190450442921875] [result: 1190450442921875] Sat Sep 22 17:40:42 2007 [now: 1190450442921875] [result: 1190450442921875] Sun Sep 23 02:40:42 2007 [now: 1190450442921875] [result: 1190482842921875]
 
 
4) 기타
 
뭐 별로 중요하지는 않지만 다음과 같은 배열을 사용할 수 있습니다.
 
const char  apr_month_snames [12][4]  = 
{
    "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
const char  apr_day_snames [7][4] =
{
    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
 
 
그리고 설명 안 한 한가지 함수가 있습니다.

void  apr_time_clock_hires (apr_pool_t *p) 

이 함수는 apr_pool_t의 시간 정밀도를 높인다고 되어 있는데... UNIX/LINUX에서는 사용해도 아무일도 하지 않구요. 윈도우즈에서만 제 역할을 합니다. 내부적으로 SetTimerResolution()함수를 사용하는데..
솔직히 정확히 뭘하는건지 현재로서는 잘 모르겠습니다. 혹시 아시는 분은 답글 좀 달아주세요.
 
APR에서 조금 아쉬운 점은 년, 월, 일, 시, 분, 초를 더하고 빼는 함수들을 제공하지 않는다는 거네요.
예를 들면 23시에서 2시간을 더하게되면 일도 바뀌게 되도 일이 31일이였다면 달도 바뀌고해야 하니깐... 좀 복잡하잖아요. 뭐 위의 함수들을 조금 응용하면 할 수 있을 것 같긴하지만...
 
그럼 이번 강좌는 여기까지 입니다.
 
 
 
 
 
Creative Commons License
Creative Commons License이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Copyright 조희창(Nicholas Jo). Some rights reserved. http://bbs.nicklib.com