삽질하는플머

php-xmlrpc 에서 시간함수 문제

탐구생활/WEB 관련

상황은 이렇다. 


델파이로 만든 XMLRPC 클라이언트에서 "시간값"을 인자로 PHP로 만든 XMLRPC 서버의 함수를 실행하고

이 값을 MySQL의 타임스탬프 필드에 저장하자. 


xml-rpc 의 시간표시는 iso 8601 에 따라 다음과 같이 표시된다.

  • 2011-08-24T00:00:00

xmlrpc.inc 에는 이 형식과 유닉스 타임스탬프 사이의 변환을 위해 iso8601_encode, iso8601_decode 함수가 정의되어있다. 
이렇게 변환한 유닉스 타임스탬프값을 MySQL에 집어넣기 위해 MySQL 내장함수인 FROM_UNIXTIME() 을 사용해 봤는데
클라에서 전송한 시간보다 +9 시간 더 나오는 문제가 발생. iso8681_decode의 두번째 인자에 1을 주어 UTC로 풀어도 마찬가지.

RPC 테스트중인 윈도의 PHP는 현재시간이 UTC로 설정되어있다. 그런데 시스템시간은 한국. 그래서 생기는 문제인 듯. 
실제로 다음과 같은 코드로 타임존을 설정하면 제대로 처리된다.


date_default_timezone_set("Asia/Seoul");


NAS, 또는 우분투의 PHP에서 echo date_default_timezone_get(); 을 찍어보면 Asia/Seoul 이 잘 출력되는 것을 보아 윈도용 WAMP의 PHP에서 시스템의 설정을 읽지 못하는 문제로 보인다. 그렇다고 코드에 저걸 무조건 박아넣기도 골룸.


date로 문자열 꾸미기도 시도해 봄. 


1 $tt = iso8601_decode($ExpireDate);
2 $ts = date("Y-m-d G:i:s", $tt);

하지만 iso8601_decode 내부에서 gmmkttime, 또는 mktime 을 실행시키면서 타임존 문제가 생김. 


뭐가 어쨌건 시스템의 날짜 설정과 무관하게 델파이에서 전송한 시간값을 MySQL에 입력하기만 하면 되므로...
iso8601_decode 의 앞부분을 흉내내 이렇게 만들어 봄. 

1 function iso8601_time_to_mysql($idate) {
2     if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $idate, $regs)) {
3         return sprintf("%s-%s-%s %s:%s:%s", $regs[1], $regs[2], $regs[3], $regs[4], $regs[5], $regs[6]);
4     } else
5         return NULL;
6 }    


요는, php의 시간변환 함수를 사용하지 말자는 것. 
비슷한 요령으로 역변환도 만들어 둠. 

1 function mysql_time_to_iso8601($idate) {
2     if (preg_match('/([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/', $idate, $regs)) {
3         return sprintf("%s%s%sT%s:%s:%s", $regs[1], $regs[2], $regs[3], $regs[4], $regs[5], $regs[6]);
4     } else
5         return NULL;
6 }


이제 델파이에서 의도한 시간값이 PHP를 거쳐 MySQL로 제대로 꽂힌다. .



여담으로, date('Z') 로 얻어낸 값에는 현재 설정된 타임존과 UTC 사이의 분단위 시간차이가 들어있다.
GetTimeZoneInformation() 으로 얻어낸 TimeZhoeBias 값과 동일. 그냥 까먹을까봐 적어둠.