lazarus-ccr/components/systools/source/general/run/stdatest.pas
wp_xxyyzz 543cdf06d9 systools: Rearrange units and packages
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6159 8e941d3f-bd1b-0410-a28a-d453659cc2b4
2018-01-30 16:17:37 +00:00

1112 lines
34 KiB
ObjectPascal

// Upgraded to Delphi 2009: Sebastian Zierer
(* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is TurboPower SysTools
*
* The Initial Developer of the Original Code is
* TurboPower Software
*
* Portions created by the Initial Developer are Copyright (C) 1996-2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* SysTools: StDateSt.pas 4.04 *}
{*********************************************************}
{* SysTools: Date and time string manipulation *}
{*********************************************************}
{$IFDEF FPC}
{$mode DELPHI}
{$ENDIF}
{$I StDefine.inc}
unit StDateSt;
interface
uses
{$IFNDEF FPC}
Windows,
{$ENDIF}
SysUtils,
StStrS,
StStrL,
StConst,
StBase,
StUtils,
StDate;
const
{the following characters are meaningful in date Picture strings}
MonthOnly = 'm'; {Formatting character for a date string picture mask}
DayOnly = 'd'; {Formatting character for a date string picture mask}
YearOnly = 'y'; {Formatting character for a date string picture mask}
MonthOnlyU = 'M'; {Formatting character for a date string picture mask.
Uppercase means pad with ' ' rather than '0'}
DayOnlyU = 'D'; {Formatting character for a date string picture mask.
Uppercase means pad with ' ' rather then '0'}
DateSlash = '/'; {Formatting character for a date string picture mask}
{'n'/'N' may be used in place of 'm'/'M' when the name of the month is
desired instead of its number. E.g., 'dd/nnn/yyyy' -\> '01-Jan-1980'.
'dd/NNN/yyyy' -\> '01-JAN-1980' (if SlashChar = '-'). The abbreviation used
is based on the width of the subfield (3 in the example) and the current
contents of the MonthString array.}
NameOnly = 'n'; {Formatting character for a date string picture mask}
NameOnlyU = 'N'; {Formatting character for a date string picture mask.
Uppercase causes the output to be in uppercase}
{'w'/'W' may be used to include the day of the week in a date string. E.g.,
'www dd nnn yyyy' -\> 'Mon 01 Jan 1989'. The abbreviation used is based on
the width of the subfield (3 in the example) and the current contents of the
DayString array. Note that TurboPower Entry Fields will not allow the user to
enter text into a subfield containing 'w' or 'W'. The day of the week will be
supplied automatically when a valid date is entered.}
WeekDayOnly = 'w'; {Formatting character for a date string picture mask}
WeekDayOnlyU = 'W'; {Formatting character for a date string picture mask.
Uppercase causes the output to be in uppercase}
LongDateSub1 = 'f'; {Mask character used strictly for dealing with Window's
long date format}
LongDateSub2 = 'g'; {Mask character used strictly for dealing with Window's
long date format}
LongDateSub3 = 'h'; {Mask character used strictly for dealing with Window's
long date format}
HourOnly = 'h'; {Formatting character for a time string picture mask}
MinOnly = 'm'; {Formatting character for a time string picture mask}
SecOnly = 's'; {Formatting character for a time string picture mask}
{if uppercase letters are used, numbers are padded with ' ' rather than '0'}
HourOnlyU = 'H'; {Formatting character for a time string picture mask.
Uppercase means pad with ' ' rather than '0'}
MinOnlyU = 'M'; {Formatting character for a time string picture mask.
Uppercase means pad with ' ' rather than '0'}
SecOnlyU = 'S'; {Formatting character for a time string picture mask.
Uppercase means pad with ' ' rather than '0'}
{'hh:mm:ss tt' -\> '12:00:00 pm', 'hh:mmt' -\> '12:00p'}
TimeOnly = 't'; {Formatting character for a time string picture mask.
This generates 'AM' or 'PM'}
TimeColon = ':'; {Formatting character for a time string picture mask}
{-------julian date routines---------------}
function DateStringHMStoAstJD(const Picture, DS : string; {!!.02}
H,M,S,Epoch : integer) : Double;
{-Returns the Astronomical Julian Date using a Date String,
Hours, Minutes, Seconds}
function MonthToString(const Month : Integer) : string;
{-Return the month as a string}
{-------date string routines---------------}
function DateStringToStDate(const Picture, S : string; Epoch : Integer) : TStDate;
{-Convert a string to a Julian date}
function DateStringToDMY(const Picture, S : string;
Epoch : Integer;
var D, M, Y : Integer) : Boolean;
{-Extract day, month, and year from a date string}
function StDateToDateString(const Picture : string; const Julian : TStDate;
Pack : Boolean) : string;
{-Convert a Julian date to a string}
function DayOfWeekToString(const WeekDay : TStDayType) : string;
{-Return the day of the week specified by WeekDay as a string in Dest.}
function DMYtoDateString(const Picture : string;
Day, Month, Year, Epoch : Integer;
Pack : Boolean) : string;
{-Merge the month, day, and year into the picture}
function CurrentDateString(const Picture : string; Pack : Boolean) : string;
{-Return today's date as a string}
{-------time routines---------------}
function CurrentTimeString(const Picture : string;
Pack : Boolean) : string;
{-Return the current time as a string of the specified form}
function TimeStringToHMS(const Picture, St : string;
var H, M, S : Integer) : Boolean;
{-Extract hours, minutes, seconds from a time string}
function TimeStringToStTime(const Picture, S : string) : TStTime;
{-Convert a time string to a time variable}
function StTimeToAmPmString(const Picture : string;
const T : TStTime; Pack : Boolean) : string;
{-Convert a time variable to a time string in am/pm format}
function StTimeToTimeString(const Picture : string; const T : TStTime;
Pack : Boolean) : string;
{-Convert a time variable to a time string}
{-------- routines for international date/time strings ---------}
function DateStringIsBlank(const Picture, S : string) : Boolean;
{-Return True if the month, day, and year in S are all blank}
function InternationalDate(ForceCentury : Boolean) : string;
{-Return a picture mask for a short date string, based on Windows' international
information}
function InternationalLongDate(ShortNames : Boolean;
ExcludeDOW : Boolean) : string;
{-Return a picture mask for a date string, based on Windows' international
information}
function InternationalTime(ShowSeconds : Boolean) : string;
{-Return a picture mask for a time string, based on Windows' international
information}
procedure ResetInternationalInfo;
{-Update internal info to match Windows' international info}
implementation
const
First2Months = 59; {1600 was a leap year}
FirstDayOfWeek = Saturday; {01/01/1600 was a Saturday}
DateLen = 40; {maximum length of Picture strings}
MaxMonthName = 15;
MaxDayName = 15;
//type
{ DateString = string[DateLen];}
// SString = string[255];
var
wLongDate : string;//[40];
wldSub1 : string[6]; //SZ: careful if converting to string; some code depends on sizeof (search for [*] around line 1021)
wldSub2 : string[6];
wldSub3 : string[6];
wShortDate : string;//[31];
w1159 : string[7];
w2359 : string[7];
wSlashChar : Char;
wColonChar : Char;
wTLZero : Boolean;
w12Hour : Boolean;
DefaultYear : Integer; {default year--used by DateStringToDMY}
DefaultMonth : ShortInt; {default month}
procedure ExtractFromPicture(const Picture, S : string; Ch : Char; {!!.02}
var I : Integer; Blank, Default : Integer); forward;
procedure AppendChar(var S : String; Ch : Char);
begin
SetLength(S,Succ(Length(S)));
S[Length(S)] := Ch;
end;
function DayOfWeekToString(const WeekDay : TStDayType) : string;
{-Return the day of the week specified by WeekDay as a string in Dest.
Will honor international names}
begin
Result := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongDayNames[Ord(WeekDay)+1];
end;
function MonthToString(const Month : Integer) : string;
{-Return the month as a string. Will honor international names}
begin
if (Month >= 1) and (Month <= 12) then
Result := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongMonthNames[Month]
else
Result := '';
end;
function AstJulianDatePrim(Year,Month,Date : Integer) : Double;
var
A, B : integer;
begin
if Month <= 2 then {!!.01}
begin
Dec(Year);
Inc(Month,12);
end;
A := Trunc(Year/100);
B := 2 - A + Trunc(A/4);
Result := Trunc(365.25 * (Year+4716))
+ Trunc(30.6001 * (Month+1))
+ Date + B - 1524.5;
end;
function DateStringHMSToAstJD(const Picture, DS : string; {!!.02}
H,M,S,Epoch : Integer) : Double;
{-Returns the Astronomical Julian Date using a Date String,
Hours, Minutes, Seconds}
var
Date, Month, Year : Integer;
begin
ExtractFromPicture(Picture, DS, NameOnly, Month, -1, 0);
if Month = 0 then
ExtractFromPicture(Picture, DS, MonthOnly, Month, -1, DefaultMonth);
ExtractFromPicture(Picture, DS, DayOnly, Date, -1, 1);
ExtractFromPicture(Picture, DS, YearOnly, Year, -1, DefaultYear);
Year := ResolveEpoch(Year, Epoch);
Result := AstJulianDatePrim(Year,Month,Date)
+ H/HoursInDay + M/MinutesInDay + S/SecondsInDay;
end;
function MonthStringToMonth(const MSt : string; Width : Byte) : Byte;{!!.02}
{-Convert the month name in MSt to a month (1..12)}
var
S : String;
T : String;
Len : Byte;
I : Word;
begin
S := UpperCase(MSt);
Len := Length(S);
// SetLength(S,Width);
// if Width > Len then
// FillChar(S[Len+1], Length(S)-Len, ' ');
S := S + StringOfChar(' ', Width - Len);
for I := 1 to 12 do begin
T := UpperCase({$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongMonthNames[I]);
Len := Length(T);
// SetLength(T,Width);
// if Width > Len then
// FillChar(T[Len+1], Length(T)-Len, ' ');
T := T + StringOfChar(' ', Width - Len);
if S = T then begin
Result := I;
Exit;
end;
end;
Result := 0;
end;
procedure ExtractFromPicture(const Picture, S : string; Ch : Char; {!!.02}
var I : Integer; Blank, Default : Integer);
{-Extract the value of the subfield specified by Ch from S and return in
I. I will be set to -1 in case of an error, Blank if the subfield exists
in Picture but is empty, Default if the subfield doesn't exist in
Picture.}
var
PTmp : string;
C, posLCCh, posUCCh : Cardinal;
Code : Integer;
begin
{find the start of the subfield}
I := Default;
StrChPosL(Picture, Ch, posLCCh);
Ch := StBase.Upcase(Ch);
StrChPosL(Picture, Ch, posUCCh);
if (posLCCh < 1) or ((posUCCh > 0) and (posUCCh < posLCCh)) then
posLCCh := posUCCh;
if (posLCCh < 1) or (Length(S) <> Length(Picture)) then
Exit;
{extract the substring}
PTmp := '';
C := Length(Picture);
while (posLCCh <= C) and (StBase.Upcase(Picture[posLCCh]) = Ch) do begin
if S[posLCCh] <> ' ' then
AppendChar(PTmp,Char(S[posLCCh]));
Inc(posLCCh);
end;
if Length(PTmp) = 0 then
I := Blank
else if Ch = NameOnlyU then begin
I := MonthStringToMonth(PTmp, Length(PTmp));
if I = 0 then
I := -1;
end
else begin
{convert to a value}
Val(PTmp, I, Code);
if Code <> 0 then
I := -1;
end;
end;
function DateStringToDMY(const Picture, S : string;
Epoch : Integer;
var D, M, Y : Integer) : Boolean;
{-Extract day, month, and year from S, returning true if string is valid}
begin
ExtractFromPicture(Picture, S, NameOnly, M, -1, 0);
if M = 0 then
ExtractFromPicture(Picture, S, MonthOnly, M, -1, DefaultMonth);
ExtractFromPicture(Picture, S, DayOnly, D, -1, 1);
ExtractFromPicture(Picture, S, YearOnly, Y, -1, DefaultYear);
if ValidDate(D, M, Y, Epoch) then begin
Result := True;
Y := ResolveEpoch(Y, Epoch);
end else
Result := False;
end;
function DateStringIsBlank(const Picture, S : string) : Boolean;
{-Return True if the month, day, and year in S are all blank}
var
M, D, Y : Integer;
begin
ExtractFromPicture(Picture, S, NameOnly, M, -2, 0);
if M = 0 then
ExtractFromPicture(Picture, S, MonthOnly, M, -2, -2);
ExtractFromPicture(Picture, S, DayOnly, D, -2, -2);
ExtractFromPicture(Picture, S, YearOnly, Y, -2, -2);
Result := (M = -2) and (D = -2) and (Y = -2);
end;
function DateStringToStDate(const Picture, S : string; Epoch : Integer) : TStDate;
{-Convert S, a string of the form indicated by Picture, to a julian date.
Picture and S must be of equal lengths}
var
Month, Day, Year : Integer;
begin
{extract day, month, year from S}
if DateStringToDMY(Picture, S, Epoch, Day, Month, Year) then
{convert to julian date}
Result := DMYtoStDate(Day, Month, Year, Epoch)
else
Result := BadDate;
end;
function SubstCharSim(P : string; OC, NC : Char) : string;
var
step : integer;
begin
for step := 1 to Length(P) do
begin
if P[step] = OC then
P[step] := NC;
end;
Result := P;
end;
function SubstChar(Picture : string; OldCh, NewCh : Char) : string;
{-Replace all instances of OldCh in Picture with NewCh}
var
I : Integer;
UpCh : Char;
P : Cardinal;
begin
UpCh := StBase.Upcase(OldCh);
if (StrChPosL(Picture,OldCh,P)) or (StrChPosL(Picture,UpCh,P)) then
for I := 1 to Length(Picture) do
if StBase.Upcase(Picture[I]) = UpCh then
Picture[I] := NewCh;
Result := Picture;
end;
function PackResult(const Picture, S : string) : string; {!!.02}
{-Remove unnecessary blanks from S}
var
step : Integer;
begin
Result := '';
for step := 1 to Length(Picture) do
begin
case Picture[step] of
MonthOnlyU, DayOnlyU, NameOnly, NameOnlyU, WeekDayOnly,
WeekDayOnlyU, HourOnlyU, SecOnlyU :
if S[step] <> ' ' then
AppendChar(Result,S[Step]);
TimeOnly :
if S[step] <> ' ' then
AppendChar(Result,S[step]);
else
AppendChar(Result,S[step]);
end;
end;
end;
procedure MergeIntoPicture(var Picture : string; Ch : Char; I : Integer);
{-Merge I into location in Picture indicated by format character Ch}
var
Tmp : string;
C,
J, K, L : Cardinal;
UCh,
CPJ,
CTI : Char;
OK, Done: Boolean;
step : Cardinal;
begin
{find the start of the subfield}
OK := StrChPosL(Picture,Ch,J);
UCh := StBase.Upcase(Ch);
if (NOT OK) then
begin
if NOT (StrChPosL(Picture, UCh, J)) then
Exit;
end;
{find the end of the subfield}
K := J;
C := Length(Picture);
while (J <= C) and (StBase.Upcase(Picture[J]) = UCh) do
Inc(J);
Dec(J);
if (UCh = WeekDayOnlyU) or (UCh = NameOnlyU) then begin
if UCh = WeekDayOnlyU then
case I of
Ord(Sunday)..Ord(Saturday) :
Tmp := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongDayNames[I+1];
else
Tmp := '';
end
else
case I of
1..12 :
Tmp := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongMonthNames[I];
else
Tmp := '';
end;
K := Succ(J-K);
if K > Length(Tmp) then
for step := 1 to (K-Length(Tmp)) do
Tmp := Tmp + ' ';
Tmp := Copy(Tmp,1,K);
end else
{convert I to a string}
Str(I:DateLen, Tmp);
{now merge}
L := Length(Tmp);
Done := False;
CPJ := Picture[J];
while (stBase.Upcase(CPJ) = UCh) and not Done do
begin
CTI := Tmp[L];
if (UCh = NameOnlyU) or (UCh = WeekDayOnlyU) then
begin
case CPJ of
NameOnlyU, WeekDayOnlyU :
CTI := stBase.Upcase(CTI);
end;
end
else{change spaces to 0's if desired}
if (CPJ >= 'a') and (CTI = ' ') then
CTI := '0';
Picture[J] := CTI;
Done := (J = 1) or (L = 0);
if not Done then
begin
Dec(J);
Dec(L);
end;
CPJ := Picture[J];
end;
end;
procedure MergePictureSt(const Picture : string; var P : string; {!!.02}
MC : Char; const SP : string); {!!.02}
var
I, J : Cardinal;
L : Cardinal;
begin
if NOT (StrChPosL(Picture,MC,I)) then
Exit;
J := 1;
L := Length(SP);
while Picture[I] = MC do begin
{if J <= Length(SP) then}
if (L = 0) or (J > L) then
P[I] := ' '
else begin
P[I] := SP[J];
Inc(J);
end;
Inc(I);
end;
end;
function DMYtoDateString(const Picture : string; Day, Month, Year, Epoch : Integer;
Pack : Boolean) : string;
{-Merge the month, day, and year into the picture}
var
DOW : Integer;
begin
Result := Picture;
Year := ResolveEpoch(Year, Epoch);
DOW := Integer( DayOfWeekDMY(Day, Month, Year, 0) );
MergeIntoPicture(Result, MonthOnly, Month);
MergeIntoPicture(Result, DayOnly, Day);
MergeIntoPicture(Result, YearOnly, Year);
MergeIntoPicture(Result, NameOnly, Month);
MergeIntoPicture(Result, WeekDayOnly, DOW);
{map slashes}
Result := SubstChar(Result, DateSlash, wSlashChar);
MergePictureSt(Picture, Result, LongDateSub1, wldSub1);
MergePictureSt(Picture, Result, LongDateSub2, wldSub2);
MergePictureSt(Picture, Result, LongDateSub3, wldSub3);
if Pack then
Result:= PackResult(Picture, Result);
end;
function StDateToDateString(const Picture : string; const Julian : TStDate;
Pack : Boolean) : string;
{-Convert Julian to a string of the form indicated by Picture}
var
Month, Day, Year : Integer;
begin
Result := Picture;
if (Julian = BadDate) or (Julian > MaxDate) then begin {!!.04}
{map picture characters to spaces}
Result := SubstChar(Result, MonthOnly, ' ');
Result := SubstChar(Result, NameOnly, ' ');
Result := SubstChar(Result, DayOnly, ' ');
Result := SubstChar(Result, YearOnly, ' ');
Result := SubstChar(Result, WeekDayOnly, ' ');
MergePictureSt(Picture, Result, LongDateSub1, wldSub1);
MergePictureSt(Picture, Result, LongDateSub2, wldSub2);
MergePictureSt(Picture, Result, LongDateSub3, wldSub3);
{map slashes}
Result := SubstChar(Result, DateSlash, wSlashChar);
end
else begin
{convert Julian to day/month/year}
StDateToDMY(Julian, Day, Month, Year);
{merge the month, day, and year into the picture}
Result := DMYtoDateString(Picture, Day, Month, Year, 0, Pack);
end;
end;
function CurrentDateString(const Picture : string; Pack : Boolean) : string;
{-Returns today's date as a string of the specified form}
begin
Result := StDateToDateString(Picture, CurrentDate, Pack);
end;
function TimeStringToHMS(const Picture, St : string; var H, M, S : Integer) : Boolean;
{-Extract Hours, Minutes, Seconds from St, returning true if string is valid}
var
I,
J : Cardinal;
Tmp,
t1159,
t2359 : string;
begin
{extract hours, minutes, seconds from St}
ExtractFromPicture(Picture, St, HourOnly, H, -1, 0);
ExtractFromPicture(Picture, St, MinOnly, M, -1, 0);
ExtractFromPicture(Picture, St, SecOnly, S, -1, 0);
if (H = -1) or (M = -1) or (S = -1) then begin
Result := False;
Exit;
end;
{check for TimeOnly}
if (StrChPosL(Picture, TimeOnly, I)) and
(Length(w1159) > 0) and (Length(w2359) > 0) then begin
Tmp := '';
J := 1;
while (I <= Cardinal(Length(Picture))) and (Picture[I] = TimeOnly) do begin{!!.02}
// while (Picture[I] = TimeOnly) do begin
//SZ Inc(Tmp[0]);
//SZ Tmp[J] := St[I];
Tmp := Tmp + St[I];
Inc(J);
Inc(I);
end;
Tmp := TrimRight(Tmp);
t1159 := w1159;
t2359 := w2359;
if (Length(Tmp) = 0) then
H := -1
else if (UpperCase(Tmp) = UpperCase(t2359)) then begin
if (H < 12) then
Inc(H,12)
else if (H=0) or (H > 12) then
{force BadTime}
H := -1;
end
else if (UpperCase(Tmp) = UpperCase(t1159)) then begin
if H = 12 then
H := 0
else if (H = 0) or (H > 12) then
{force BadTime}
H := -1;
end
else
{force BadTime}
H := -1;
end;
Result := ValidTime(H, M, S);
end;
function TimeStringToStTime(const Picture, S : string) : TStTime;
{-Convert S, a string of the form indicated by Picture, to a Time variable}
var
Hours, Minutes, Seconds : Integer;
begin
if TimeStringToHMS(Picture, S, Hours, Minutes, Seconds) then
Result := HMStoStTime(Hours, Minutes, Seconds)
else
Result := BadTime;
end;
function TimeToTimeStringPrim(const Picture : string; T : TStTime; {!!.02}
Pack : Boolean;
const t1159, t2359 : string) : string; {!!.02}
{-Convert T to a string of the form indicated by Picture}
var
Hours,
Minutes,
Seconds : Byte;
L, I,
TPos : Cardinal;
P : string;
OK : Boolean;
C : string;//[1];
begin
{merge the hours, minutes, and seconds into the picture}
StTimeToHMS(T, Hours, Minutes, Seconds);
Result := Picture;
{check for TimeOnly}
OK := StrChPosL(Result, TimeOnly, TPos);
if OK then begin
if (Hours >= 12) then
P := t2359
else
P := t1159;
if (Length(t1159) > 0) and (Length(t2359) > 0) then
case Hours of
0 : Hours := 12;
13..23 : Dec(Hours, 12);
end;
end;
if T = BadTime then begin
{map picture characters to spaces}
Result := SubstChar(Result, HourOnly, ' ');
Result := SubstChar(Result, MinOnly, ' ');
Result := SubstChar(Result, SecOnly, ' ');
end
else begin
{merge the numbers into the picture}
MergeIntoPicture(Result, HourOnly, Hours);
MergeIntoPicture(Result, MinOnly, Minutes);
MergeIntoPicture(Result, SecOnly, Seconds);
end;
{map colons}
Result := SubstChar(Result, TimeColon, wColonChar);
{plug in AM/PM string if appropriate}
if OK then begin
if (Length(t1159) = 0) and (Length(t2359) = 0) then begin
C := SubstCharSim(Result[TPos], TimeOnly, ' ');
Result[TPos] := C[1];
end else if (T = BadTime) and (Length(t1159) = 0) then begin
C := SubstCharSim(Result[TPos], TimeOnly, ' ');
Result[TPos] := C[1];
end else begin
I := 1;
L := Length(P);
// while (I <= L) and (Result[TPos] = TimeOnly) do begin {!!.01} {!!.03}
while (I <= L) and {!!.03}
(TPos <= Length(Result)) and (Result[TPos] = TimeOnly) do {!!.03}
begin {!!.03}
Result[TPos] := P[I];
Inc(I);
Inc(TPos);
end;
end;
end;
if Pack and (T <> BadTime) then
Result := PackResult(Picture, Result);
end;
function StTimeToTimeString(const Picture : string; const T : TStTime;
Pack : Boolean) : string;
{-Convert T to a string of the form indicated by Picture}
begin
Result := TimeToTimeStringPrim(Picture, T, Pack, w1159, w2359);
end;
function StTimeToAmPmString(const Picture : string; const T : TStTime;
Pack : Boolean) : string;
{-Convert T to a string of the form indicated by Picture. Times are always
displayed in am/pm format.}
const
t1159 = 'AM';
t2359 = 'PM';
var
P : Cardinal;
begin
Result := Picture;
if NOT (StrChPosL(Result, TimeOnly, P)) then
Result := Result + TimeOnly;
Result := TimeToTimeStringPrim(Result, T, Pack, t1159, t2359);
end;
function CurrentTime : TStTime;
{-Returns current time in seconds since midnight}
begin
Result := Trunc(SysUtils.Time * SecondsInDay);
end;
function CurrentTimeString(const Picture : string; Pack : Boolean) : string;
{-Returns current time as a string of the specified form}
begin
Result := StTimeToTimeString(Picture, CurrentTime, Pack);
end;
function MaskCharCount(const P : string; MC : Char) : Integer; {!!.02}
var
I, R,
Len : Cardinal;
OK : Boolean;
begin
OK := StrChPosL(P, MC, I);
R := Ord(OK);
Len := Length(P);
if OK then
while (I+R <= Len) and (P[I+R] = MC) do {!!.01}
Inc(R);
Result := R;
end;
function InternationalDate(ForceCentury : Boolean) : string;
{-Return a picture mask for a date string, based on Windows' int'l info}
procedure FixMask(MC : Char; DL : Integer);
var
I, J, AL, D : Cardinal;
MCT : Char;
OK : Boolean;
begin
{find number of matching characters}
OK := StrChPosL(Result, MC, I);
MCT := MC;
if not OK then begin
MCT := StBase.UpCase(MC);
OK := StrChPosL(Result, MCT, I);
end;
if NOT OK then
Exit;
D := DL;
{pad substring to desired length}
AL := MaskCharCount(Result, MCT);
if AL < D then
for J := 1 to D-AL do
Result := StrChInsertL(Result, MCT, I);
if MC <> YearOnly then begin
{choose blank/zero padding}
case AL of
1 : if MCT = MC then
Result := SubstCharSim(Result, MCT, StBase.UpCase(MCT));
2 : if MCT <> MC then
Result := SubstCharSim(Result, MCT, MC);
end;
end;
end;
begin
{copy Windows mask into our var}
Result := wShortDate;
{if single Day marker, make double}
FixMask(DayOnly, 2);
{if single Month marker, make double}
FixMask(MonthOnly, 2);
{force yyyy if desired}
FixMask(YearOnly, 2 shl Ord(ForceCentury));
end;
function InternationalLongDate(ShortNames : Boolean;
ExcludeDOW : Boolean) : string;
{-Return a picture mask for a date string, based on Windows' int'l info}
var
I, WC : Cardinal;
OK,
Stop : Boolean;
Temp : string[81];
function LongestMonthName : Integer;
var
L, I : Integer;
begin
L := 0;
for I := 1 to 12 do
L := Maxword(L, Length({$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongMonthNames[I]));
LongestMonthName := L;
end;
function LongestDayName : Integer;
var
D : TStDayType;
L : Integer;
begin
L := 0;
for D := Sunday to Saturday do
L := Maxword(L, Length({$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongDayNames[Ord(D)+1]));
LongestDayName := L;
end;
procedure FixMask(MC : Char; DL : Integer);
var
I, J, AL, D : Cardinal;
MCT : Char;
begin
{find first matching mask character}
OK := StrChPosS(Temp, MC, I);
MCT := MC;
if NOT OK then begin
MCT := StBase.UpCase(MC);
OK := StrChPosS(Temp, MCT, I);
end;
if NOT OK then
Exit;
D := DL;
{pad substring to desired length}
AL := MaskCharCount(Temp, MCT);
if AL < D then begin
for J := 1 to D-AL do
Temp := StrChInsertL(Temp, MCT, I);
end else if (AL > D) then
Temp := StrStDeleteL(Temp, I, AL-D);
if MC <> YearOnly then
{choose blank/zero padding}
case AL of
1 : if MCT = MC then
Temp := SubstCharSim(Temp, MCT, StBase.UpCase(MCT));
2 : if MCT <> MC then
Temp := SubstCharSim(Temp, MCT, MC);
end;
end;
begin
{copy Windows mask into temporary var}
Temp := wLongDate;
if ExcludeDOW then begin
{remove day-of-week and any junk that follows}
if (StrChPosS(Temp, WeekDayOnly,I)) then begin
Stop := False;
WC := I+1;
while (WC <= Length(Temp)) AND (NOT Stop) do
begin
if LoCase(Temp[WC]) in [MonthOnly,DayOnly,YearOnly,NameOnly] then
Stop := TRUE
else
Inc(WC);
end;
if (NOT ShortNames) then
Dec(WC);
Temp := StrStDeleteS(Temp, I, WC);
end;
end
else if ShortNames then
FixMask(WeekDayOnly, 3)
else if MaskCharCount(Temp, WeekdayOnly) = 4 then
FixMask(WeekDayOnly, LongestDayName);
{fix month names}
if ShortNames then
FixMask(NameOnly, 3)
else if MaskCharCount(Temp, NameOnly) = 4 then
FixMask(NameOnly, LongestMonthName);
{if single Day marker, make double}
FixMask(DayOnly, 2);
{if single Month marker, make double}
FixMask(MonthOnly, 2);
{force yyyy}
FixMask(YearOnly, 4);
Result := Temp;
end;
function InternationalTime(ShowSeconds : Boolean) : string;
{-Return a picture mask for a time string, based on Windows' int'l info}
var
ML,
I : Integer;
begin
{format the default string}
SetLength(Result,21);
Result := 'hh:mm:ss';
if not wTLZero then
Result[1] := HourOnlyU;
{show seconds?}
if not ShowSeconds then
SetLength(Result,5);
{handle international AM/PM markers}
if w12Hour then begin
ML := Maxword(Length(w1159), Length(w2359));
if (ML <> 0) then begin
AppendChar(Result,' ');
for I := 1 to ML do
AppendChar(Result, TimeOnly);
end;
end;
end;
procedure SetDefaultYear;
{-Initialize DefaultYear and DefaultMonth}
var
Month, Day : Word;
T : TDateTime;
W : Word;
begin
T := Now;
W := DefaultYear;
DecodeDate(T,W,Month,Day);
DefaultYear := W;
DefaultMonth := Month;
end;
procedure ResetInternationalInfo;
var
I : Integer;
S : array[0..20] of char;
procedure ExtractSubString(SubChar : Char; Dest : string);
var
I, L, P : Cardinal;
begin
// SetLength(Dest,sizeof(wldSub1));
// FillChar(Dest[1], SizeOf(wldSub1), 0);
Dest := StringOfChar(#0, Succ(High(wldSub1))); //SZ: not length! [*]
if NOT (StrChPosS(wLongDate, '''',I)) then
Exit;
{delete the first quote}
wLongDate := StrChDeleteS(wLongDate, I);
{assure that there is another quote}
if NOT (StrChPosS(wLongDate, '''',P)) then
Exit;
{copy substring into Dest, replace substring with SubChar}
L := 1;
while wLongDate[I] <> '''' do
if L < SizeOf(wldSub1) then begin
Dest[L] := wLongDate[I];
Inc(L);
wLongDate[I] := SubChar;
Inc(I);
end else
wLongDate := StrChDeleteL(wLongDate, I);
{delete the second quote}
wLongDate := StrChDeleteL(wLongDate, I);
end;
begin
wTLZero := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongTimeFormat[2] = 'h';
w12Hour := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongTimeFormat[length({$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongTimeFormat)] = 'M';
wColonChar := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}TimeSeparator;
wSlashChar := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}DateSeparator;
{$IFDEF FPC}
w1159 := ''; // ????????????
w2359 := '';
{$ELSE}
GetProfileString('intl','s1159','AM', S, Length(S));
w1159 := StrPas(S);
GetProfileString('intl','s2359','PM', S, Length(S));
w2359 := StrPas(S);
{$ENDIF}
{get short date mask and fix it up}
wShortDate := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}ShortDateFormat;
for I := 1 to Length(wShortDate) do
if (wShortDate[I] = wSlashChar) then
wShortDate[I] := '/';
{get long date mask and fix it up}
wLongDate := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongDateFormat;
ExtractSubString(LongDateSub1, wldSub1);
ExtractSubString(LongDateSub2, wldSub2);
ExtractSubString(LongDateSub3, wldSub3);
{replace ddd/dddd with www/wwww}
I := pos('ddd',wLongDate);
if I > 0 then begin
while wLongDate[I] = 'd' do begin
wLongDate[I] := 'w';
Inc(I);
end;
end;
{replace MMM/MMMM with nnn/nnnn}
if pos('MMM',wLongDate) > 0 then
while (pos('M',wLongDate) > 0) do
wLongDate[pos('M',wLongDate)] := 'n';
{deal with oddities concerning . and ,}
for I := 1 to Length(wLongDate)-1 do begin
case wLongDate[I] of
'.', ',' :
if wLongDate[I+1] <> ' ' then
wLongDate := StrChInsertS(wLongDate, ' ', I+1);
end;
end;
end;
initialization
{initialize DefaultYear and DefaultMonth}
SetDefaultYear;
ResetInternationalInfo;
end.