// Author : Gregor Ibich (gregor.ibic@intelicom.si)
// Pascal translation: Doychin Bondzhev (doichin@5group.com)
// 20240206 modified: Harald E. Sommermeyer (hes)
// Converts the following string representation into corresponding parts
// YYMMDDHHMMSS(+|-)HH( )MM
// and
// YYYYMMDDHHMMSS(+|-)HH( )MM (20240206: hes - Y2K38-Fix)
function UTC_Time_Decode(UCTtime : PASN1_UTCTIME;
var year, month, day, hour, min, sec: Word;
var tz_hour, tz_min: Integer): Integer;
var
i, tz_dir: Integer;
idx_add, idx_from: Integer;
time_str:
string;
{$IFNDEF USE_MARSHALLED_PTRS}
{$IFNDEF STRING_IS_ANSI}
LTemp: AnsiString;
{$ENDIF}
{$ENDIF}
begin
Result := 1;
if UCTtime^.length < 12
then begin
Exit;
end;
{$IFDEF USE_MARSHALLED_PTRS}
time_str := TMarshal.ReadStringAsAnsi(TPtrWrapper.Create(UCTtime^.data), UCTtime^.length);
{$ELSE}
{$IFDEF STRING_IS_ANSI}
SetString(time_str, UCTtime^.data, UCTtime^.length);
{$ELSE}
SetString(LTemp, UCTtime^.data, UCTtime^.length);
time_str :=
String(LTemp);
// explicit convert to Unicode
{$ENDIF}
{$ENDIF}
// Check if first 12 chars are numbers
// YYMMDDHHMMSS(+|-)HH( )MM
idx_from := 0;
idx_add := 0;
if not IsNumeric(time_str, 12)
then begin
Exit;
end;
// Convert time from string to number
// Y2K38 Fix: If the year has four digits, check if first 14 characters are number.
idx_from := 1;
if IsNumeric(time_str, 14)
then
begin
// YYYYMMDDHHMMSS(+|-)HH( )MM
idx_add := 4;
year := IndyStrToInt(Copy(time_str, idx_from, idx_add));
end else begin
// YYMMDDHHMMSS(+|-)HH( )MM
idx_add := 2;
year := IndyStrToInt(Copy(time_str, idx_from, idx_add)) + 1900;
end;
inc(idx_from, idx_add);
idx_add := 2;
month := IndyStrToInt(Copy(time_str, idx_from, idx_add));
inc(idx_from, idx_add);
day := IndyStrToInt(Copy(time_str, idx_from, idx_add));
inc(idx_from, idx_add);
hour := IndyStrToInt(Copy(time_str, idx_from, idx_add));
inc(idx_from, idx_add);
min := IndyStrToInt(Copy(time_str, idx_from, idx_add));
inc(idx_from, idx_add);
sec := IndyStrToInt(Copy(time_str, idx_from, idx_add));
inc(idx_from, idx_add);
// Fix year. This function is Y2k but isn't compatible with Y2k5 :-( {Do not Localize}
if year < 1950
then begin
Inc(year, 100);
end;
// Check TZ
tz_hour := 0;
tz_min := 0;
if CharIsInSet(time_str, idx_from, '
-+')
then begin {Do not Localize}
tz_dir := iif(CharEquals(time_str, idx_from, '
-'), -1, 1);
{Do not Localize}
inc(idx_from, 1);
for i := idx_from
to idx_from + 4
do begin // Check if numbers are numbers
if i = idx_from + 2
then begin
Continue;
end;
if not IsNumeric(time_str[i])
then begin
Exit;
end;
end;
tz_hour := IndyStrToInt(Copy(time_str, idx_from, idx_from + 1)) * tz_dir;
inc(idx_from, 2);
tz_min := IndyStrToInt(Copy(time_str, idx_from, idx_from + 1)) * tz_dir;
end;
end;