658 lines
17 KiB
Plaintext
658 lines
17 KiB
Plaintext
{*******************************************************}
|
|
{ }
|
|
{ Tocsg.DateTime }
|
|
{ }
|
|
{ Copyright (C) 2022 kkuzil }
|
|
{ }
|
|
{*******************************************************}
|
|
|
|
unit Tocsg.DateTime;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.Generics.Collections, System.Generics.Defaults, System.SysUtils,
|
|
Winapi.Windows;
|
|
|
|
type
|
|
TDateTimeList = TList<TDateTime>;
|
|
|
|
TDateTimeComparer = class(TComparer<TDateTime>)
|
|
public
|
|
function Compare(const Left, Right: TDateTime): Integer; override;
|
|
end;
|
|
|
|
function ConvStrToDateTime(sDtStr: String): TDateTime; {$IFDEF RELEASE} inline; {$ENDIF}
|
|
function ConvSecToProgTime(dwSec: DWORD): String; inline;
|
|
function ConvSecBetweenToProgTime(dtNow, dtThen: TDateTime): String;
|
|
|
|
function GetBootTime: TDateTime;
|
|
function GetLocalIncUtcMin: Integer; // 로컬 타임존 UTC+분
|
|
|
|
function ConvFileTimeToDateTime(const aFileTime: TFileTime): TDateTime;
|
|
function ConvFileTimeToDateTime_Local(const aFileTime: TFileTime): TDateTime;
|
|
function ConvSystemTimeToDateTime(const st: TSystemTime): TDateTime;
|
|
function ConvSystemTimeToDateTime_Local(const st: TSystemTime): TDateTime;
|
|
function ConvDateTimeToSystemTime(dt: TDateTime): TSystemTime;
|
|
function ConvDateTimeToSystemTime_Local(dt: TDateTime): TSystemTime;
|
|
function ConvDateTimeToFileTime(dt: TDateTime): TFileTime;
|
|
function ConvUtcToLocal(dt: TDateTime): TDateTime;
|
|
function ConvLocalToUtc(dt: TDateTime): TDateTime;
|
|
|
|
function ConvTimeToDateTime(t: Integer): TDateTime;
|
|
function ConvTimestampToDateTime(llTime: LONGLONG): TDateTime;
|
|
function ConvChromeTimestampToDateTime(llTime: LONGLONG): TDateTime;
|
|
function ConvTimestampToFileTime_Local(llTime: LONGLONG): TFileTime;
|
|
function ConvTimestampToFileTime(llTime: LONGLONG): TFileTIme;
|
|
function ConvJavaToDelphiDateTime(const llVal: LONGLONG; bUtc0: Boolean = false): TDateTime;
|
|
|
|
function ConvStrDtToDateTime(const sDateTime: String): TDateTime;
|
|
function UnixTimeToDateTime(llDT: LONGLONG): TDateTime;
|
|
|
|
function AppendTime(dt: TDateTime; wHour, wMin, wSec, wMSec: WORD): TDateTime;
|
|
|
|
function RawStrToDateTime(const RawStr: string): TDateTime;
|
|
|
|
function JavaDtToDelphiDt(const dt: int64): TDateTime;
|
|
function DelphiDtToJavaDt(const dt: TDateTime): int64;
|
|
|
|
implementation
|
|
|
|
uses
|
|
System.DateUtils, Tocsg.Exception;
|
|
|
|
{ TDateTimeComparer }
|
|
|
|
function TDateTimeComparer.Compare(const Left, Right: TDateTime): Integer;
|
|
begin
|
|
Result := CompareDateTime(Right, Left);
|
|
end;
|
|
|
|
{ Other }
|
|
|
|
function ConvStrToDateTime(sDtStr: String): TDateTime;
|
|
var
|
|
wLen, wYear, wMonth, wDay, wHour, wMin, wSec: WORD;
|
|
begin
|
|
Result := 0;
|
|
|
|
sDtStr := StringReplace(sDtStr, '-', '', [rfReplaceAll]);
|
|
sDtStr := StringReplace(sDtStr, ':', '', [rfReplaceAll]);
|
|
sDtStr := StringReplace(sDtStr, ' ', '', [rfReplaceAll]);
|
|
|
|
wLen := sDtStr.Length;
|
|
if wLen >= 8 then
|
|
begin
|
|
wYear := StrToIntDef(Copy(sDtStr, 1, 4), 0);
|
|
wMonth := StrToIntDef(Copy(sDtStr, 5, 2), 0);
|
|
wDay := StrToIntDef(Copy(sDtStr, 7, 2), 0);
|
|
if wLen >= 14 then
|
|
begin
|
|
wHour := StrToIntDef(Copy(sDtStr, 9, 2), 0);
|
|
wMin := StrToIntDef(Copy(sDtStr, 11, 2), 0);
|
|
wSec := StrToIntDef(Copy(sDtStr, 13, 2), 0);
|
|
end else begin
|
|
wHour := 0;
|
|
wMin := 0;
|
|
wSec := 0;
|
|
end;
|
|
|
|
try
|
|
Result := EncodeDateTime(wYear, wMonth, wDay, wHour, wMin, wSec, 0);
|
|
except
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function ConvSecToProgTime(dwSec: DWORD): String;
|
|
var
|
|
dwMin,
|
|
dwHour, dwDay: DWORD;
|
|
begin
|
|
dwMin := (dwSec div 60) mod 60;
|
|
dwHour := (dwSec div 60 div 60) mod 24;
|
|
dwDay := dwSec div 60 div 60 div 24;
|
|
dwSec := dwSec mod 60;
|
|
if dwDay > 0 then
|
|
begin
|
|
if (dwHour + dwMin + dwSec) = 0 then
|
|
Result := Format('%dDay', [dwDay])
|
|
else
|
|
Result := Format('%dDay, %.2d:%.2d:%.2d', [dwDay, dwHour, dwMin, dwSec]);
|
|
end else
|
|
Result := Format('%.2d:%.2d:%.2d', [dwHour, dwMin, dwSec]);
|
|
end;
|
|
|
|
function ConvSecBetweenToProgTime(dtNow, dtThen: TDateTime): String;
|
|
begin
|
|
Result := ConvSecToProgTime(SecondsBetween(dtNow, dtThen));
|
|
end;
|
|
|
|
function GetBootTime: TDateTime;
|
|
begin
|
|
Result := IncMilliSecond(now, LONGLONG(-1) * GetTickCount);
|
|
end;
|
|
|
|
function GetLocalIncUtcMin: Integer;
|
|
begin
|
|
Result := (TTimeZone.Local.UtcOffset.Hours * 60) + TTimeZone.Local.UtcOffset.Minutes;
|
|
end;
|
|
|
|
function ConvFileTimeToDateTime(const aFileTime: TFileTime): TDateTime;
|
|
var
|
|
nDosTime: Integer;
|
|
begin
|
|
Result := 0;
|
|
try
|
|
if WinApi.Windows.FileTimeToDosDateTime(aFileTime, LongRec(nDosTime).Hi,
|
|
LongRec(nDosTime).Lo) then
|
|
try
|
|
Result := FileDateToDateTime(nDosTime);
|
|
except
|
|
On EConvertError do
|
|
exit;
|
|
end;
|
|
except
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
function ConvFileTimeToDateTime_Local(const aFileTime: TFileTime): TDateTime;
|
|
var
|
|
lcFT : TFileTime;
|
|
lc: Integer;
|
|
begin
|
|
Result := 0;
|
|
if WinApi.Windows.FileTimeToLocalFileTime(aFileTime, lcFT) then
|
|
begin
|
|
if WinApi.Windows.FileTimeToDosDateTime(lcFT, LongRec(lc).Hi, LongRec(lc).Lo) then
|
|
try
|
|
Result := FileDateToDateTime(lc);
|
|
except
|
|
On EConvertError do
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function ConvSystemTimeToDateTime(const st: TSystemTime): TDateTime;
|
|
var
|
|
ft: TFileTime;
|
|
begin
|
|
Result := 0;
|
|
|
|
if SystemTimeToFileTime(st, ft) then
|
|
Result := ConvFileTimeToDateTime(ft);
|
|
end;
|
|
|
|
function ConvSystemTimeToDateTime_Local(const st: TSystemTime): TDateTime;
|
|
var
|
|
ft: TFileTime;
|
|
begin
|
|
Result := 0;
|
|
|
|
if SystemTimeToFileTime(st, ft) then
|
|
Result := ConvFileTimeToDateTime_Local(ft);
|
|
end;
|
|
|
|
function ConvDateTimeToSystemTime(dt: TDateTime): TSystemTime;
|
|
begin
|
|
try
|
|
if not FileTimeToSystemTime(ConvDateTimeToFileTime(dt), Result) then
|
|
ZeroMemory(@Result, SizeOf(Result));
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
ETgException.TraceException(E, 'Fail .. ConvDateTimeToSystemTime()');
|
|
ZeroMemory(@Result, SizeOf(Result));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function ConvDateTimeToSystemTime_Local(dt: TDateTime): TSystemTime;
|
|
var
|
|
lcFT: TFileTime;
|
|
begin
|
|
ZeroMemory(@Result, SizeOf(Result));
|
|
try
|
|
if WinApi.Windows.FileTimeToLocalFileTime(ConvDateTimeToFileTime(dt), lcFT) then
|
|
FileTimeToSystemTime(lcFT, Result);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. ConvDateTimeToSystemTime_Local()');
|
|
end;
|
|
end;
|
|
|
|
function ConvDateTimeToFileTime(dt: TDateTime): TFileTime;
|
|
var
|
|
LocalFileTime, Ft: TFileTime;
|
|
SystemTime: TSystemTime;
|
|
begin
|
|
Result.dwLowDateTime := 0;
|
|
Result.dwHighDateTime := 0;
|
|
try
|
|
DateTimeToSystemTime(dt, SystemTime);
|
|
SystemTimeToFileTime(SystemTime, LocalFileTime);
|
|
LocalFileTimeToFileTime(LocalFileTime, Ft);
|
|
Result := Ft;
|
|
except
|
|
ZeroMemory(@Result, SizeOf(Result));
|
|
end;
|
|
end;
|
|
|
|
function ConvUtcToLocal(dt: TDateTime): TDateTime;
|
|
var
|
|
tzi: TTimeZoneInformation;
|
|
lt, ut: TSystemTime;
|
|
begin
|
|
Result := 0;
|
|
try
|
|
GetTimeZoneInformation(tzi);
|
|
DateTimeToSystemTime(dt, ut);
|
|
SystemTimeToTzSpecificLocalTime(@tzi, ut, lt);
|
|
Result := SystemTimeToDateTime(lt);
|
|
except
|
|
|
|
end;
|
|
end;
|
|
|
|
function ConvLocalToUtc(dt: TDateTime): TDateTime;
|
|
begin
|
|
Result := 0;
|
|
try
|
|
Result := TTimeZone.Local.ToUniversalTime(Now);
|
|
except
|
|
|
|
end;
|
|
end;
|
|
|
|
function ConvTimeToDateTime(t: Integer): TDateTime;
|
|
var
|
|
sysTime, sysTime1 : TSystemTime;
|
|
begin
|
|
DateTimeToSystemTime(EncodeDate(1970, 1, 1) + (t / 86400), sysTime);
|
|
SystemTimeToTzSpecificLocalTime(nil, sysTime, sysTime1);
|
|
Result := SystemTimeToDateTime(sysTime1);
|
|
end;
|
|
|
|
function ConvTimestampToDateTime(llTime: LONGLONG): TDateTime;
|
|
var
|
|
nTime: Integer;
|
|
ft: TFileTime;
|
|
begin
|
|
Result := 0;
|
|
// 이 값이 들어오는 경우가 있는데..
|
|
// 이 경우는 FileDateToDateTime() 여기서 예외가 발생해서 미리 체크함 20_0522 09:26:30 sunk
|
|
if llTime <> 116444736000000000 then
|
|
begin
|
|
CopyMemory(@ft, @llTime, SizeOf(LONGLONG));
|
|
try
|
|
FileTimeToDosDateTime(ft, LongRec(nTime).Hi, LongRec(nTime).Lo);
|
|
if nTime > 0 then
|
|
Result := FileDateToDateTime(nTime);
|
|
except
|
|
// On EConvertError do
|
|
// exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function ConvChromeTimestampToDateTime(llTime: LONGLONG): TDateTime;
|
|
begin
|
|
{
|
|
u : Unix timestamp eg: 1378615325
|
|
j : JavaScript timestamp eg: 1378615325177
|
|
c : Chrome timestamp eg: 13902597987770000
|
|
w : Windows timestamp eg: 139025979877700000
|
|
|
|
u = (j / 1000)
|
|
u = (c - 116444736000000) / 10000000
|
|
u = (w - 1164447360000000) / 100000000
|
|
|
|
j = (u * 1000)
|
|
j = (c - 116444736000000) / 10000
|
|
j = (w - 1164447360000000) / 100000
|
|
|
|
c = (u * 10000000) + 116444736000000
|
|
c = (j * 10000) + 116444736000000
|
|
c = (w / 10)
|
|
|
|
w = (u * 100000000) + 1164447360000000
|
|
w = (j * 100000) + 1164447360000000
|
|
w = (c * 10)
|
|
}
|
|
if llTime > 116444736000000 then
|
|
Result := ConvTimestampToDateTime(llTime * 10)
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function ConvTimestampToFileTime_Local(llTime: LONGLONG): TFileTime;
|
|
var
|
|
ft,
|
|
localft: TFileTime;
|
|
begin
|
|
CopyMemory(@ft, @llTime, SizeOf(LONGLONG));
|
|
|
|
try
|
|
FileTimeToLocalFileTime(ft, localft); // 생성일 기준
|
|
Result := localft;
|
|
except
|
|
ZeroMemory(@Result, SizeOf(Result));
|
|
end;
|
|
end;
|
|
|
|
function ConvTimestampToFileTime(llTime: LONGLONG): TFileTIme;
|
|
var
|
|
ft: TFileTime;
|
|
begin
|
|
CopyMemory(@ft, @llTime, SizeOf(LONGLONG));
|
|
Result := ft;
|
|
end;
|
|
|
|
// superobject.pas에 있는거 가져옴
|
|
function ConvJavaToDelphiDateTime(const llVal: LONGLONG; bUtc0: Boolean = false): TDateTime;
|
|
var
|
|
t: TSystemTime;
|
|
begin
|
|
DateTimeToSystemTime(25569 + (llVal / 86400000), t);
|
|
if not bUtc0 then
|
|
SystemTimeToTzSpecificLocalTime(nil, t, t);
|
|
Result := SystemTimeToDateTime(t);
|
|
end;
|
|
|
|
function ConvStrDtToDateTime(const sDateTime: String): TDateTime;
|
|
var
|
|
wLen, wYear, wMonth, wDay, wHour, wMin, wSec: WORD;
|
|
begin
|
|
Result := 0;
|
|
|
|
wLen := Length(sDateTime);
|
|
if wLen >= 8 then
|
|
begin
|
|
wYear := StrToIntDef(Copy(sDateTime, 1, 4), 0);
|
|
wMonth := StrToIntDef(Copy(sDateTime, 5, 2), 0);
|
|
wDay := StrToIntDef(Copy(sDateTime, 7, 2), 0);
|
|
if wLen >= 14 then
|
|
begin
|
|
wHour := StrToIntDef(Copy(sDateTime, 9, 2), 0);
|
|
wMin := StrToIntDef(Copy(sDateTime, 11, 2), 0);
|
|
wSec := StrToIntDef(Copy(sDateTime, 13, 2), 0);
|
|
end else begin
|
|
wHour := 0;
|
|
wMin := 0;
|
|
wSec := 0;
|
|
end;
|
|
|
|
try
|
|
Result := EncodeDateTime(wYear, wMonth, wDay, wHour, wMin, wSec, 0);
|
|
except
|
|
Result := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function UnixTimeToDateTime(llDT: LONGLONG): TDateTime;
|
|
begin
|
|
Result := (llDT / 86400) + 25569;
|
|
end;
|
|
|
|
function AppendTime(dt: TDateTime; wHour, wMin, wSec, wMSec: WORD): TDateTime;
|
|
var
|
|
wYear, wMonth, wDay: WORD;
|
|
begin
|
|
try
|
|
DecodeDate(dt, wYear, wMonth, wDay);
|
|
Result := EncodeDateTime(wYear, wMonth, wDay, wHour, wMin, wSec, wMSec);
|
|
except
|
|
Result := dt;
|
|
end;
|
|
end;
|
|
|
|
function RawStrToDateTime(const RawStr: string): TDateTime;
|
|
var
|
|
v: Int64;
|
|
begin
|
|
v := StrToInt64(RawStr);
|
|
Result := PDouble(@v)^;
|
|
end;
|
|
|
|
// superobject.pas에서 가져옴
|
|
function DayLightCompareDate(const date: PSystemTime;
|
|
const compareDate: PSystemTime): Integer;
|
|
var
|
|
limit_day, dayinsecs, weekofmonth: Integer;
|
|
First: Word;
|
|
begin
|
|
if (date^.wMonth < compareDate^.wMonth) then
|
|
begin
|
|
Result := -1; (* We are in a month before the date limit. *)
|
|
Exit;
|
|
end;
|
|
|
|
if (date^.wMonth > compareDate^.wMonth) then
|
|
begin
|
|
Result := 1; (* We are in a month after the date limit. *)
|
|
Exit;
|
|
end;
|
|
|
|
(* if year is 0 then date is in day-of-week format, otherwise
|
|
* it's absolute date.
|
|
*)
|
|
if (compareDate^.wYear = 0) then
|
|
begin
|
|
(* compareDate.wDay is interpreted as number of the week in the month
|
|
* 5 means: the last week in the month *)
|
|
weekofmonth := compareDate^.wDay;
|
|
(* calculate the day of the first DayOfWeek in the month *)
|
|
First := (6 + compareDate^.wDayOfWeek - date^.wDayOfWeek + date^.wDay) mod 7 + 1;
|
|
limit_day := First + 7 * (weekofmonth - 1);
|
|
(* check needed for the 5th weekday of the month *)
|
|
if (limit_day > MonthDays[(date^.wMonth=2) and IsLeapYear(date^.wYear)][date^.wMonth]) then
|
|
dec(limit_day, 7);
|
|
end
|
|
else
|
|
limit_day := compareDate^.wDay;
|
|
|
|
(* convert to seconds *)
|
|
limit_day := ((limit_day * 24 + compareDate^.wHour) * 60 + compareDate^.wMinute ) * 60;
|
|
dayinsecs := ((date^.wDay * 24 + date^.wHour) * 60 + date^.wMinute ) * 60 + date^.wSecond;
|
|
(* and compare *)
|
|
|
|
if dayinsecs < limit_day then
|
|
Result := -1 else
|
|
if dayinsecs > limit_day then
|
|
Result := 1 else
|
|
Result := 0; (* date is equal to the date limit. *)
|
|
end;
|
|
|
|
function CompTimeZoneID(const pTZinfo: PTimeZoneInformation;
|
|
lpFileTime: PFileTime; islocal: Boolean): LongWord;
|
|
var
|
|
ret: Integer;
|
|
beforeStandardDate, afterDaylightDate: Boolean;
|
|
llTime: Int64;
|
|
SysTime: TSystemTime;
|
|
ftTemp: TFileTime;
|
|
begin
|
|
llTime := 0;
|
|
|
|
if (pTZinfo^.DaylightDate.wMonth <> 0) then
|
|
begin
|
|
(* if year is 0 then date is in day-of-week format, otherwise
|
|
* it's absolute date.
|
|
*)
|
|
if ((pTZinfo^.StandardDate.wMonth = 0) or
|
|
((pTZinfo^.StandardDate.wYear = 0) and
|
|
((pTZinfo^.StandardDate.wDay < 1) or
|
|
(pTZinfo^.StandardDate.wDay > 5) or
|
|
(pTZinfo^.DaylightDate.wDay < 1) or
|
|
(pTZinfo^.DaylightDate.wDay > 5)))) then
|
|
begin
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
Result := TIME_ZONE_ID_INVALID;
|
|
Exit;
|
|
end;
|
|
|
|
if (not islocal) then
|
|
begin
|
|
llTime := PInt64(lpFileTime)^;
|
|
dec(llTime, Int64(pTZinfo^.Bias + pTZinfo^.DaylightBias) * 600000000);
|
|
PInt64(@ftTemp)^ := llTime;
|
|
lpFileTime := @ftTemp;
|
|
end;
|
|
|
|
FileTimeToSystemTime(lpFileTime^, SysTime);
|
|
|
|
(* check for daylight savings *)
|
|
ret := DayLightCompareDate(@SysTime, @pTZinfo^.StandardDate);
|
|
if (ret = -2) then
|
|
begin
|
|
Result := TIME_ZONE_ID_INVALID;
|
|
Exit;
|
|
end;
|
|
|
|
beforeStandardDate := ret < 0;
|
|
|
|
if (not islocal) then
|
|
begin
|
|
dec(llTime, Int64(pTZinfo^.StandardBias - pTZinfo^.DaylightBias) * 600000000);
|
|
PInt64(@ftTemp)^ := llTime;
|
|
FileTimeToSystemTime(lpFileTime^, SysTime);
|
|
end;
|
|
|
|
ret := DayLightCompareDate(@SysTime, @pTZinfo^.DaylightDate);
|
|
if (ret = -2) then
|
|
begin
|
|
Result := TIME_ZONE_ID_INVALID;
|
|
Exit;
|
|
end;
|
|
|
|
afterDaylightDate := ret >= 0;
|
|
|
|
Result := TIME_ZONE_ID_STANDARD;
|
|
if( pTZinfo^.DaylightDate.wMonth < pTZinfo^.StandardDate.wMonth ) then
|
|
begin
|
|
(* Northern hemisphere *)
|
|
if( beforeStandardDate and afterDaylightDate) then
|
|
Result := TIME_ZONE_ID_DAYLIGHT;
|
|
end else (* Down south *)
|
|
if( beforeStandardDate or afterDaylightDate) then
|
|
Result := TIME_ZONE_ID_DAYLIGHT;
|
|
end else
|
|
(* No transition date *)
|
|
Result := TIME_ZONE_ID_UNKNOWN;
|
|
end;
|
|
|
|
function GetTimezoneBias(const pTZinfo: PTimeZoneInformation;
|
|
lpFileTime: PFileTime; islocal: Boolean; pBias: PLongint): Boolean;
|
|
var
|
|
bias: LongInt;
|
|
tzid: LongWord;
|
|
begin
|
|
bias := pTZinfo^.Bias;
|
|
tzid := CompTimeZoneID(pTZinfo, lpFileTime, islocal);
|
|
|
|
if( tzid = TIME_ZONE_ID_INVALID) then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end;
|
|
if (tzid = TIME_ZONE_ID_DAYLIGHT) then
|
|
inc(bias, pTZinfo^.DaylightBias)
|
|
else if (tzid = TIME_ZONE_ID_STANDARD) then
|
|
inc(bias, pTZinfo^.StandardBias);
|
|
pBias^ := bias;
|
|
Result := True;
|
|
end;
|
|
|
|
function TzSpecificLocalTimeToSystemTime(
|
|
const lpTimeZoneInformation: PTimeZoneInformation;
|
|
const lpLocalTime: PSystemTime; lpUniversalTime: PSystemTime): BOOL;
|
|
var
|
|
ft: TFileTime;
|
|
lBias: LongInt;
|
|
t: Int64;
|
|
tzinfo: TTimeZoneInformation;
|
|
begin
|
|
if (lpTimeZoneInformation <> nil) then
|
|
tzinfo := lpTimeZoneInformation^
|
|
else
|
|
if (GetTimeZoneInformation(tzinfo) = TIME_ZONE_ID_INVALID) then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end;
|
|
|
|
if (not SystemTimeToFileTime(lpLocalTime^, ft)) then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end;
|
|
t := PInt64(@ft)^;
|
|
if (not GetTimezoneBias(@tzinfo, @ft, True, @lBias)) then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end;
|
|
(* convert minutes to 100-nanoseconds-ticks *)
|
|
inc(t, Int64(lBias) * 600000000);
|
|
PInt64(@ft)^ := t;
|
|
Result := FileTimeToSystemTime(ft, lpUniversalTime^);
|
|
end;
|
|
|
|
function SystemTimeToTzSpecificLocalTime(
|
|
lpTimeZoneInformation: PTimeZoneInformation;
|
|
lpUniversalTime, lpLocalTime: PSystemTime): BOOL;
|
|
var
|
|
ft: TFileTime;
|
|
lBias: LongInt;
|
|
llTime: Int64;
|
|
tzinfo: TTimeZoneInformation;
|
|
begin
|
|
if (lpTimeZoneInformation <> nil) then
|
|
tzinfo := lpTimeZoneInformation^ else
|
|
if (GetTimeZoneInformation(tzinfo) = TIME_ZONE_ID_INVALID) then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end;
|
|
|
|
if (not SystemTimeToFileTime(lpUniversalTime^, ft)) then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end;
|
|
llTime := PInt64(@ft)^;
|
|
if (not GetTimezoneBias(@tzinfo, @ft, False, @lBias)) then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end;
|
|
(* convert minutes to 100-nanoseconds-ticks *)
|
|
dec(llTime, Int64(lBias) * 600000000);
|
|
PInt64(@ft)^ := llTime;
|
|
Result := FileTimeToSystemTime(ft, lpLocalTime^);
|
|
end;
|
|
|
|
function JavaDtToDelphiDt(const dt: int64): TDateTime;
|
|
var
|
|
t: TSystemTime;
|
|
begin
|
|
DateTimeToSystemTime(25569 + (dt / 86400000), t);
|
|
SystemTimeToTzSpecificLocalTime(nil, @t, @t);
|
|
Result := SystemTimeToDateTime(t);
|
|
end;
|
|
|
|
function DelphiDtToJavaDt(const dt: TDateTime): int64;
|
|
var
|
|
t: TSystemTime;
|
|
begin
|
|
DateTimeToSystemTime(dt, t);
|
|
TzSpecificLocalTimeToSystemTime(nil, @t, @t);
|
|
Result := Round((SystemTimeToDateTime(t) - 25569) * 86400000)
|
|
end;
|
|
|
|
end.
|