Dateutil.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:17k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 1995, 1996 AO ROSNO             }
  6. {         Copyright (c) 1997, 1998 Master-Bank          }
  7. {                                                       }
  8. {*******************************************************}
  9. unit DateUtil;
  10. {$I RX.INC}
  11. {$B-,V-,R-,Q-}
  12. interface
  13.   uses RTLConsts;
  14. function CurrentYear: Word;
  15. function IsLeapYear(AYear: Integer): Boolean;
  16. function DaysPerMonth(AYear, AMonth: Integer): Integer;
  17. function FirstDayOfPrevMonth: TDateTime;
  18. function LastDayOfPrevMonth: TDateTime;
  19. function FirstDayOfNextMonth: TDateTime;
  20. function ExtractDay(ADate: TDateTime): Word;
  21. function ExtractMonth(ADate: TDateTime): Word;
  22. function ExtractYear(ADate: TDateTime): Word;
  23. function IncDate(ADate: TDateTime; Days, Months, Years: Integer): TDateTime;
  24. function IncDay(ADate: TDateTime; Delta: Integer): TDateTime;
  25. function IncMonth(ADate: TDateTime; Delta: Integer): TDateTime;
  26. function IncYear(ADate: TDateTime; Delta: Integer): TDateTime;
  27. function ValidDate(ADate: TDateTime): Boolean;
  28. procedure DateDiff(Date1, Date2: TDateTime; var Days, Months, Years: Word);
  29. function MonthsBetween(Date1, Date2: TDateTime): Double;
  30. function DaysInPeriod(Date1, Date2: TDateTime): Longint;
  31.   { Count days between Date1 and Date2 + 1, so if Date1 = Date2 result = 1 }
  32. function DaysBetween(Date1, Date2: TDateTime): Longint;
  33.   { The same as previous but if Date2 < Date1 result = 0 }
  34. function IncTime(ATime: TDateTime; Hours, Minutes, Seconds, MSecs: Integer): TDateTime;
  35. function IncHour(ATime: TDateTime; Delta: Integer): TDateTime;
  36. function IncMinute(ATime: TDateTime; Delta: Integer): TDateTime;
  37. function IncSecond(ATime: TDateTime; Delta: Integer): TDateTime;
  38. function IncMSec(ATime: TDateTime; Delta: Integer): TDateTime;
  39. function CutTime(ADate: TDateTime): TDateTime; { Set time to 00:00:00:00 }
  40. type
  41.   TDateOrder = (doMDY, doDMY, doYMD);
  42.   TDayOfWeekName = (Sun, Mon, Tue, Wed, Thu, Fri, Sat);
  43.   TDaysOfWeek = set of TDayOfWeekName;
  44. { String to date conversions }
  45. function GetDateOrder(const DateFormat: string): TDateOrder;
  46. function MonthFromName(const S: string; MaxLen: Byte): Byte;
  47. function StrToDateDef(const S: string; Default: TDateTime): TDateTime;
  48. function StrToDateFmt(const DateFormat, S: string): TDateTime;
  49. function StrToDateFmtDef(const DateFormat, S: string; Default: TDateTime): TDateTime;
  50. function DefDateFormat(FourDigitYear: Boolean): string;
  51. function DefDateMask(BlanksChar: Char; FourDigitYear: Boolean): string;
  52. {$IFDEF WIN32}
  53. function FormatLongDate(Value: TDateTime): string;
  54. function FormatLongDateTime(Value: TDateTime): string;
  55. {$ENDIF}
  56. const
  57.   DefaultDateOrder = doDMY;
  58. {$IFDEF USE_FOUR_DIGIT_YEAR}
  59. var
  60.   FourDigitYear: Boolean;
  61. {$ELSE}
  62. function FourDigitYear: Boolean;
  63. {$ENDIF USE_FOUR_DIGIT_YEAR}
  64. const
  65.   CenturyOffset: Byte = 60;
  66. {$IFDEF WIN32}
  67.   NullDate: TDateTime = {-693594} 0;
  68. {$ELSE}
  69.   NullDate: TDateTime = 0;
  70. {$ENDIF}
  71. implementation
  72. uses SysUtils, {$IFDEF WIN32} Windows, {$ENDIF} Consts, rxStrUtils;
  73. function IsLeapYear(AYear: Integer): Boolean;
  74. begin
  75.   Result := (AYear mod 4 = 0) and ((AYear mod 100 <> 0) or (AYear mod 400 = 0));
  76. end;
  77. function DaysPerMonth(AYear, AMonth: Integer): Integer;
  78. const
  79.   DaysInMonth: array[1..12] of Integer =
  80.     (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  81. begin
  82.   Result := DaysInMonth[AMonth];
  83.   if (AMonth = 2) and IsLeapYear(AYear) then Inc(Result); { leap-year Feb is special }
  84. end;
  85. function FirstDayOfNextMonth: TDateTime;
  86. var
  87.   Year, Month, Day: Word;
  88. begin
  89.   DecodeDate(Date, Year, Month, Day);
  90.   Day := 1;
  91.   if Month < 12 then Inc(Month)
  92.   else begin
  93.     Inc(Year);
  94.     Month := 1;
  95.   end;
  96.   Result := EncodeDate(Year, Month, Day);
  97. end;
  98. function FirstDayOfPrevMonth: TDateTime;
  99. var
  100.   Year, Month, Day: Word;
  101. begin
  102.   DecodeDate(Date, Year, Month, Day);
  103.   Day := 1;
  104.   if Month > 1 then Dec(Month)
  105.   else begin
  106.     Dec(Year);
  107.     Month := 12;
  108.   end;
  109.   Result := EncodeDate(Year, Month, Day);
  110. end;
  111. function LastDayOfPrevMonth: TDateTime;
  112. var
  113.   D: TDateTime;
  114.   Year, Month, Day: Word;
  115. begin
  116.   D := FirstDayOfPrevMonth;
  117.   DecodeDate(D, Year, Month, Day);
  118.   Day := DaysPerMonth(Year, Month);
  119.   Result := EncodeDate(Year, Month, Day);
  120. end;
  121. function ExtractDay(ADate: TDateTime): Word;
  122. var
  123.   M, Y: Word;
  124. begin
  125.   DecodeDate(ADate, Y, M, Result);
  126. end;
  127. function ExtractMonth(ADate: TDateTime): Word;
  128. var
  129.   D, Y: Word;
  130. begin
  131.   DecodeDate(ADate, Y, Result, D);
  132. end;
  133. function ExtractYear(ADate: TDateTime): Word;
  134. var
  135.   D, M: Word;
  136. begin
  137.   DecodeDate(ADate, Result, M, D);
  138. end;
  139. function IncDate(ADate: TDateTime; Days, Months, Years: Integer): TDateTime;
  140. var
  141.   D, M, Y: Word;
  142.   Day, Month, Year: Longint;
  143. begin
  144.   DecodeDate(ADate, Y, M, D);
  145.   Year := Y; Month := M; Day := D;
  146.   Inc(Year, Years);
  147.   Inc(Year, Months div 12);
  148.   Inc(Month, Months mod 12);
  149.   if Month < 1 then begin
  150.     Inc(Month, 12);
  151.     Dec(Year);
  152.   end
  153.   else if Month > 12 then begin
  154.     Dec(Month, 12);
  155.     Inc(Year);
  156.   end;
  157.   if Day > DaysPerMonth(Year, Month) then Day := DaysPerMonth(Year, Month);
  158.   Result := EncodeDate(Year, Month, Day) + Days + Frac(ADate);
  159. end;
  160. procedure DateDiff(Date1, Date2: TDateTime; var Days, Months, Years: Word);
  161. { Corrected by Anatoly A. Sanko (2:450/73) }
  162. var
  163.   DtSwap: TDateTime;
  164.   Day1, Day2, Month1, Month2, Year1, Year2: Word;
  165. begin
  166.   if Date1 > Date2 then begin
  167.     DtSwap := Date1;
  168.     Date1 := Date2;
  169.     Date2 := DtSwap;
  170.   end;
  171.   DecodeDate(Date1, Year1, Month1, Day1);
  172.   DecodeDate(Date2, Year2, Month2, Day2);
  173.   Years := Year2 - Year1;
  174.   Months := 0;
  175.   Days := 0;
  176.   if Month2 < Month1 then begin
  177.     Inc(Months, 12);
  178.     Dec(Years);
  179.   end;
  180.   Inc(Months, Month2 - Month1);
  181.   if Day2 < Day1 then begin
  182.     Inc(Days, DaysPerMonth(Year1, Month1));
  183.     if Months = 0 then begin
  184.       Dec(Years);
  185.       Months := 11;
  186.     end
  187.     else Dec(Months);
  188.   end;
  189.   Inc(Days, Day2 - Day1);
  190. end;
  191. function IncDay(ADate: TDateTime; Delta: Integer): TDateTime;
  192. begin
  193.   Result := ADate + Delta;
  194. end;
  195. function IncMonth(ADate: TDateTime; Delta: Integer): TDateTime;
  196. begin
  197.   Result := IncDate(ADate, 0, Delta, 0);
  198. end;
  199. function IncYear(ADate: TDateTime; Delta: Integer): TDateTime;
  200. begin
  201.   Result := IncDate(ADate, 0, 0, Delta);
  202. end;
  203. function MonthsBetween(Date1, Date2: TDateTime): Double;
  204. var
  205.   D, M, Y: Word;
  206. begin
  207.   DateDiff(Date1, Date2, D, M, Y);
  208.   Result := 12 * Y + M;
  209.   if (D > 1) and (D < 7) then Result := Result + 0.25
  210.   else if (D >= 7) and (D < 15) then Result := Result + 0.5
  211.   else if (D >= 15) and (D < 21) then Result := Result + 0.75
  212.   else if (D >= 21) then Result := Result + 1;
  213. end;
  214. function IsValidDate(Y, M, D: Word): Boolean;
  215. begin
  216.   Result := (Y >= 1) and (Y <= 9999) and (M >= 1) and (M <= 12) and
  217.     (D >= 1) and (D <= DaysPerMonth(Y, M));
  218. end;
  219. function ValidDate(ADate: TDateTime): Boolean;
  220. var
  221.   Year, Month, Day: Word;
  222. begin
  223.   try
  224.     DecodeDate(ADate, Year, Month, Day);
  225.     Result := IsValidDate(Year, Month, Day);
  226.   except
  227.     Result := False;
  228.   end;
  229. end;
  230. function DaysInPeriod(Date1, Date2: TDateTime): Longint;
  231. begin
  232.   if ValidDate(Date1) and ValidDate(Date2) then
  233.     Result := Abs(Trunc(Date2) - Trunc(Date1)) + 1
  234.   else Result := 0;
  235. end;
  236. function DaysBetween(Date1, Date2: TDateTime): Longint;
  237. begin
  238.   Result := Trunc(Date2) - Trunc(Date1) + 1;
  239.   if Result < 0 then Result := 0;
  240. end;
  241. function IncTime(ATime: TDateTime; Hours, Minutes, Seconds,
  242.   MSecs: Integer): TDateTime;
  243. begin
  244.   Result := ATime + (Hours div 24) + (((Hours mod 24) * 3600000 +
  245.     Minutes * 60000 + Seconds * 1000 + MSecs) / MSecsPerDay);
  246.   if Result < 0 then Result := Result + 1;
  247. end;
  248. function IncHour(ATime: TDateTime; Delta: Integer): TDateTime;
  249. begin
  250.   Result := IncTime(ATime, Delta, 0, 0, 0);
  251. end;
  252. function IncMinute(ATime: TDateTime; Delta: Integer): TDateTime;
  253. begin
  254.   Result := IncTime(ATime, 0, Delta, 0, 0);
  255. end;
  256. function IncSecond(ATime: TDateTime; Delta: Integer): TDateTime;
  257. begin
  258.   Result := IncTime(ATime, 0, 0, Delta, 0);
  259. end;
  260. function IncMSec(ATime: TDateTime; Delta: Integer): TDateTime;
  261. begin
  262.   Result := IncTime(ATime, 0, 0, 0, Delta);
  263. end;
  264. function CutTime(ADate: TDateTime): TDateTime;
  265. begin
  266.   Result := Trunc(ADate);
  267. end;
  268. function CurrentYear: Word; {$IFNDEF WIN32} assembler; {$ENDIF}
  269. {$IFDEF WIN32}
  270. var
  271.   SystemTime: TSystemTime;
  272. begin
  273.   GetLocalTime(SystemTime);
  274.   Result := SystemTime.wYear;
  275. end;
  276. {$ELSE}
  277. asm
  278.         MOV     AH,2AH
  279.         INT     21H
  280.         MOV     AX,CX
  281. end;
  282. {$ENDIF}
  283. { String to date conversions. Copied from SYSUTILS.PAS unit. }
  284. procedure ScanBlanks(const S: string; var Pos: Integer);
  285. var
  286.   I: Integer;
  287. begin
  288.   I := Pos;
  289.   while (I <= Length(S)) and (S[I] = ' ') do Inc(I);
  290.   Pos := I;
  291. end;
  292. function ScanNumber(const S: string; MaxLength: Integer; var Pos: Integer;
  293.   var Number: Longint): Boolean;
  294. var
  295.   I: Integer;
  296.   N: Word;
  297. begin
  298.   Result := False;
  299.   ScanBlanks(S, Pos);
  300.   I := Pos;
  301.   N := 0;
  302.   while (I <= Length(S)) and (Longint(I - Pos) < MaxLength) and
  303.     (S[I] in ['0'..'9']) and (N < 1000) do
  304.   begin
  305.     N := N * 10 + (Ord(S[I]) - Ord('0'));
  306.     Inc(I);
  307.   end;
  308.   if I > Pos then begin
  309.     Pos := I;
  310.     Number := N;
  311.     Result := True;
  312.   end;
  313. end;
  314. function ScanChar(const S: string; var Pos: Integer; Ch: Char): Boolean;
  315. begin
  316.   Result := False;
  317.   ScanBlanks(S, Pos);
  318.   if (Pos <= Length(S)) and (S[Pos] = Ch) then begin
  319.     Inc(Pos);
  320.     Result := True;
  321.   end;
  322. end;
  323. {$IFDEF RX_D3}
  324. procedure ScanToNumber(const S: string; var Pos: Integer);
  325. begin
  326.   while (Pos <= Length(S)) and not (S[Pos] in ['0'..'9']) do begin
  327.     if S[Pos] in LeadBytes then Inc(Pos);
  328.     Inc(Pos);
  329.   end;
  330. end;
  331. {$ENDIF}
  332. function GetDateOrder(const DateFormat: string): TDateOrder;
  333. var
  334.   I: Integer;
  335. begin
  336.   Result := DefaultDateOrder;
  337.   I := 1;
  338.   while I <= Length(DateFormat) do begin
  339.     case Chr(Ord(DateFormat[I]) and $DF) of
  340. {$IFDEF RX_D3}
  341.       'E': Result := doYMD;
  342. {$ENDIF}
  343.       'Y': Result := doYMD;
  344.       'M': Result := doMDY;
  345.       'D': Result := doDMY;
  346.     else
  347.       Inc(I);
  348.       Continue;
  349.     end;
  350.     Exit;
  351.   end;
  352.   Result := DefaultDateOrder; { default }
  353. end;
  354. function ExpandYear(Year: Integer): Integer;
  355. var
  356.   N: Longint;
  357. begin
  358.   Result := Year;
  359.   if Result < 100 then begin
  360.     N := CurrentYear - CenturyOffset;
  361.     Inc(Result, N div 100 * 100);
  362.     if (CenturyOffset > 0) and (Result < N) then
  363.       Inc(Result, 100);
  364.   end;
  365. end;
  366. function ScanDate(const S, DateFormat: string; var Pos: Integer;
  367.   var Y, M, D: Integer): Boolean;
  368. var
  369.   DateOrder: TDateOrder;
  370.   N1, N2, N3: Longint;
  371. begin
  372.   Result := False;
  373.   Y := 0; M := 0; D := 0;
  374.   DateOrder := GetDateOrder(DateFormat);
  375. {$IFDEF RX_D3}
  376.   if ShortDateFormat[1] = 'g' then { skip over prefix text }
  377.     ScanToNumber(S, Pos);
  378. {$ENDIF RX_D3}
  379.   if not (ScanNumber(S, MaxInt, Pos, N1) and ScanChar(S, Pos, DateSeparator) and
  380.     ScanNumber(S, MaxInt, Pos, N2)) then Exit;
  381.   if ScanChar(S, Pos, DateSeparator) then begin
  382.     if not ScanNumber(S, MaxInt, Pos, N3) then Exit;
  383.     case DateOrder of
  384.       doMDY: begin Y := N3; M := N1; D := N2; end;
  385.       doDMY: begin Y := N3; M := N2; D := N1; end;
  386.       doYMD: begin Y := N1; M := N2; D := N3; end;
  387.     end;
  388.     Y := ExpandYear(Y);
  389.   end
  390.   else begin
  391.     Y := CurrentYear;
  392.     if DateOrder = doDMY then begin
  393.       D := N1; M := N2;
  394.     end
  395.     else begin
  396.       M := N1; D := N2;
  397.     end;
  398.   end;
  399.   ScanChar(S, Pos, DateSeparator);
  400.   ScanBlanks(S, Pos);
  401. {$IFDEF RX_D3}
  402.   if SysLocale.FarEast and (System.Pos('ddd', ShortDateFormat) <> 0) then
  403.   begin { ignore trailing text }
  404.     if ShortTimeFormat[1] in ['0'..'9'] then  { stop at time digit }
  405.       ScanToNumber(S, Pos)
  406.     else  { stop at time prefix }
  407.       repeat
  408.         while (Pos <= Length(S)) and (S[Pos] <> ' ') do Inc(Pos);
  409.         ScanBlanks(S, Pos);
  410.       until (Pos > Length(S)) or
  411.         (AnsiCompareText(TimeAMString, Copy(S, Pos, Length(TimeAMString))) = 0) or
  412.         (AnsiCompareText(TimePMString, Copy(S, Pos, Length(TimePMString))) = 0);
  413.   end;
  414. {$ENDIF RX_D3}
  415.   Result := IsValidDate(Y, M, D) and (Pos > Length(S));
  416. end;
  417. function MonthFromName(const S: string; MaxLen: Byte): Byte;
  418. begin
  419.   if Length(S) > 0 then
  420.     for Result := 1 to 12 do begin
  421.       if (Length(LongMonthNames[Result]) > 0) and
  422.         (AnsiCompareText(Copy(S, 1, MaxLen),
  423.         Copy(LongMonthNames[Result], 1, MaxLen)) = 0) then Exit;
  424.     end;
  425.   Result := 0;
  426. end;
  427. procedure ExtractMask(const Format, S: string; Ch: Char; Cnt: Integer;
  428.   var I: Integer; Blank, Default: Integer);
  429. var
  430.   Tmp: string[20];
  431.   J, L: Integer;
  432. begin
  433.   I := Default;
  434.   Ch := UpCase(Ch);
  435.   L := Length(Format);
  436.   if Length(S) < L then L := Length(S)
  437.   else if Length(S) > L then Exit;
  438.   J := Pos(MakeStr(Ch, Cnt), AnsiUpperCase(Format));
  439.   if J <= 0 then Exit;
  440.   Tmp := '';
  441.   while (UpCase(Format[J]) = Ch) and (J <= L) do begin
  442.     if S[J] <> ' ' then Tmp := Tmp + S[J];
  443.     Inc(J);
  444.   end;
  445.   if Tmp = '' then I := Blank
  446.   else if Cnt > 1 then begin
  447.     I := MonthFromName(Tmp, Length(Tmp));
  448.     if I = 0 then I := -1;
  449.   end
  450.   else I := StrToIntDef(Tmp, -1);
  451. end;
  452. function ScanDateStr(const Format, S: string; var D, M, Y: Integer): Boolean;
  453. var
  454.   Pos: Integer;
  455. begin
  456.   ExtractMask(Format, S, 'm', 3, M, -1, 0); { short month name? }
  457.   if M = 0 then ExtractMask(Format, S, 'm', 1, M, -1, 0);
  458.   ExtractMask(Format, S, 'd', 1, D, -1, 1);
  459.   ExtractMask(Format, S, 'y', 1, Y, -1, CurrentYear);
  460.   Y := ExpandYear(Y);
  461.   Result := IsValidDate(Y, M, D);
  462.   if not Result then begin
  463.     Pos := 1;
  464.     Result := ScanDate(S, Format, Pos, Y, M, D);
  465.   end;
  466. end;
  467. function InternalStrToDate(const DateFormat, S: string;
  468.   var Date: TDateTime): Boolean;
  469. var
  470.   D, M, Y: Integer;
  471. begin
  472.   if S = '' then begin
  473.     Date := NullDate;
  474.     Result := True;
  475.   end
  476.   else begin
  477.     Result := ScanDateStr(DateFormat, S, D, M, Y);
  478.     if Result then
  479.     try
  480.       Date := EncodeDate(Y, M, D);
  481.     except
  482.       Result := False;
  483.     end;
  484.   end;
  485. end;
  486. function StrToDateFmt(const DateFormat, S: string): TDateTime;
  487. begin
  488.   if not InternalStrToDate(DateFormat, S, Result) then
  489.     raise EConvertError.CreateFmt({$IFDEF RX_D3} SInvalidDate {$ELSE}
  490.       LoadStr(SInvalidDate) {$ENDIF}, [S]);
  491. end;
  492. function StrToDateDef(const S: string; Default: TDateTime): TDateTime;
  493. begin
  494.   if not InternalStrToDate(ShortDateFormat, S, Result) then
  495.     Result := Trunc(Default);
  496. end;
  497. function StrToDateFmtDef(const DateFormat, S: string; Default: TDateTime): TDateTime;
  498. begin
  499.   if not InternalStrToDate(DateFormat, S, Result) then
  500.     Result := Trunc(Default);
  501. end;
  502. function DefDateFormat(FourDigitYear: Boolean): string;
  503. begin
  504.   if FourDigitYear then begin
  505.     case GetDateOrder(ShortDateFormat) of
  506.       doMDY: Result := 'MM/DD/YYYY';
  507.       doDMY: Result := 'DD/MM/YYYY';
  508.       doYMD: Result := 'YYYY/MM/DD';
  509.     end;
  510.   end
  511.   else begin
  512.     case GetDateOrder(ShortDateFormat) of
  513.       doMDY: Result := 'MM/DD/YY';
  514.       doDMY: Result := 'DD/MM/YY';
  515.       doYMD: Result := 'YY/MM/DD';
  516.     end;
  517.   end;
  518. end;
  519. function DefDateMask(BlanksChar: Char; FourDigitYear: Boolean): string;
  520. begin
  521.   if FourDigitYear then begin
  522.     case GetDateOrder(ShortDateFormat) of
  523.       doMDY, doDMY: Result := '!99/99/9999;1;';
  524.       doYMD: Result := '!9999/99/99;1;';
  525.     end;
  526.   end
  527.   else begin
  528.     case GetDateOrder(ShortDateFormat) of
  529.       doMDY, doDMY: Result := '!99/99/99;1;';
  530.       doYMD: Result := '!99/99/99;1;';
  531.     end;
  532.   end;
  533.   if Result <> '' then Result := Result + BlanksChar;
  534. end;
  535. {$IFDEF WIN32}
  536. function FormatLongDate(Value: TDateTime): string;
  537. var
  538.   Buffer: array[0..1023] of Char;
  539.   SystemTime: TSystemTime;
  540. begin
  541. {$IFDEF RX_D3}
  542.   DateTimeToSystemTime(Value, SystemTime);
  543. {$ELSE}
  544.   with SystemTime do begin
  545.     DecodeDate(Value, wYear, wMonth, wDay);
  546.     DecodeTime(Value, wHour, wMinute, wSecond, wMilliseconds);
  547.   end;
  548. {$ENDIF}
  549.   SetString(Result, Buffer, GetDateFormat(GetThreadLocale, DATE_LONGDATE,
  550.     @SystemTime, nil, Buffer, SizeOf(Buffer) - 1));
  551.   Result := TrimRight(Result);
  552. end;
  553. function FormatLongDateTime(Value: TDateTime): string;
  554. begin
  555.   if Value <> NullDate then
  556.     Result := FormatLongDate(Value) + FormatDateTime(' tt', Value)
  557.   else Result := '';
  558. end;
  559. {$ENDIF WIN32}
  560. {$IFNDEF USE_FOUR_DIGIT_YEAR}
  561. function FourDigitYear: Boolean;
  562. begin
  563.   Result := Pos('YYYY', AnsiUpperCase(ShortDateFormat)) > 0;
  564. end;
  565. {$ENDIF}
  566. {$IFDEF USE_FOUR_DIGIT_YEAR}
  567. initialization
  568.   FourDigitYear := Pos('YYYY', AnsiUpperCase(ShortDateFormat)) > 0;
  569. {$ENDIF}
  570. end.