lazarus-ccr/components/flashfiler/sourcelaz/fflldate.pas
2016-12-07 13:31:59 +00:00

296 lines
8.4 KiB
ObjectPascal

{*********************************************************}
{* FlashFiler: Date/time support routines *}
{*********************************************************}
(* ***** 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 FlashFiler
*
* 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 ***** *)
{$I ffdefine.inc}
unit fflldate;
interface
uses
ffllbase,
ffstdate,
Windows,
SysUtils;
const
{the following characters are meaningful in date Picture masks}
pmMonth = 'M'; {formatting character for a date string picture mask. }
pmDay = 'D'; {formatting character for a date string picture mask. }
pmYear = 'Y'; {formatting character for a date string picture mask}
pmDateSlash = '/'; {formatting character for a date string picture mask}
pmHour = 'h'; {formatting character for a time string picture mask}
pmMinute = 'm'; {formatting character for a time string picture mask}
pmSecond = 's'; {formatting character for a time string picture mask}
{'hh:mm:ss tt' -\> '12:00:00 pm', 'hh:mmt' -\> '12:00p'}
pmAmPm = 't'; {formatting character for a time string picture mask.
This generates 'AM' or 'PM'}
pmTimeColon = ':'; {formatting character for a time string picture mask}
MaxDateLen = 40; { maximum length of date picture mask }
function DateStringToDMY(const Picture, S : string; var Day, Month, Year : Integer;
Epoch : Integer) : Boolean;
{-extract day, month, and year from S, returning true if string is valid}
function DatePCharToDMY(Picture, S : PAnsiChar; var Day, Month, Year : Integer;
Epoch : Integer) : Boolean;
{-extract day, month, and year from S, returning true if string is valid}
function TimeStringToHMS(const Picture, S : string;
var Hour, Minute, Second : Integer) : Boolean;
{-extract Hours, Minutes, Seconds from St, returning true if string is valid}
function TimePCharToHMS(Picture, S : PAnsiChar;
var Hour, Minute, Second : Integer) : Boolean;
{-extract Hours, Minutes, Seconds from St, returning true if string is valid}
implementation
var
w1159 : array[0..5] of AnsiChar;
w2359 : array[0..5] of AnsiChar;
{===== Internal Routines =====}
function StrChPos(P : PAnsiChar; C : AnsiChar;
var Pos : Cardinal): Boolean; register;
{-Sets Pos to position of character C within string P returns True if found}
asm
push esi {save since we'll be changing}
push edi
push ebx
mov esi, ecx {save Pos}
cld {forward string ops}
mov edi, eax {copy P to EDI}
or ecx, -1
xor eax, eax {zero}
mov ebx, edi {save EDI to EBX}
repne scasb {search for NULL terminator}
not ecx
dec ecx {ecx has len of string}
test ecx, ecx
jz @@NotFound {if len of P = 0 then done}
mov edi, ebx {reset EDI to beginning of string}
mov al, dl {copy C to AL}
repne scasb {find C in string}
jne @@NotFound
mov ecx, edi {calculate position of C}
sub ecx, ebx
dec ecx {ecx holds found position}
mov [esi], ecx {store location}
mov eax, 1 {return true}
jmp @@ExitCode
@@NotFound:
xor eax, eax
@@ExitCode:
pop ebx {restore registers}
pop edi
pop esi
end;
function UpCaseChar(C : AnsiChar) : AnsiChar; register;
asm
and eax, 0FFh
push eax
call CharUpper
end;
procedure ExtractFromPicture(Picture, S : PAnsiChar;
Ch : AnsiChar; 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 : Array[0..20] of AnsiChar;
J, K : Cardinal;
Code : Integer;
Found,
UpFound : Boolean;
begin
{find the start of the subfield}
I := Default;
Found := StrChPos(Picture, Ch, J);
Ch := UpCaseChar(Ch);
UpFound := StrChPos(Picture, Ch, K);
if not Found or (UpFound and (K < J)) then begin
J := K;
Found := UpFound;
end;
if not Found or (StrLen(S) <> StrLen(Picture)) then
Exit;
{extract the substring}
PTmp[0] := #0;
K := 0;
while (UpCaseChar(Picture[J]) = Ch) and (J < StrLen(Picture)) do begin
if S[J] <> ' ' then begin
PTmp[k] := S[J];
Inc(K);
PTmp[k] := #0;
end;
Inc(J);
end;
if StrLen(PTmp) = 0 then
I := Blank
else begin
{convert to a value}
Val(PTmp, I, Code);
if Code <> 0 then
I := -1;
end;
end;
{===== Exported routines =====}
function DateStringToDMY(const Picture, S : string; var Day, Month, Year : Integer;
Epoch : Integer) : Boolean;
{-extract day, month, and year from S, returning true if string is valid}
var
Buf1 : array[0..255] of AnsiChar;
Buf2 : array[0..255] of AnsiChar;
begin
StrPCopy(Buf1, Picture);
StrPCopy(Buf2, S);
Result := DatePCharToDMY(Buf1, Buf2, Day, Month, Year, Epoch);
end;
function DatePCharToDMY(Picture, S : PAnsiChar; var Day, Month, Year : Integer;
Epoch : Integer) : Boolean;
{-extract day, month, and year from S, returning true if string is valid}
begin
Result := False;
if StrLen(Picture) <> StrLen(S) then
Exit;
ExtractFromPicture(Picture, S, pmMonth, Month, -1, DefaultMonth);
ExtractFromPicture(Picture, S, pmDay, Day, -1, 1);
ExtractFromPicture(Picture, S, pmYear, Year, -1, DefaultYear);
Result := ValidDate(Day, Month, Year, Epoch);
end;
function TimeStringToHMS(const Picture, S : string;
var Hour, Minute, Second : Integer) : Boolean;
{-extract Hours, Minutes, Seconds from St, returning true if string is valid}
var
Buf1 : array[0..255] of AnsiChar;
Buf2 : array[0..255] of AnsiChar;
begin
StrPCopy(Buf1, Picture);
StrPCopy(Buf2, S);
Result := TimePCharToHMS(Buf1, Buf2, Hour, Minute, Second);
end;
function TimePCharToHMS(Picture, S : PAnsiChar;
var Hour, Minute, Second : Integer) : Boolean;
{-extract Hours, Minutes, Seconds from St, returning true if string is valid}
var
I, J : Cardinal;
Tmp,
t1159,
t2359 : array[0..20] of AnsiChar;
begin
Result := False;
if StrLen(Picture) <> StrLen(S) then
Exit;
{extract hours, minutes, seconds from St}
ExtractFromPicture(Picture, S, pmHour, Hour, -1, 0);
ExtractFromPicture(Picture, S, pmMinute, Minute, -1, 0);
ExtractFromPicture(Picture, S, pmSecond, Second, -1, 0);
if (Hour = -1) or (Minute = -1) or (Second = -1) then begin
Result := False;
Exit;
end;
{check for TimeOnly}
if StrChPos(Picture, pmAmPm, I) and (w1159[0] <> #0)
and (w2359[0] <> #0) then begin
Tmp[0] := #0;
J := 0;
while Picture[I] = pmAmPm do begin
Tmp[J] := S[I];
Inc(J);
Inc(I);
end;
Tmp[J] := #0;
FFStrTrimR(Tmp);
StrCopy(t1159, w1159);
t1159[J] := #0;
StrCopy(t2359, w2359);
t2359[J] := #0;
if (Tmp[0] = #0) then
Hour := -1
else if StrIComp(Tmp, t2359) = 0 then begin
if (Hour < 12) then
Inc(Hour, 12)
else if (Hour = 0) or (Hour > 12) then
{force BadTime}
Hour := -1;
end else if StrIComp(Tmp, t1159) = 0 then begin
if Hour = 12 then
Hour := 0
else if (Hour = 0) or (Hour > 12) then
{force BadTime}
Hour := -1;
end else
{force BadTime}
Hour := -1;
end;
Result := ValidTime(Hour, Minute, Second);
end;
initialization
GetProfileString('intl', 's1159', 'AM', w1159, SizeOf(w1159));
GetProfileString('intl', 's2359', 'PM', w2359, SizeOf(w2359));
end.