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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2671 - (show annotations) (download)
Tue Aug 25 18:15:15 2015 UTC (8 years, 9 months ago) by torben
File size: 35306 byte(s)
Added tpsystools component
1 // 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