/[projects]/dao/DelphiScanner/Components/tpsystools_4.04/source/StDateSt.pas
ViewVC logotype

Annotation of /dao/DelphiScanner/Components/tpsystools_4.04/source/StDateSt.pas

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2671 - (hide annotations) (download)
Tue Aug 25 18:15:15 2015 UTC (8 years, 10 months ago) by torben
File size: 35306 byte(s)
Added tpsystools component
1 torben 2671 // Upgraded to Delphi 2009: Sebastian Zierer
2    
3     (* ***** BEGIN LICENSE BLOCK *****
4     * Version: MPL 1.1
5     *
6     * The contents of this file are subject to the Mozilla Public License Version
7     * 1.1 (the "License"); you may not use this file except in compliance with
8     * the License. You may obtain a copy of the License at
9     * http://www.mozilla.org/MPL/
10     *
11     * Software distributed under the License is distributed on an "AS IS" basis,
12     * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13     * for the specific language governing rights and limitations under the
14     * License.
15     *
16     * The Original Code is TurboPower SysTools
17     *
18     * The Initial Developer of the Original Code is
19     * TurboPower Software
20     *
21     * Portions created by the Initial Developer are Copyright (C) 1996-2002
22     * the Initial Developer. All Rights Reserved.
23     *
24     * Contributor(s):
25     *
26     * ***** END LICENSE BLOCK ***** *)
27    
28     {*********************************************************}
29     {* SysTools: StDateSt.pas 4.04 *}
30     {*********************************************************}
31     {* SysTools: Date and time string manipulation *}
32     {*********************************************************}
33    
34     {$I StDefine.inc}
35    
36     unit StDateSt;
37    
38     interface
39    
40     uses
41     Windows, SysUtils,
42     StStrS,
43     StStrL,
44     StConst,
45     StBase,
46     StUtils,
47     StDate;
48    
49     const
50     {the following characters are meaningful in date Picture strings}
51     MonthOnly = 'm'; {Formatting character for a date string picture mask}
52     DayOnly = 'd'; {Formatting character for a date string picture mask}
53     YearOnly = 'y'; {Formatting character for a date string picture mask}
54     MonthOnlyU = 'M'; {Formatting character for a date string picture mask.
55     Uppercase means pad with ' ' rather than '0'}
56     DayOnlyU = 'D'; {Formatting character for a date string picture mask.
57     Uppercase means pad with ' ' rather then '0'}
58     DateSlash = '/'; {Formatting character for a date string picture mask}
59    
60     {'n'/'N' may be used in place of 'm'/'M' when the name of the month is
61     desired instead of its number. E.g., 'dd/nnn/yyyy' -\> '01-Jan-1980'.
62     'dd/NNN/yyyy' -\> '01-JAN-1980' (if SlashChar = '-'). The abbreviation used
63     is based on the width of the subfield (3 in the example) and the current
64     contents of the MonthString array.}
65     NameOnly = 'n'; {Formatting character for a date string picture mask}
66     NameOnlyU = 'N'; {Formatting character for a date string picture mask.
67     Uppercase causes the output to be in uppercase}
68    
69     {'w'/'W' may be used to include the day of the week in a date string. E.g.,
70     'www dd nnn yyyy' -\> 'Mon 01 Jan 1989'. The abbreviation used is based on
71     the width of the subfield (3 in the example) and the current contents of the
72     DayString array. Note that TurboPower Entry Fields will not allow the user to
73     enter text into a subfield containing 'w' or 'W'. The day of the week will be
74     supplied automatically when a valid date is entered.}
75     WeekDayOnly = 'w'; {Formatting character for a date string picture mask}
76     WeekDayOnlyU = 'W'; {Formatting character for a date string picture mask.
77     Uppercase causes the output to be in uppercase}
78    
79     LongDateSub1 = 'f'; {Mask character used strictly for dealing with Window's
80     long date format}
81     LongDateSub2 = 'g'; {Mask character used strictly for dealing with Window's
82     long date format}
83     LongDateSub3 = 'h'; {Mask character used strictly for dealing with Window's
84     long date format}
85    
86     HourOnly = 'h'; {Formatting character for a time string picture mask}
87     MinOnly = 'm'; {Formatting character for a time string picture mask}
88     SecOnly = 's'; {Formatting character for a time string picture mask}
89     {if uppercase letters are used, numbers are padded with ' ' rather than '0'}
90     HourOnlyU = 'H'; {Formatting character for a time string picture mask.
91     Uppercase means pad with ' ' rather than '0'}
92     MinOnlyU = 'M'; {Formatting character for a time string picture mask.
93     Uppercase means pad with ' ' rather than '0'}
94     SecOnlyU = 'S'; {Formatting character for a time string picture mask.
95     Uppercase means pad with ' ' rather than '0'}
96     {'hh:mm:ss tt' -\> '12:00:00 pm', 'hh:mmt' -\> '12:00p'}
97     TimeOnly = 't'; {Formatting character for a time string picture mask.
98     This generates 'AM' or 'PM'}
99     TimeColon = ':'; {Formatting character for a time string picture mask}
100    
101    
102     {-------julian date routines---------------}
103    
104     function DateStringHMStoAstJD(const Picture, DS : string; {!!.02}
105     H,M,S,Epoch : integer) : Double;
106     {-Returns the Astronomical Julian Date using a Date String,
107     Hours, Minutes, Seconds}
108    
109     function MonthToString(const Month : Integer) : string;
110     {-Return the month as a string}
111    
112     {-------date string routines---------------}
113    
114     function DateStringToStDate(const Picture, S : string; Epoch : Integer) : TStDate;
115     {-Convert a string to a Julian date}
116    
117     function DateStringToDMY(const Picture, S : string;
118     Epoch : Integer;
119     var D, M, Y : Integer) : Boolean;
120     {-Extract day, month, and year from a date string}
121    
122     function StDateToDateString(const Picture : string; const Julian : TStDate;
123     Pack : Boolean) : string;
124     {-Convert a Julian date to a string}
125    
126     function DayOfWeekToString(const WeekDay : TStDayType) : string;
127     {-Return the day of the week specified by WeekDay as a string in Dest.}
128    
129     function DMYtoDateString(const Picture : string;
130     Day, Month, Year, Epoch : Integer;
131     Pack : Boolean) : string;
132     {-Merge the month, day, and year into the picture}
133    
134     function CurrentDateString(const Picture : string; Pack : Boolean) : string;
135     {-Return today's date as a string}
136    
137     {-------time routines---------------}
138    
139     function CurrentTimeString(const Picture : string;
140     Pack : Boolean) : string;
141     {-Return the current time as a string of the specified form}
142    
143     function TimeStringToHMS(const Picture, St : string;
144     var H, M, S : Integer) : Boolean;
145     {-Extract hours, minutes, seconds from a time string}
146    
147     function TimeStringToStTime(const Picture, S : string) : TStTime;
148     {-Convert a time string to a time variable}
149    
150     function StTimeToAmPmString(const Picture : string;
151     const T : TStTime; Pack : Boolean) : string;
152     {-Convert a time variable to a time string in am/pm format}
153    
154     function StTimeToTimeString(const Picture : string; const T : TStTime;
155     Pack : Boolean) : string;
156     {-Convert a time variable to a time string}
157    
158    
159     {-------- routines for international date/time strings ---------}
160    
161     function DateStringIsBlank(const Picture, S : string) : Boolean;
162     {-Return True if the month, day, and year in S are all blank}
163    
164     function InternationalDate(ForceCentury : Boolean) : string;
165     {-Return a picture mask for a short date string, based on Windows' international
166     information}
167    
168     function InternationalLongDate(ShortNames : Boolean;
169     ExcludeDOW : Boolean) : string;
170     {-Return a picture mask for a date string, based on Windows' international
171     information}
172    
173     function InternationalTime(ShowSeconds : Boolean) : string;
174     {-Return a picture mask for a time string, based on Windows' international
175     information}
176    
177     procedure ResetInternationalInfo;
178     {-Update internal info to match Windows' international info}
179    
180    
181     implementation
182    
183     const
184     First2Months = 59; {1600 was a leap year}
185     FirstDayOfWeek = Saturday; {01/01/1600 was a Saturday}
186     DateLen = 40; {maximum length of Picture strings}
187     MaxMonthName = 15;
188     MaxDayName = 15;
189    
190     //type
191     { DateString = string[DateLen];}
192     // SString = string[255];
193    
194     var
195     wLongDate : string;//[40];
196     wldSub1 : string[6]; //SZ: careful if converting to string; some code depends on sizeof (search for [*] around line 1021)
197     wldSub2 : string[6];
198     wldSub3 : string[6];
199     wShortDate : string;//[31];
200     w1159 : string[7];
201     w2359 : string[7];
202     wSlashChar : Char;
203     wColonChar : Char;
204     wTLZero : Boolean;
205     w12Hour : Boolean;
206     DefaultYear : Integer; {default year--used by DateStringToDMY}
207     DefaultMonth : ShortInt; {default month}
208    
209     procedure ExtractFromPicture(const Picture, S : string; Ch : Char; {!!.02}
210     var I : Integer; Blank, Default : Integer); forward;
211    
212     procedure AppendChar(var S : String; Ch : Char);
213     begin
214     SetLength(S,Succ(Length(S)));
215     S[Length(S)] := Ch;
216     end;
217    
218     function DayOfWeekToString(const WeekDay : TStDayType) : string;
219     {-Return the day of the week specified by WeekDay as a string in Dest.
220     Will honor international names}
221     begin
222     Result := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongDayNames[Ord(WeekDay)+1];
223     end;
224    
225     function MonthToString(const Month : Integer) : string;
226     {-Return the month as a string. Will honor international names}
227     begin
228     if (Month >= 1) and (Month <= 12) then
229     Result := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongMonthNames[Month]
230     else
231     Result := '';
232     end;
233    
234     function AstJulianDatePrim(Year,Month,Date : Integer) : Double;
235     var
236     A, B : integer;
237     begin
238     if Month <= 2 then {!!.01}
239     begin
240     Dec(Year);
241     Inc(Month,12);
242     end;
243     A := Trunc(Year/100);
244     B := 2 - A + Trunc(A/4);
245    
246     Result := Trunc(365.25 * (Year+4716))
247     + Trunc(30.6001 * (Month+1))
248     + Date + B - 1524.5;
249     end;
250    
251     function DateStringHMSToAstJD(const Picture, DS : string; {!!.02}
252     H,M,S,Epoch : Integer) : Double;
253     {-Returns the Astronomical Julian Date using a Date String,
254     Hours, Minutes, Seconds}
255     var
256     Date, Month, Year : Integer;
257     begin
258     ExtractFromPicture(Picture, DS, NameOnly, Month, -1, 0);
259     if Month = 0 then
260     ExtractFromPicture(Picture, DS, MonthOnly, Month, -1, DefaultMonth);
261     ExtractFromPicture(Picture, DS, DayOnly, Date, -1, 1);
262     ExtractFromPicture(Picture, DS, YearOnly, Year, -1, DefaultYear);
263    
264     Year := ResolveEpoch(Year, Epoch);
265     Result := AstJulianDatePrim(Year,Month,Date)
266     + H/HoursInDay + M/MinutesInDay + S/SecondsInDay;
267     end;
268    
269     function MonthStringToMonth(const MSt : string; Width : Byte) : Byte;{!!.02}
270     {-Convert the month name in MSt to a month (1..12)}
271     var
272     S : String;
273     T : String;
274     Len : Byte;
275     I : Word;
276     begin
277     S := UpperCase(MSt);
278     Len := Length(S);
279     // SetLength(S,Width);
280     // if Width > Len then
281     // FillChar(S[Len+1], Length(S)-Len, ' ');
282     S := S + StringOfChar(' ', Width - Len);
283    
284     for I := 1 to 12 do begin
285     T := UpperCase({$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongMonthNames[I]);
286     Len := Length(T);
287     // SetLength(T,Width);
288     // if Width > Len then
289     // FillChar(T[Len+1], Length(T)-Len, ' ');
290     T := T + StringOfChar(' ', Width - Len);
291    
292     if S = T then begin
293     Result := I;
294     Exit;
295     end;
296     end;
297     Result := 0;
298     end;
299    
300     procedure ExtractFromPicture(const Picture, S : string; Ch : Char; {!!.02}
301     var I : Integer; Blank, Default : Integer);
302     {-Extract the value of the subfield specified by Ch from S and return in
303     I. I will be set to -1 in case of an error, Blank if the subfield exists
304     in Picture but is empty, Default if the subfield doesn't exist in
305     Picture.}
306     var
307     PTmp : string;
308     C, posLCCh, posUCCh : Cardinal;
309     Code : Integer;
310     begin
311     {find the start of the subfield}
312     I := Default;
313    
314     StrChPosL(Picture, Ch, posLCCh);
315     Ch := StBase.Upcase(Ch);
316     StrChPosL(Picture, Ch, posUCCh);
317    
318     if (posLCCh < 1) or ((posUCCh > 0) and (posUCCh < posLCCh)) then
319     posLCCh := posUCCh;
320     if (posLCCh < 1) or (Length(S) <> Length(Picture)) then
321     Exit;
322    
323     {extract the substring}
324    
325     PTmp := '';
326     C := Length(Picture);
327     while (posLCCh <= C) and (StBase.Upcase(Picture[posLCCh]) = Ch) do begin
328     if S[posLCCh] <> ' ' then
329     AppendChar(PTmp,Char(S[posLCCh]));
330     Inc(posLCCh);
331     end;
332    
333     if Length(PTmp) = 0 then
334     I := Blank
335     else if Ch = NameOnlyU then begin
336     I := MonthStringToMonth(PTmp, Length(PTmp));
337     if I = 0 then
338     I := -1;
339     end
340     else begin
341     {convert to a value}
342     Val(PTmp, I, Code);
343     if Code <> 0 then
344     I := -1;
345     end;
346     end;
347    
348     function DateStringToDMY(const Picture, S : string;
349     Epoch : Integer;
350     var D, M, Y : Integer) : Boolean;
351     {-Extract day, month, and year from S, returning true if string is valid}
352     begin
353     ExtractFromPicture(Picture, S, NameOnly, M, -1, 0);
354     if M = 0 then
355     ExtractFromPicture(Picture, S, MonthOnly, M, -1, DefaultMonth);
356     ExtractFromPicture(Picture, S, DayOnly, D, -1, 1);
357     ExtractFromPicture(Picture, S, YearOnly, Y, -1, DefaultYear);
358     if ValidDate(D, M, Y, Epoch) then begin
359     Result := True;
360     Y := ResolveEpoch(Y, Epoch);
361     end else
362     Result := False;
363     end;
364    
365     function DateStringIsBlank(const Picture, S : string) : Boolean;
366     {-Return True if the month, day, and year in S are all blank}
367     var
368     M, D, Y : Integer;
369     begin
370     ExtractFromPicture(Picture, S, NameOnly, M, -2, 0);
371     if M = 0 then
372     ExtractFromPicture(Picture, S, MonthOnly, M, -2, -2);
373     ExtractFromPicture(Picture, S, DayOnly, D, -2, -2);
374     ExtractFromPicture(Picture, S, YearOnly, Y, -2, -2);
375     Result := (M = -2) and (D = -2) and (Y = -2);
376     end;
377    
378    
379     function DateStringToStDate(const Picture, S : string; Epoch : Integer) : TStDate;
380     {-Convert S, a string of the form indicated by Picture, to a julian date.
381     Picture and S must be of equal lengths}
382     var
383     Month, Day, Year : Integer;
384     begin
385     {extract day, month, year from S}
386     if DateStringToDMY(Picture, S, Epoch, Day, Month, Year) then
387     {convert to julian date}
388     Result := DMYtoStDate(Day, Month, Year, Epoch)
389     else
390     Result := BadDate;
391     end;
392    
393     function SubstCharSim(P : string; OC, NC : Char) : string;
394     var
395     step : integer;
396     begin
397     for step := 1 to Length(P) do
398     begin
399     if P[step] = OC then
400     P[step] := NC;
401     end;
402     Result := P;
403     end;
404    
405     function SubstChar(Picture : string; OldCh, NewCh : Char) : string;
406     {-Replace all instances of OldCh in Picture with NewCh}
407     var
408     I : Integer;
409     UpCh : Char;
410     P : Cardinal;
411     begin
412     UpCh := StBase.Upcase(OldCh);
413     if (StrChPosL(Picture,OldCh,P)) or (StrChPosL(Picture,UpCh,P)) then
414     for I := 1 to Length(Picture) do
415     if StBase.Upcase(Picture[I]) = UpCh then
416     Picture[I] := NewCh;
417     Result := Picture;
418     end;
419    
420     function PackResult(const Picture, S : string) : string; {!!.02}
421     {-Remove unnecessary blanks from S}
422     var
423     step : Integer;
424     begin
425     Result := '';
426    
427     for step := 1 to Length(Picture) do
428     begin
429     case Picture[step] of
430     MonthOnlyU, DayOnlyU, NameOnly, NameOnlyU, WeekDayOnly,
431     WeekDayOnlyU, HourOnlyU, SecOnlyU :
432     if S[step] <> ' ' then
433     AppendChar(Result,S[Step]);
434     TimeOnly :
435     if S[step] <> ' ' then
436     AppendChar(Result,S[step]);
437     else
438     AppendChar(Result,S[step]);
439     end;
440     end;
441     end;
442    
443     procedure MergeIntoPicture(var Picture : string; Ch : Char; I : Integer);
444     {-Merge I into location in Picture indicated by format character Ch}
445     var
446     Tmp : string;
447     C,
448     J, K, L : Cardinal;
449     UCh,
450     CPJ,
451     CTI : Char;
452     OK, Done: Boolean;
453     step : Cardinal;
454     begin
455     {find the start of the subfield}
456     OK := StrChPosL(Picture,Ch,J);
457     UCh := StBase.Upcase(Ch);
458     if (NOT OK) then
459     begin
460     if NOT (StrChPosL(Picture, UCh, J)) then
461     Exit;
462     end;
463    
464     {find the end of the subfield}
465     K := J;
466     C := Length(Picture);
467     while (J <= C) and (StBase.Upcase(Picture[J]) = UCh) do
468     Inc(J);
469     Dec(J);
470    
471     if (UCh = WeekDayOnlyU) or (UCh = NameOnlyU) then begin
472     if UCh = WeekDayOnlyU then
473     case I of
474     Ord(Sunday)..Ord(Saturday) :
475     Tmp := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongDayNames[I+1];
476     else
477     Tmp := '';
478     end
479     else
480     case I of
481     1..12 :
482     Tmp := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongMonthNames[I];
483     else
484     Tmp := '';
485     end;
486     K := Succ(J-K);
487     if K > Length(Tmp) then
488     for step := 1 to (K-Length(Tmp)) do
489     Tmp := Tmp + ' ';
490     Tmp := Copy(Tmp,1,K);
491     end else
492     {convert I to a string}
493     Str(I:DateLen, Tmp);
494    
495     {now merge}
496     L := Length(Tmp);
497     Done := False;
498     CPJ := Picture[J];
499    
500     while (stBase.Upcase(CPJ) = UCh) and not Done do
501     begin
502     CTI := Tmp[L];
503     if (UCh = NameOnlyU) or (UCh = WeekDayOnlyU) then
504     begin
505     case CPJ of
506     NameOnlyU, WeekDayOnlyU :
507     CTI := stBase.Upcase(CTI);
508     end;
509     end
510     else{change spaces to 0's if desired}
511     if (CPJ >= 'a') and (CTI = ' ') then
512     CTI := '0';
513     Picture[J] := CTI;
514     Done := (J = 1) or (L = 0);
515     if not Done then
516     begin
517     Dec(J);
518     Dec(L);
519     end;
520     CPJ := Picture[J];
521     end;
522     end;
523    
524    
525     procedure MergePictureSt(const Picture : string; var P : string; {!!.02}
526     MC : Char; const SP : string); {!!.02}
527     var
528     I, J : Cardinal;
529     L : Cardinal;
530     begin
531     if NOT (StrChPosL(Picture,MC,I)) then
532     Exit;
533     J := 1;
534     L := Length(SP);
535     while Picture[I] = MC do begin
536     {if J <= Length(SP) then}
537     if (L = 0) or (J > L) then
538     P[I] := ' '
539     else begin
540     P[I] := SP[J];
541     Inc(J);
542     end;
543     Inc(I);
544     end;
545     end;
546    
547    
548     function DMYtoDateString(const Picture : string; Day, Month, Year, Epoch : Integer;
549     Pack : Boolean) : string;
550     {-Merge the month, day, and year into the picture}
551     var
552     DOW : Integer;
553    
554     begin
555     Result := Picture;
556    
557     Year := ResolveEpoch(Year, Epoch);
558    
559     DOW := Integer( DayOfWeekDMY(Day, Month, Year, 0) );
560     MergeIntoPicture(Result, MonthOnly, Month);
561     MergeIntoPicture(Result, DayOnly, Day);
562     MergeIntoPicture(Result, YearOnly, Year);
563     MergeIntoPicture(Result, NameOnly, Month);
564     MergeIntoPicture(Result, WeekDayOnly, DOW);
565    
566     {map slashes}
567     Result := SubstChar(Result, DateSlash, wSlashChar);
568    
569     MergePictureSt(Picture, Result, LongDateSub1, wldSub1);
570     MergePictureSt(Picture, Result, LongDateSub2, wldSub2);
571     MergePictureSt(Picture, Result, LongDateSub3, wldSub3);
572    
573     if Pack then
574     Result:= PackResult(Picture, Result);
575     end;
576    
577     function StDateToDateString(const Picture : string; const Julian : TStDate;
578     Pack : Boolean) : string;
579     {-Convert Julian to a string of the form indicated by Picture}
580     var
581     Month, Day, Year : Integer;
582     begin
583     Result := Picture;
584     if (Julian = BadDate) or (Julian > MaxDate) then begin {!!.04}
585     {map picture characters to spaces}
586     Result := SubstChar(Result, MonthOnly, ' ');
587     Result := SubstChar(Result, NameOnly, ' ');
588     Result := SubstChar(Result, DayOnly, ' ');
589     Result := SubstChar(Result, YearOnly, ' ');
590     Result := SubstChar(Result, WeekDayOnly, ' ');
591    
592     MergePictureSt(Picture, Result, LongDateSub1, wldSub1);
593     MergePictureSt(Picture, Result, LongDateSub2, wldSub2);
594     MergePictureSt(Picture, Result, LongDateSub3, wldSub3);
595    
596     {map slashes}
597     Result := SubstChar(Result, DateSlash, wSlashChar);
598     end
599     else begin
600     {convert Julian to day/month/year}
601     StDateToDMY(Julian, Day, Month, Year);
602    
603     {merge the month, day, and year into the picture}
604     Result := DMYtoDateString(Picture, Day, Month, Year, 0, Pack);
605     end;
606     end;
607    
608     function CurrentDateString(const Picture : string; Pack : Boolean) : string;
609     {-Returns today's date as a string of the specified form}
610     begin
611     Result := StDateToDateString(Picture, CurrentDate, Pack);
612     end;
613    
614     function TimeStringToHMS(const Picture, St : string; var H, M, S : Integer) : Boolean;
615     {-Extract Hours, Minutes, Seconds from St, returning true if string is valid}
616     var
617     I,
618     J : Cardinal;
619     Tmp,
620     t1159,
621     t2359 : string;
622     begin
623     {extract hours, minutes, seconds from St}
624     ExtractFromPicture(Picture, St, HourOnly, H, -1, 0);
625     ExtractFromPicture(Picture, St, MinOnly, M, -1, 0);
626     ExtractFromPicture(Picture, St, SecOnly, S, -1, 0);
627     if (H = -1) or (M = -1) or (S = -1) then begin
628     Result := False;
629     Exit;
630     end;
631    
632     {check for TimeOnly}
633     if (StrChPosL(Picture, TimeOnly, I)) and
634     (Length(w1159) > 0) and (Length(w2359) > 0) then begin
635    
636     Tmp := '';
637     J := 1;
638     while (I <= Cardinal(Length(Picture))) and (Picture[I] = TimeOnly) do begin{!!.02}
639     // while (Picture[I] = TimeOnly) do begin
640     //SZ Inc(Tmp[0]);
641     //SZ Tmp[J] := St[I];
642     Tmp := Tmp + St[I];
643     Inc(J);
644     Inc(I);
645     end;
646     Tmp := TrimRight(Tmp);
647    
648     t1159 := w1159;
649     t2359 := w2359;
650     if (Length(Tmp) = 0) then
651     H := -1
652     else if (UpperCase(Tmp) = UpperCase(t2359)) then begin
653     if (H < 12) then
654     Inc(H,12)
655     else if (H=0) or (H > 12) then
656     {force BadTime}
657     H := -1;
658     end
659     else if (UpperCase(Tmp) = UpperCase(t1159)) then begin
660     if H = 12 then
661     H := 0
662     else if (H = 0) or (H > 12) then
663     {force BadTime}
664     H := -1;
665     end
666     else
667     {force BadTime}
668     H := -1;
669     end;
670     Result := ValidTime(H, M, S);
671     end;
672    
673     function TimeStringToStTime(const Picture, S : string) : TStTime;
674     {-Convert S, a string of the form indicated by Picture, to a Time variable}
675     var
676     Hours, Minutes, Seconds : Integer;
677     begin
678     if TimeStringToHMS(Picture, S, Hours, Minutes, Seconds) then
679     Result := HMStoStTime(Hours, Minutes, Seconds)
680     else
681     Result := BadTime;
682     end;
683    
684     function TimeToTimeStringPrim(const Picture : string; T : TStTime; {!!.02}
685     Pack : Boolean;
686     const t1159, t2359 : string) : string; {!!.02}
687     {-Convert T to a string of the form indicated by Picture}
688     var
689     Hours,
690     Minutes,
691     Seconds : Byte;
692     L, I,
693     TPos : Cardinal;
694     P : string;
695     OK : Boolean;
696     C : string;//[1];
697     begin
698     {merge the hours, minutes, and seconds into the picture}
699     StTimeToHMS(T, Hours, Minutes, Seconds);
700     Result := Picture;
701    
702     {check for TimeOnly}
703     OK := StrChPosL(Result, TimeOnly, TPos);
704     if OK then begin
705     if (Hours >= 12) then
706     P := t2359
707     else
708     P := t1159;
709     if (Length(t1159) > 0) and (Length(t2359) > 0) then
710     case Hours of
711     0 : Hours := 12;
712     13..23 : Dec(Hours, 12);
713     end;
714     end;
715    
716     if T = BadTime then begin
717     {map picture characters to spaces}
718     Result := SubstChar(Result, HourOnly, ' ');
719     Result := SubstChar(Result, MinOnly, ' ');
720     Result := SubstChar(Result, SecOnly, ' ');
721     end
722     else begin
723     {merge the numbers into the picture}
724     MergeIntoPicture(Result, HourOnly, Hours);
725     MergeIntoPicture(Result, MinOnly, Minutes);
726     MergeIntoPicture(Result, SecOnly, Seconds);
727     end;
728    
729     {map colons}
730     Result := SubstChar(Result, TimeColon, wColonChar);
731    
732     {plug in AM/PM string if appropriate}
733     if OK then begin
734     if (Length(t1159) = 0) and (Length(t2359) = 0) then begin
735     C := SubstCharSim(Result[TPos], TimeOnly, ' ');
736     Result[TPos] := C[1];
737     end else if (T = BadTime) and (Length(t1159) = 0) then begin
738     C := SubstCharSim(Result[TPos], TimeOnly, ' ');
739     Result[TPos] := C[1];
740     end else begin
741     I := 1;
742     L := Length(P);
743     // while (I <= L) and (Result[TPos] = TimeOnly) do begin {!!.01} {!!.03}
744     while (I <= L) and {!!.03}
745     (TPos <= Length(Result)) and (Result[TPos] = TimeOnly) do {!!.03}
746     begin {!!.03}
747     Result[TPos] := P[I];
748     Inc(I);
749     Inc(TPos);
750     end;
751     end;
752     end;
753    
754     if Pack and (T <> BadTime) then
755     Result := PackResult(Picture, Result);
756     end;
757    
758     function StTimeToTimeString(const Picture : string; const T : TStTime;
759     Pack : Boolean) : string;
760     {-Convert T to a string of the form indicated by Picture}
761     begin
762     Result := TimeToTimeStringPrim(Picture, T, Pack, w1159, w2359);
763     end;
764    
765     function StTimeToAmPmString(const Picture : string; const T : TStTime;
766     Pack : Boolean) : string;
767     {-Convert T to a string of the form indicated by Picture. Times are always
768     displayed in am/pm format.}
769     const
770     t1159 = 'AM';
771     t2359 = 'PM';
772     var
773     P : Cardinal;
774     begin
775     Result := Picture;
776     if NOT (StrChPosL(Result, TimeOnly, P)) then
777     Result := Result + TimeOnly;
778     Result := TimeToTimeStringPrim(Result, T, Pack, t1159, t2359);
779     end;
780    
781     function CurrentTime : TStTime;
782     {-Returns current time in seconds since midnight}
783     begin
784     Result := Trunc(SysUtils.Time * SecondsInDay);
785     end;
786    
787     function CurrentTimeString(const Picture : string; Pack : Boolean) : string;
788     {-Returns current time as a string of the specified form}
789     begin
790     Result := StTimeToTimeString(Picture, CurrentTime, Pack);
791     end;
792    
793     function MaskCharCount(const P : string; MC : Char) : Integer; {!!.02}
794     var
795     I, R,
796     Len : Cardinal;
797     OK : Boolean;
798     begin
799     OK := StrChPosL(P, MC, I);
800     R := Ord(OK);
801     Len := Length(P);
802     if OK then
803     while (I+R <= Len) and (P[I+R] = MC) do {!!.01}
804     Inc(R);
805     Result := R;
806     end;
807    
808     function InternationalDate(ForceCentury : Boolean) : string;
809     {-Return a picture mask for a date string, based on Windows' int'l info}
810    
811     procedure FixMask(MC : Char; DL : Integer);
812     var
813     I, J, AL, D : Cardinal;
814     MCT : Char;
815     OK : Boolean;
816     begin
817     {find number of matching characters}
818     OK := StrChPosL(Result, MC, I);
819     MCT := MC;
820     if not OK then begin
821     MCT := StBase.UpCase(MC);
822     OK := StrChPosL(Result, MCT, I);
823     end;
824     if NOT OK then
825     Exit;
826    
827     D := DL;
828     {pad substring to desired length}
829     AL := MaskCharCount(Result, MCT);
830     if AL < D then
831     for J := 1 to D-AL do
832     Result := StrChInsertL(Result, MCT, I);
833    
834     if MC <> YearOnly then begin
835     {choose blank/zero padding}
836     case AL of
837     1 : if MCT = MC then
838     Result := SubstCharSim(Result, MCT, StBase.UpCase(MCT));
839     2 : if MCT <> MC then
840     Result := SubstCharSim(Result, MCT, MC);
841     end;
842     end;
843     end;
844    
845     begin
846     {copy Windows mask into our var}
847     Result := wShortDate;
848    
849     {if single Day marker, make double}
850     FixMask(DayOnly, 2);
851    
852     {if single Month marker, make double}
853     FixMask(MonthOnly, 2);
854    
855     {force yyyy if desired}
856     FixMask(YearOnly, 2 shl Ord(ForceCentury));
857     end;
858    
859    
860     function InternationalLongDate(ShortNames : Boolean;
861     ExcludeDOW : Boolean) : string;
862     {-Return a picture mask for a date string, based on Windows' int'l info}
863     var
864     I, WC : Cardinal;
865     OK,
866     Stop : Boolean;
867     Temp : string[81];
868    
869     function LongestMonthName : Integer;
870     var
871     L, I : Integer;
872     begin
873     L := 0;
874     for I := 1 to 12 do
875     L := Maxword(L, Length({$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongMonthNames[I]));
876     LongestMonthName := L;
877     end;
878    
879     function LongestDayName : Integer;
880     var
881     D : TStDayType;
882     L : Integer;
883     begin
884     L := 0;
885     for D := Sunday to Saturday do
886     L := Maxword(L, Length({$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongDayNames[Ord(D)+1]));
887     LongestDayName := L;
888     end;
889    
890     procedure FixMask(MC : Char; DL : Integer);
891     var
892     I, J, AL, D : Cardinal;
893     MCT : Char;
894     begin
895     {find first matching mask character}
896     OK := StrChPosS(Temp, MC, I);
897     MCT := MC;
898     if NOT OK then begin
899     MCT := StBase.UpCase(MC);
900     OK := StrChPosS(Temp, MCT, I);
901     end;
902     if NOT OK then
903     Exit;
904    
905     D := DL;
906     {pad substring to desired length}
907     AL := MaskCharCount(Temp, MCT);
908     if AL < D then begin
909     for J := 1 to D-AL do
910     Temp := StrChInsertL(Temp, MCT, I);
911     end else if (AL > D) then
912     Temp := StrStDeleteL(Temp, I, AL-D);
913    
914     if MC <> YearOnly then
915     {choose blank/zero padding}
916     case AL of
917     1 : if MCT = MC then
918     Temp := SubstCharSim(Temp, MCT, StBase.UpCase(MCT));
919     2 : if MCT <> MC then
920     Temp := SubstCharSim(Temp, MCT, MC);
921     end;
922     end;
923    
924     begin
925     {copy Windows mask into temporary var}
926     Temp := wLongDate;
927    
928     if ExcludeDOW then begin
929     {remove day-of-week and any junk that follows}
930     if (StrChPosS(Temp, WeekDayOnly,I)) then begin
931     Stop := False;
932     WC := I+1;
933     while (WC <= Length(Temp)) AND (NOT Stop) do
934     begin
935     if LoCase(Temp[WC]) in [MonthOnly,DayOnly,YearOnly,NameOnly] then
936     Stop := TRUE
937     else
938     Inc(WC);
939     end;
940     if (NOT ShortNames) then
941     Dec(WC);
942     Temp := StrStDeleteS(Temp, I, WC);
943     end;
944     end
945     else if ShortNames then
946     FixMask(WeekDayOnly, 3)
947     else if MaskCharCount(Temp, WeekdayOnly) = 4 then
948     FixMask(WeekDayOnly, LongestDayName);
949    
950     {fix month names}
951     if ShortNames then
952     FixMask(NameOnly, 3)
953     else if MaskCharCount(Temp, NameOnly) = 4 then
954     FixMask(NameOnly, LongestMonthName);
955    
956     {if single Day marker, make double}
957     FixMask(DayOnly, 2);
958    
959     {if single Month marker, make double}
960     FixMask(MonthOnly, 2);
961    
962     {force yyyy}
963     FixMask(YearOnly, 4);
964    
965     Result := Temp;
966     end;
967    
968     function InternationalTime(ShowSeconds : Boolean) : string;
969     {-Return a picture mask for a time string, based on Windows' int'l info}
970     var
971     ML,
972     I : Integer;
973     begin
974     {format the default string}
975    
976     SetLength(Result,21);
977     Result := 'hh:mm:ss';
978     if not wTLZero then
979     Result[1] := HourOnlyU;
980    
981     {show seconds?}
982     if not ShowSeconds then
983     SetLength(Result,5);
984    
985     {handle international AM/PM markers}
986     if w12Hour then begin
987     ML := Maxword(Length(w1159), Length(w2359));
988     if (ML <> 0) then begin
989     AppendChar(Result,' ');
990     for I := 1 to ML do
991     AppendChar(Result, TimeOnly);
992     end;
993     end;
994     end;
995    
996     procedure SetDefaultYear;
997     {-Initialize DefaultYear and DefaultMonth}
998     var
999     Month, Day : Word;
1000     T : TDateTime;
1001     W : Word;
1002     begin
1003     T := Now;
1004     W := DefaultYear;
1005     DecodeDate(T,W,Month,Day);
1006     DefaultYear := W;
1007     DefaultMonth := Month;
1008     end;
1009    
1010     procedure ResetInternationalInfo;
1011     var
1012     I : Integer;
1013     S : array[0..20] of char;
1014    
1015     procedure ExtractSubString(SubChar : Char; Dest : string);
1016     var
1017     I, L, P : Cardinal;
1018     begin
1019     // SetLength(Dest,sizeof(wldSub1));
1020     // FillChar(Dest[1], SizeOf(wldSub1), 0);
1021     Dest := StringOfChar(#0, Succ(High(wldSub1))); //SZ: not length! [*]
1022     if NOT (StrChPosS(wLongDate, '''',I)) then
1023     Exit;
1024    
1025     {delete the first quote}
1026     wLongDate := StrChDeleteS(wLongDate, I);
1027    
1028     {assure that there is another quote}
1029     if NOT (StrChPosS(wLongDate, '''',P)) then
1030     Exit;
1031    
1032     {copy substring into Dest, replace substring with SubChar}
1033     L := 1;
1034     while wLongDate[I] <> '''' do
1035     if L < SizeOf(wldSub1) then begin
1036     Dest[L] := wLongDate[I];
1037     Inc(L);
1038     wLongDate[I] := SubChar;
1039     Inc(I);
1040     end else
1041     wLongDate := StrChDeleteL(wLongDate, I);
1042    
1043     {delete the second quote}
1044     wLongDate := StrChDeleteL(wLongDate, I);
1045     end;
1046    
1047     begin
1048     wTLZero := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongTimeFormat[2] = 'h';
1049     w12Hour := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongTimeFormat[length({$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongTimeFormat)] = 'M';
1050    
1051     wColonChar := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}TimeSeparator;
1052     wSlashChar := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}DateSeparator;
1053    
1054     GetProfileString('intl','s1159','AM', S, Length(S));
1055     w1159 := StrPas(S);
1056     GetProfileString('intl','s2359','PM', S, Length(S));
1057     w2359 := StrPas(S);
1058    
1059     {get short date mask and fix it up}
1060     wShortDate := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}ShortDateFormat;
1061     for I := 1 to Length(wShortDate) do
1062     if (wShortDate[I] = wSlashChar) then
1063     wShortDate[I] := '/';
1064    
1065     {get long date mask and fix it up}
1066     wLongDate := {$IFDEF DELPHIXE2}FormatSettings.{$ENDIF}LongDateFormat;
1067     ExtractSubString(LongDateSub1, wldSub1);
1068     ExtractSubString(LongDateSub2, wldSub2);
1069     ExtractSubString(LongDateSub3, wldSub3);
1070    
1071     {replace ddd/dddd with www/wwww}
1072     I := pos('ddd',wLongDate);
1073     if I > 0 then begin
1074     while wLongDate[I] = 'd' do begin
1075     wLongDate[I] := 'w';
1076     Inc(I);
1077     end;
1078     end;
1079    
1080     {replace MMM/MMMM with nnn/nnnn}
1081     if pos('MMM',wLongDate) > 0 then
1082     while (pos('M',wLongDate) > 0) do
1083     wLongDate[pos('M',wLongDate)] := 'n';
1084    
1085     {deal with oddities concerning . and ,}
1086     for I := 1 to Length(wLongDate)-1 do begin
1087     case wLongDate[I] of
1088     '.', ',' :
1089     if wLongDate[I+1] <> ' ' then
1090     wLongDate := StrChInsertS(wLongDate, ' ', I+1);
1091     end;
1092     end;
1093     end;
1094    
1095    
1096     initialization
1097     {initialize DefaultYear and DefaultMonth}
1098     SetDefaultYear;
1099     ResetInternationalInfo;
1100     end.

  ViewVC Help
Powered by ViewVC 1.1.20