델파이

DateSeparator 로케일에 따른 날짜포맷 변경

미스터몽키 2018. 9. 15. 11:37

델파이 2007버전에 있던 DateSeparator 는

XE부터는 FormatSettings.DateSeparator 으로 사용해야한다.  XE부터는 System.SysUtils 유닛에 있다.

 

우리나라 Locale에서 기본 날짜 포맷은 'yyyy-mm-dd' 이고 미국은 'mm/dd/yyyy' 가 기본이다.

 

한글 윈도우 기본 로케일에서 다음 2가지는 동일한 "yyyy-mm-dd hh:nn:ss" ("2018-09-05 13:08:12") 를 표시한다.

FormatDateTime('yyyy-mm-dd hh:nn:ss', Now);

FormatDateTime('yyyy/mm/dd hh:nn:ss', Now);

 

이유는 "/" 가 프로그램에 설정된 FormatSettings.DateSeparator 값을 의미하지 "/" (슬래시) 자체 문자를 의미하지 않기 때문이다.

 

즉 FormatSettings.DateSeparator 가 "-" (대시)로 설정되어 있기 때문이다.

 

슬래시("/")로 날짜를 구분하고 싶다면  FormatSettings.DateSeparator := '/'; 로 변경하고 FormatDateTime함수를 사용하면 된다.

 

StrToDateTime, StrToDate, StrToDateTimeDef, StrToDateDef  등은 시스템 기본 날짜포맷 형식의 문자열을 날짜형으로 변경한다.

 

즉 시스템 기본 날짜포맷이 "yyyy-mm-dd" 일때 함수 StrToDate('2018-09-05') 는 날짜형 값을 리턴한다. 

 

그런데 간혹 제어판에서 날짜 포맷을 미국 형식의 "mm/dd/yyyy" 로 변경하고 사용하는 사용자가 있다.

이런 경우 함수 StrToDate('2018-09-05') 는 에러가 발생하거나 엉뚱한 값을 리턴한다.

 

프로그램 사용자 마다 시스템 날짜 포맷을 변경하라고 할 수는 없다.

 

이를 해결하려면 프로그램 시작부분에서

 

FormatSettings.ShortDateFormat := 'yyyy-mm-dd';
 FormatSettings.LongDateFormat := 'yyyy-mm-dd';
 FormatSettings.ShortTimeFormat := 'hh:mm:ss';
 FormatSettings.LongTimeFormat := 'hh:mm:ss';
 FormatSettings.DateSeparator := '-';
 

설정하여 프로그램 내에서는 날짜표시 형식을 통일하면 StrToDate 함수 등이 원할하게 사용할 수 있다. 

 

또 다른 방법은 StrToDate 함수의 마지막 파라미터인 FormatSettings를 사용하여 매번 문자열포맷에 따라 날짜로 변환하는 방법도 있다.

 

 
procedure TfrmSGridmain.Button48Click(Sender: TObject);
var sDT : string;
    Fmt : TFormatSettings;
    vdT : TDateTime;
begin
  fmt.ShortDateFormat:='yyyy-mm-dd';   //미국식은 'mm/dd/yyyy';
  fmt.DateSeparator  := '-';                     //미국식은 '/';
  fmt.LongTimeFormat :='hh:nn:ss';
  fmt.TimeSeparator  :=':';
 
 
  DateTimePicker5.DateTime := StrToDateTimeDef(Edit9.Text, StartOfTheYear(Now), Fmt);
end;
 
 

 

 

편리한 방법은 당연히 프로그램 시작부분에서 FormatSettings.ShortDateFormat 등을 설정하는 것이다.

하지만 상황에 따라 두번째 방법이 필요할 때도 있다.

 

여담이지만 미국식 날짜표현이 실 생활에서는 더 가독성이 좋다.  오늘이 몇년인지 보다는 몇월 몇일 인지가 더 알고 싶은 자료이니 앞쪽에 배치하는 것이 효율적이다.

그러나 전산에서 정렬, 비교 등을 할 때는 년->월->일 순으로 되어있는것이 효율적이다.

 

우리나라 날짜 표시 형식을 처음 누가 설정했을까 궁금하다.

 

(추가)

운영체제 기본 날짜, 시간 포맷을 확인해보니 다음과 같이 월(Month) 과 분(Minute) 모두 'mm' 이었다.

 

 

FormatSettings.ShortDateFormat  := 'yyyy-mm-dd';
FormatSettings.ShortTimeFormat  := 'hh:mm';
FormatSettings.LongTimeFormat   := 'hh:mm:ss';

 

테스트 해 보아도 다음과 같이 이상하게 정확하게 잘 표현되었다.

 

FormatDateTime('yyyy-mm-dd hh:mm:ss', Now)  -> '2020-08-15 15:16:52'

FormatDateTime('yyyy-mm-dd hh:nn:ss', Now)  -> '2020-08-15 15:16:52'

 

하지만 다음과 같이 시(hh) 부분이 없을 경우는 'nn' 이 정확하게 분을 표현했고  'mm' 은 월을 표현했다.

 

FormatDateTime('yyyy-mm-dd mm:ss', Now)  -> '2020-08-15 08:52'

FormatDateTime('yyyy-mm-dd nn:ss', Now) -> '2020-08-15 16:52'

 

결국 분(Minute)을 표현하는 정확한 포맷은 'nn' 이지만  앞에 시(hh)가 있을 때는 'mm' 도 분을 표현한다.