프로그래밍/델파이

StrToDateTime, StrToDateTimeDef, TFormatSettings 관계 둘러보기

채윤아빠 2008. 1. 29. 16:14
728x90
반응형

문자열을 날짜로 변환하는 경우에 사용하는 함수가 StrToDateTime, StrToDateTimeDef 입니다.
이 함수는 다음과 같이 선언되어 있습니다.

function StrToDateTime(const S: string): TDateTime; overload;
function StrToDateTime(const S: string; const FormatSettings: TFormatSettings): TDateTime; overload;

function StrToDateTimeDef(const S: string; const Default: TDateTime): TDateTime; overload;
function StrToDateTimeDef(const S: string; const Default: TDateTime; const FormatSettings: TFormatSettings): TDateTime; overload;
함수 선언에 보면 TFormatSettings 레코드를 넘겨주는 경우가 있습니다.
일반적으로 한국에서는 날짜 구분을 '-' 문자로 합니다. 하지만 영어권에서는 '/' 문자를 기준으로 합니다.
해당 언어권의 날짜와 다른 형태의 날짜 문자열을 변환할 때는 마지막의 TFormatSettings 레코드를 올바로 설정한 이후에 StrToDateTime, StrToDateTimeDef 함수를 이용하면 올바로 날짜 형태의 데이터로 변환됩니다.
그렇지 않고 직접 날짜 문자열의 틀린 문자들을 직접 StringReplace 함수를 이용하여 올바르게 바꾼 후에 StrToDateTime, StrToDateTimeDef 함수를 이용할 수도 있겠지요.
어쨌든 날짜 문자열을 바꿀때는 언어권에 따라서 StrToDateTime, StrToDateTimeDef 함수를 잘 이용해야 합니다.

다음과 같이 변환하는 코드가 있다고 가정하면,
procedure TForm1.Button1Click(Sender: TObject);
var
  dtDate: TDateTime;
begin
  dtDate:= StrToDateTimeDef('2001.10.10', 0, AFormatSettings);
  Memo1.Lines.Add(FormatDateTime('yyyy-mm-dd', dtDate));
  dtDate:= StrToDateTimeDef('2001/10/10', 0, AFormatSettings);
  Memo1.Lines.Add(FormatDateTime('yyyy-mm-dd', dtDate));
  dtDate:= StrToDateTimeDef('2001-10-10', 0);
  Memo1.Lines.Add(FormatDateTime('yyyy-mm-dd', dtDate));
end
결과는 다음과 같이 됩니다
1899-12-30
1899-12-30
2001-10-10
'2001.10.10', '2001/10/10'의 경우는 올바로 변환이 되지 않습니다. 날짜 구분 기호가 틀리기 때문입니다.
하지만 이를 약간 변형하여 TFormatSettings 레코드에 날짜 구분 기호를 날짜 문자열에 있는 문자로 변경하여 함수를 호출하에 되면 올바른 날짜로 변환이 됩니다.
procedure TForm1.Button1Click(Sender: TObject);
var
  dtDate: TDateTime;
  AFormatSettings : TFormatSettings;
begin
  GetLocaleFormatSettings(GetUserDefaultLCID, AFormatSettings);
  AFormatSettings.DateSeparator := '.';
  dtDate:= StrToDateTimeDef('2001.10.10', 0, AFormatSettings);
  Memo1.Lines.Add(FormatDateTime('yyyy-mm-dd', dtDate));
  AFormatSettings.DateSeparator := '/';
  dtDate:= StrToDateTimeDef('2001/10/10', 0, AFormatSettings);
  Memo1.Lines.Add(FormatDateTime('yyyy-mm-dd', dtDate));
  dtDate:= StrToDateTimeDef('2001-10-10', 0);
  Memo1.Lines.Add(FormatDateTime('yyyy-mm-dd', dtDate));
end;
실행한 결과는 다음과 같습니다.
2001-10-10
2001-10-10
2001-10-10

앞의 예에서, TFormatSettings 레코드를 사용하지 않고, 다음과 같이 하여도 동일하게 올바른 결과를 얻을 수 있습니다.
procedure TForm1.Button1Click(Sender: TObject);
var
  dtDate: TDateTime;
begin
  dtDate:= StrToDateTimeDef(StringReplace('2001.10.10', '.', DateSeparator, [rfReplaceAll]), 0, AFormatSettings);
  Memo1.Lines.Add(FormatDateTime('yyyy-mm-dd', dtDate));
  dtDate:= StrToDateTimeDef(StringReplace('2001/10/10', '.', DateSeparator, [rfReplaceAll]), 0, AFormatSettings);
  Memo1.Lines.Add(FormatDateTime('yyyy-mm-dd', dtDate));
  dtDate:= StrToDateTimeDef(StringReplace('2001-10-10', '.', DateSeparator, [rfReplaceAll]), 0);
  Memo1.Lines.Add(FormatDateTime('yyyy-mm-dd', dtDate));
end
SysUtils.DateSeparator에 전역변수로 선언이 되어 있는 문자가 날짜 구분기호로, 잘못된 날짜 구문기호를 올바른 문자 기호로 변경합니다.