timeutils.pas
来自「用DELPHI实现的 PGP 加密算法」· PAS 代码 · 共 648 行 · 第 1/2 页
PAS
648 行
else Result := 28;
4, 6, 9, 11: Result := 30;
else Result := 31;
end;
end; { DaysInMonth }
function ThisYear: Word;
begin
Result := Date2Year(Date);
end; { ThisYear }
function ThisMonth: Word;
begin
Result := Date2Month(Date);
end; { ThisMonth }
function ThisDay: Word;
begin
Result := Date2Day(Date);
end; { ThisDay }
function ThisHr: Word;
begin
Result := Time2Hr(Time);
end; { ThisHr }
function ThisMin: Word;
begin
Result := Time2Min(Time);
end; { ThisMin }
function ThisSec: Word;
begin
Result := Time2Sec(Time);
end; { ThisSec }
function ThisMSec: Word;
begin
Result := Time2MSec(Time);
end; { ThisYear }
function DayOfMonth2Date(year,month,weekInMonth,dayInWeek: word): TDateTime;
var
days: integer;
day : integer;
begin
if (weekInMonth >= 1) and (weekInMonth <= 4) then begin
day := DayOfWeek(EncodeDate(year,month,1)); // get first day in month
day := 1 + dayInWeek-day; // get first dayInWeek in month
if day <= 0 then
Inc(day,7);
day := day + 7*(weekInMonth-1); // get weekInMonth-th dayInWeek in month
Result := EncodeDate(year,month,day);
end
else if weekInMonth = 5 then begin // last week, calculate from end of month
days := DaysInMonth(EncodeDate(year,month,1));
day := DayOfWeek(EncodeDate(year,month,days)); // get last day in month
day := days + (dayInWeek-day);
if day > days then
Dec(day,7); // get last dayInWeek in month
Result := EncodeDate(year,month,day);
end
else
Result := 0;
end; { DayOfMonth2Date }
function DSTDate2Date(const dstDate: TSystemTime; year: word): TDateTime;
begin
if dstDate.wMonth = 0 then
Result := 0 // invalid month => no DST info
else if dstDate.wYear = 0 then begin // day-of-month notation
Result :=
DayOfMonth2Date(year,dstDate.wMonth,dstDate.wDay,dstDate.wDayOfWeek+1{convert to Delphi Style}) +
EncodeTime(dstDate.wHour,dstDate.wMinute,dstDate.wSecond,dstDate.wMilliseconds);
end
else if dstDate.wYear = year then // absolute format - valid only for specified year
Result := SystemTimeToDateTime(dstDate)
else
Result := 0;
end; { DSTDate2Date }
function GetTZDaylightSavingInfoForYear(
const TZ: TTimeZoneInformation; year: word;
var DaylightDate, StandardDate: TDateTime;
var DaylightBias, StandardBias: longint): boolean;
begin
Result := false;
if (TZ.DaylightDate.wMonth <> 0) and
(TZ.StandardDate.wMonth <> 0) then
begin
DaylightDate := DSTDate2Date(TZ.DaylightDate,year);
StandardDate := DSTDate2Date(TZ.StandardDate,year);
DaylightBias := TZ.Bias+TZ.DaylightBias;
StandardBias := TZ.Bias+TZ.StandardBias;
Result := (DaylightDate <> 0) and (StandardDate <> 0);
end;
end; { GetTZDaylightSavingInfoForYear }
function GetTZDaylightSavingInfo(
const TZ: TTimeZoneInformation;
var DaylightDate, StandardDate: TDateTime;
var DaylightBias, StandardBias: longint): boolean;
begin
Result := GetTZDaylightSavingInfoForYear(TZ,ThisYear,DaylightDate,StandardDate,DaylightBias,StandardBias);
end; { GetTZDaylightSavingInfo }
function GetDaylightSavingInfoForYear(
year: word;
var DaylightDate, StandardDate: TDateTime;
var DaylightBias, StandardBias: longint): boolean;
var
TZ: TTimeZoneInformation;
begin
GetTimeZoneInformation(TZ);
Result := GetTZDaylightSavingInfoForYear(TZ,year,DaylightDate,StandardDate,StandardBias,DaylightBias);
end; { GetDaylightSavingInfoForYear }
function GetDaylightSavingInfo(
var DaylightDate, StandardDate: TDateTime;
var DaylightBias, StandardBias: longint): boolean;
var
TZ: TTimeZoneInformation;
begin
GetTimeZoneInformation(TZ);
Result := GetTZDaylightSavingInfo(TZ,DaylightDate,StandardDate,StandardBias,DaylightBias);
end; { GetDaylightSavingInfo }
function TZLocalTimeToUTC(
const TZ: TTimeZoneInformation;
const loctime: TDateTime;
preferDST: boolean): TDateTime;
function Convert(const startDate, endDate, startOverl, endOverl: TDateTime;
const startInval, endInval: TDateTime; inBias, outBias, overlBias: longint): TDateTime;
begin
if ((locTime > startOverl) or DateEQ(locTime,startOverl)) and (locTime < endOverl) then
Result := loctime + overlBias/MINUTES_PER_DAY
else if ((locTime > startInval) or DateEQ(locTime,startInval)) and (locTime < endInval) then
Result := 0
else if ((locTime > startDate) or DateEQ(locTime,startDate)) and (locTime < endDate) then
Result := loctime + inBias/MINUTES_PER_DAY
else
Result := loctime + outBias/MINUTES_PER_DAY;
end; { Convert }
var
dltBias : real;
overBias: longint;
stdBias : longint;
dayBias : longint;
stdDate : TDateTime;
dayDate : TDateTime;
begin { TZLocalTimeToUTC }
if GetTZDaylightSavingInfoForYear(TZ, Date2Year(loctime), dayDate, stdDate, dayBias, stdBias) then begin
if preferDST then
overBias := dayBias
else
overBias := stdBias;
dltBias := (stdBias-dayBias)/MINUTES_PER_DAY;
if dayDate < stdDate then begin // northern hemisphere
if dayBias < stdBias then // overlap at stdDate
Result := Convert(dayDate, stdDate, stdDate-dltBias, stdDate,
dayDate, dayDate+dltBias, dayBias, stdBias, overBias)
else // overlap at dayDate - that actually never happens
Result := Convert(dayDate, stdDate, dayDate+dltBias, dayDate,
stdDate, stdDate-dltBias, dayBias, stdBias, overBias);
end
else begin // southern hemisphere
if dayBias < stdBias then // overlap at stdDate
Result := Convert(stdDate, dayDate, stdDate-dltBias, stdDate,
dayDate, dayDate+dltBias, stdBias, dayBias, overBias)
else // overlap at dayDate - that actually never happens
Result := Convert(stdDate, dayDate, dayDate+dltBias, dayDate,
stdDate, stdDate-dltBias, stdBias, dayBias, overBias);
end;
end
else
Result := loctime + TZ.bias/MINUTES_PER_DAY; // TZ does not use DST
end; { TZLocalTimeToUTC }
function UTCToTZLocalTime(
const TZ: TTimeZoneInformation;
const utctime: TDateTime): TDateTime;
function Convert(const startDate, endDate: TDateTime; inBias, outBias: longint): TDateTime;
begin
if ((utctime > startDate) or DateEQ(utctime,startDate)) and (utctime < endDate) then
Result := utctime - inBias/MINUTES_PER_DAY
else
Result := utctime - outBias/MINUTES_PER_DAY;
end; { Convert }
var
stdUTC : TDateTime;
dayUTC : TDateTime;
stdBias: longint;
dayBias: longint;
stdDate: TDateTime;
dayDate: TDateTime;
begin { UTCToTZLocalTime }
if GetTZDaylightSavingInfoForYear(TZ, Date2Year(utctime), dayDate, stdDate, dayBias, stdBias) then begin
dayUTC := dayDate + stdBias/MINUTES_PER_DAY;
stdUTC := stdDate + dayBias/MINUTES_PER_DAY;
if dayUTC < stdUTC then
Result := Convert(dayUTC,stdUTC,dayBias,stdBias) // northern hem.
else
Result := Convert(stdUTC,dayUTC,stdBias,dayBias); // southern hem.
end
else
Result := utctime - TZ.bias/MINUTES_PER_DAY; // TZ does not use DST
end; { UTCToTZLocalTime }
function LocalTimeToUTC(const loctime: TDateTime; preferDST: boolean): TDateTime;
var
TZ: TTimeZoneInformation;
begin
GetTimeZoneInformation(TZ);
Result := TZLocalTimeToUTC(TZ,loctime,preferDST);
end; { LocalTimeToUTC }
function UTCToLocalTime(const utctime: TDateTime): TDateTime;
var
TZ: TTimeZoneInformation;
begin
GetTimeZoneInformation(TZ);
Result := UTCToTZLocalTime(TZ,utctime);
end; { UTCToLocalTime }
function CompareSysTime(st1, st2: TSystemTime): integer;
begin
if st1.wYear < st2.wYear then
Result := -1
else if st1.wYear > st2.wYear then
Result := 1
else if st1.wMonth < st2.wMonth then
Result := -1
else if st1.wMonth > st2.wMonth then
Result := 1
else if st1.wDayOfWeek < st2.wDayOfWeek then
Result := -1
else if st1.wDayOfWeek > st2.wDayOfWeek then
Result := 1
else if st1.wDay < st2.wDay then
Result := -1
else if st1.wDay > st2.wDay then
Result := 1
else if st1.wHour < st2.wHour then
Result := -1
else if st1.wHour > st2.wHour then
Result := 1
else if st1.wMinute < st2.wMinute then
Result := -1
else if st1.wMinute > st2.wMinute then
Result := 1
else if st1.wSecond < st2.wSecond then
Result := -1
else if st1.wSecond > st2.wSecond then
Result := 1
else if st1.wMilliseconds < st2.wMilliseconds then
Result := -1
else if st1.wMilliseconds > st2.wMilliseconds then
Result := 1
else
Result := 0;
end; { CompareSysTime }
function IsEqualTZ(tz1, tz2: TTimeZoneInformation): boolean;
begin
Result :=
(tz1.Bias = tz2.Bias) and
(tz1.StandardBias = tz2.StandardBias) and
(tz1.DaylightBias = tz2.DaylightBias) and
(CompareSysTime(tz1.StandardDate,tz2.StandardDate) = 0) and
(CompareSysTime(tz1.DaylightDate,tz2.DaylightDate) = 0) and
(WideCharToString(tz1.StandardName) = WideCharToString(tz2.StandardName)) and
(WideCharToString(tz1.DaylightName) = WideCharToString(tz2.DaylightName));
end; { IsEqualTZ }
function NowUTC: TDateTime;
var
sysnow: TSystemTime;
begin
GetSystemTime(sysnow);
Result := SystemTimeToDateTime(sysnow);
end; { NowUTC }
function TimeUTC: TDateTime;
begin
Result := Frac(NowUTC);
end; { TimeUTC }
function DateUTC: TDateTime;
begin
Result := Int(NowUTC);
end; { DateUTC }
// added by idw =========================================================== //
function SystemTimeToDateTime(const ST: TSystemTime): TDateTime;
begin
with ST do Result:=EncodeDate(wYear, wMonth, wDay) + EncodeTime(wHour, wMinute, wSecond, wMilliseconds);
end;
function SystemTimeToUnixTime(const ST: TSystemTime): longint;
var
UTC: TDateTime;
begin
UTC:=SystemTimeToDateTime(ST);
Result:=Round((UTC - EncodeDate(1970, 1, 1)) * SECONDS_PER_DAY);
end;
function UnixTimeToLocalTime(unixtime: longint): TDateTime;
var
TZ: TTimeZoneInformation;
begin
Result:=EncodeDate(1970, 1, 1) + unixtime/SECONDS_PER_DAY;
GetTimeZoneInformation(TZ);
Result:=UTCToTZLocalTime(TZ, Result);
end;
end.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?