프로그래밍/델파이

GetSystemTime과 TDateTime, FILETIME

채윤아빠 2008. 10. 14. 16:17
728x90
반응형

GetSystemTime으로 얻은 SYSTEMTIME 구조체를 사용할 때, 주의해야할 점은 SYSTEMTIME 구조체의 시각 정보가 UTC 표준 시각이라는 점입니다.
우리가 일반적으로 사용하는 TDateTime이나, FILETIME은 현재 TimeZone의 시각이므로, 지역별로 차이가 존재하게 됩니다.
세계 각 지역별 UTC 시각와의 차이는 http://rimy.co.kr/entry/UTC-%EA%B8%B0%EC%A4%80-%EC%84%B8%EA%B3%84-%EC%8B%9C%EA%B0%84-%EC%B0%A8 여기서 확인해 보시면 됩니다.

이 때문에 GetSystemTime이나, FILETIME에서 변환된 SYSTEMTIME을 델파이의 SystemTimeToDateTime 함수에 논리적 버그가 생깁니다.
위의 SYSTEMTIME을 TDateTime 형으로 변경하고자 할 때, 프로그램이 실행중인 지역의 TimeZone을 고려하여 변환이 되어야 하는데, 그런 고려없이 그냥 보이는 시각 그대로 SYSTEMTIME으로 변환이 되어 버려 TimeZone별 차이가 나게 됩니다.

예를 들면,
GetSystemTime으로 현재 시각을 얻어서 SystemTimeToDateTime으로 변환하면 9시간 늦은 UTC 시각이 반환되게 됩니다.

var
  stSystem: SYSTEMTIME;
begin
  GetSystemTime(stSystem);
  ShowMessage(DateTimeToStr(SystemTimeToDateTime(stSystem)));
end;



위의 예제에서는 GetLocalTime을 사용하면 간단하게 해결이 되는데, FILETIME 등과 연계해서 사용하게 되면, 델파이에서는 반드시 TimeZone을 생각해서 시간차를 계산해 주어야만 합니다. 그래야 올바른 시간이 계산됩니다.

아래는 UTC 와 현 지역의 TimeZone 시각과의 차이를 구하는 방법입니다. 참고하셔서 이용하시면 될것 같습니다.

var
  stLocal, stSystem: SYSTEMTIME;
  dtLocal, dtSystem, dtGap: TDateTime;
begin
  GetLocalTime(stLocal);
  dtLocal := SystemTimeToDateTime(stLocal);
  GetSystemTime(stSystem);
  dtSystem := SystemTimeToDateTime(stSystem);
  dtGap := dtLocal - dtSystem;


dtGap에 UTC 시각과 현 지역의 시간차가 들어가 있습니다. 이를 SYSTEMTIME 변환시에 고려하여 입력해 주면 됩니다.