time_t 변수를 TTimeDate로 변환하는 방법 (DateUtils 에 있는 UnixToDateTime 함수 구현 원리)
절름발이 프로그래머/Delphi / 2011. 3. 5. 20:39
운영 체제에서는 time_t를 32 비트나 64 비트 부호있는 정수형으로 정의하며, UTC 1970-1-1 0:00:00 이후 경과한 초를 담고 있다. (이것이 바로 Unix Time 이라고 불린다.)
이것을 작성하게 된 계기는 PE 파일 헤러의 TimeDateStamp 값을 현재 시간으로 변환하는 과정에서 알게된 사실을 기억해두기 위해서이다. - 처음에는 변환 함수가 없는 것으로 생각했다가, 나중에 알고보니 UnixToDateTime() 함수가 있었다. 문제는 이 날짜,시간 관련 함수들은 DateUtils 유닛을 사용해야 한다.
수동으로 구현한 UnixToDateTime() 함수는 다음과 같다.
var
dt: TDateTime;
tzinfo: TTimeZoneInformation; // UTC 시간을 GMT 시간으로 변환하기 위해서,
GMT_Plus_Offset: Double;
begin
TSEdit.Text:=IntToHex(ImageNTHeaders.FileHeader.TimeDateStamp,8); // PE 헤더에 있는 TimeDateStamp 값을 가져온다.
tFlag:=ImageNTHeaders.FileHeader.TimeDateStamp;
case GetTimeZoneInformation(tzinfo) of // 현재 컴퓨터에서 타임존 정보를 읽어온다.
TIME_ZONE_ID_STANDARD: GMT_Plus_Offset := -(tzinfo.StandardBias + tzinfo.Bias) / (24*60); // 표준 타임존 일 경우,
TIME_ZONE_ID_DAYLIGHT: GMT_Plus_Offset := -(tzinfo.DaylightBias + tzinfo.Bias) / (24*60); // 일광절약시간을 적용하는 경우,
else // 매우 일반적인 경우,
GMT_Plus_Offset := -(tzinfo.Bias) / (24*60); // 한국의 경우에는 Bias 값이 -540 으로 9시간 * 60 분으로 지정되어 있다. 이것을 TTimeDate 객체로 변환하려면, 날짜 수로 변환해야 되서, 60분과 24시간으로 나누어준다.
end;
dt := EncodeDate(1970, 1, 1) + (tFlag / SecsPerDay) + GMT_Plus_Offset; // 변환 완료
edtTimeDateStampStr.Text := DateTimeToStr(dt); // GMT+9 시간을 출력한다.
end;
위에서 tzinfo를 얻는 과정을 제외하면, TimeDateStmap 값을 UTC 시간으로 변환할 수 있다. (너무 쉽다.)
이것을 작성하게 된 계기는 PE 파일 헤러의 TimeDateStamp 값을 현재 시간으로 변환하는 과정에서 알게된 사실을 기억해두기 위해서이다. - 처음에는 변환 함수가 없는 것으로 생각했다가, 나중에 알고보니 UnixToDateTime() 함수가 있었다. 문제는 이 날짜,시간 관련 함수들은 DateUtils 유닛을 사용해야 한다.
수동으로 구현한 UnixToDateTime() 함수는 다음과 같다.
var
dt: TDateTime;
tzinfo: TTimeZoneInformation; // UTC 시간을 GMT 시간으로 변환하기 위해서,
GMT_Plus_Offset: Double;
begin
TSEdit.Text:=IntToHex(ImageNTHeaders.FileHeader.TimeDateStamp,8); // PE 헤더에 있는 TimeDateStamp 값을 가져온다.
tFlag:=ImageNTHeaders.FileHeader.TimeDateStamp;
case GetTimeZoneInformation(tzinfo) of // 현재 컴퓨터에서 타임존 정보를 읽어온다.
TIME_ZONE_ID_STANDARD: GMT_Plus_Offset := -(tzinfo.StandardBias + tzinfo.Bias) / (24*60); // 표준 타임존 일 경우,
TIME_ZONE_ID_DAYLIGHT: GMT_Plus_Offset := -(tzinfo.DaylightBias + tzinfo.Bias) / (24*60); // 일광절약시간을 적용하는 경우,
else // 매우 일반적인 경우,
GMT_Plus_Offset := -(tzinfo.Bias) / (24*60); // 한국의 경우에는 Bias 값이 -540 으로 9시간 * 60 분으로 지정되어 있다. 이것을 TTimeDate 객체로 변환하려면, 날짜 수로 변환해야 되서, 60분과 24시간으로 나누어준다.
end;
dt := EncodeDate(1970, 1, 1) + (tFlag / SecsPerDay) + GMT_Plus_Offset; // 변환 완료
edtTimeDateStampStr.Text := DateTimeToStr(dt); // GMT+9 시간을 출력한다.
end;
위에서 tzinfo를 얻는 과정을 제외하면, TimeDateStmap 값을 UTC 시간으로 변환할 수 있다. (너무 쉽다.)