📄 stdate.pas
字号:
else if (Year = 1582) then begin
if (Month > 10) then
GC := True
else if (Month < 10) then
GC := False
else begin
if (Date >= 15) then
GC := True
else
GC := False;
end;
end else
GC := False;
if (GC) then
B := 2 - A + abs(A div 4)
else
B := 0;
Result := Trunc(365.25 * (Year + 4716))
+ Trunc(30.6001 * (Month + 1))
+ Date + B - 1524.5
+ UT / SecondsInDay;
end;
function AstJulianDatetoStDate(AstJulian : Double; Truncate : Boolean) : TStDate;
{-Returns a TStDate from an Astronomical Julian Date.
Truncate TRUE Converts to appropriate 0 hours then truncates
FALSE Converts to appropriate 0 hours, then rounds to
nearest;}
begin
{Convert to TStDate, adding 0.5d for implied .0d of TStDate}
AstJulian := AstJulian + 0.5 - DeltaJD;
if (AstJulian < MinDate) OR (AstJulian > MaxDate) then
begin
Result := BadDate;
Exit;
end;
if Truncate then
Result := Trunc(AstJulian)
else
Result := Trunc(AstJulian + 0.5);
end;
procedure StDateToDMY(Julian : TStDate; var Day, Month, Year : Integer);
{-Convert from a julian date to month, day, year}
var
I, J : LongInt;
begin
if Julian = BadDate then begin
Day := 0;
Month := 0;
Year := 0;
end else if Julian <= First2Months then begin
Year := MinYear;
if Julian <= 30 then begin
Month := 1;
Day := Succ(Julian);
end else begin
Month := 2;
Day := Julian-30;
end;
end else begin
I := (4*LongInt(Julian-First2Months))-1;
J := (4*((I mod Days400Yr) div 4))+3;
Year := (100*(I div Days400Yr))+(J div 1461);
I := (5*(((J mod 1461)+4) div 4))-3;
Day := ((I mod 153)+5) div 5;
Month := I div 153;
if Month < 10 then
Inc(Month, 3)
else begin
Dec(Month, 9);
Inc(Year);
end;
Inc(Year, MinYear);
end;
end;
function IncDate(Julian : TStDate; Days, Months, Years : Integer) : TStDate;
{-Add (or subtract) the number of months, days, and years to a date.
Months and years are added before days. No overflow/underflow
checks are made}
var
Day, Month, Year, Day28Delta : Integer;
begin
StDateToDMY(Julian, Day, Month, Year);
Day28Delta := Day-28;
if Day28Delta < 0 then
Day28Delta := 0
else
Day := 28;
Inc(Year, Years);
Inc(Year, Months div 12);
Inc(Month, Months mod 12);
if Month < 1 then begin
Inc(Month, 12);
Dec(Year);
end
else if Month > 12 then begin
Dec(Month, 12);
Inc(Year);
end;
Julian := DMYtoStDate(Day, Month, Year,0);
if Julian <> BadDate then begin
Inc(Julian, Days);
Inc(Julian, Day28Delta);
end;
Result := Julian;
end;
function IncDateTrunc(Julian : TStDate; Months, Years : Integer) : TStDate;
{-Add (or subtract) the specified number of months and years to a date}
var
Day, Month, Year : Integer;
MaxDay, Day28Delta : Integer;
begin
StDateToDMY(Julian, Day, Month, Year);
Day28Delta := Day-28;
if Day28Delta < 0 then
Day28Delta := 0
else
Day := 28;
Inc(Year, Years);
Inc(Year, Months div 12);
Inc(Month, Months mod 12);
if Month < 1 then begin
Inc(Month, 12);
Dec(Year);
end
else if Month > 12 then begin
Dec(Month, 12);
Inc(Year);
end;
Julian := DMYtoStDate(Day, Month, Year,0);
if Julian <> BadDate then begin
MaxDay := DaysInMonth(Month, Year,0);
if Day+Day28Delta > MaxDay then
Inc(Julian, MaxDay-Day)
else
Inc(Julian, Day28Delta);
end;
Result := Julian;
end;
procedure DateDiff(Date1, Date2 : TStDate; var Days, Months, Years : Integer);
{-Return the difference in days,months,years between two valid julian dates}
var
Day1, Day2, Month1, Month2, Year1, Year2 : Integer;
begin
{we want Date2 > Date1}
if Date1 > Date2 then
ExchangeLongInts(Date1, Date2);
{convert dates to day,month,year}
StDateToDMY(Date1, Day1, Month1, Year1);
StDateToDMY(Date2, Day2, Month2, Year2);
{days first}
if (Day1 = DaysInMonth(Month1, Year1, 0)) then begin
Day1 := 0;
Inc(Month1); {OK if Month1 > 12}
end;
if (Day2 = DaysInMonth(Month2, Year2, 0)) then begin
Day2 := 0;
Inc(Month2); {OK if Month2 > 12}
end;
if (Day2 < Day1) then begin
Dec(Month2);
if Month2 = 0 then begin
Month2 := 12;
Dec(Year2);
end;
Days := Day2 + DaysInMonth(Month2, Year2, 0) - Day1; {!!.02}
end else
Days := Day2-Day1;
{now months and years}
if Month2 < Month1 then begin
Inc(Month2, 12);
Dec(Year2);
end;
Months := Month2-Month1;
Years := Year2-Year1;
end;
function BondDateDiff(Date1, Date2 : TStDate; DayBasis : TStBondDateType) : TStDate;
{-Return the difference in days between two valid Julian
dates using one a specific accrual method}
var
Day1,
Month1,
Year1,
Day2,
Month2,
Year2 : Integer;
IY : LongInt;
begin
{we want Date2 > Date1}
if Date1 > Date2 then
ExchangeLongInts(Date1, Date2);
if (DayBasis = bdtActual) then
Result := Date2-Date1
else
begin
StDateToDMY(Date1, Day1, Month1, Year1);
StDateToDMY(Date2, Day2, Month2, Year2);
if ((DayBasis = bdt30360PSA) and IsLastDayofFeb(Date1)) or (Day1 = 31) then
Day1 := 30;
if (DayBasis = bdt30E360) then
begin
if (Day2 = 31) then
Day2 := 30
end else
if (Day2 = 31) and (Day1 >= 30) then
Day2 := 30;
IY := 360 * (Year2 - Year1);
Result := IY + 30 * (Month2 - Month1) + (Day2 - Day1);
end;
end;
function DayOfWeek(Julian : TStDate) : TStDayType;
{-Return the day of the week for the date. Returns TStDayType(7) if Julian =
BadDate.}
var
B : Byte;
begin
if Julian = BadDate then begin
B := 7;
Result := TStDayType(B);
end else
Result := TStDayType( (Julian+Ord(FirstDayOfWeek)) mod 7 );
end;
function DayOfWeekDMY(Day, Month, Year, Epoch : Integer) : TStDayType;
{-Return the day of the week for the day, month, year}
begin
Result := DayOfWeek( DMYtoStDate(Day, Month, Year, Epoch) );
end;
procedure StTimeToHMS(T : TStTime; var Hours, Minutes, Seconds : Byte);
{-Convert a Time variable to Hours, Minutes, Seconds}
begin
if T = BadTime then begin
Hours := 0;
Minutes := 0;
Seconds := 0;
end
else begin
Hours := T div SecondsInHour;
Dec(T, LongInt(Hours)*SecondsInHour);
Minutes := T div SecondsInMinute;
Dec(T, LongInt(Minutes)*SecondsInMinute);
Seconds := T;
end;
end;
function HMStoStTime(Hours, Minutes, Seconds : Byte) : TStTime;
{-Convert Hours, Minutes, Seconds to a Time variable}
var
T : TStTime;
begin
Hours := Hours mod HoursInDay;
T := (LongInt(Hours)*SecondsInHour)+(LongInt(Minutes)*SecondsInMinute)+Seconds;
Result := T mod SecondsInDay;
end;
function ValidTime(Hours, Minutes, Seconds : Integer) : Boolean;
{-Return true if Hours:Minutes:Seconds is a valid time}
begin
if (Hours < 0) or (Hours > 23) or
(Minutes < 0) or (Minutes >= 60) or
(Seconds < 0) or (Seconds >= 60) then
Result := False
else
Result := True;
end;
function CurrentTime : TStTime;
{-Returns current time in seconds since midnight}
begin
Result := Trunc(SysUtils.Time * SecondsInDay);
end;
procedure TimeDiff(Time1, Time2 : TStTime; var Hours, Minutes, Seconds : Byte);
{-Return the difference in hours,minutes,seconds between two times}
begin
StTimeToHMS(Abs(Time1-Time2), Hours, Minutes, Seconds);
end;
function IncTime(T : TStTime; Hours, Minutes, Seconds : Byte) : TStTime;
{-Add the specified hours,minutes,seconds to T and return the result}
begin
Inc(T, HMStoStTime(Hours, Minutes, Seconds));
Result := T mod SecondsInDay;
end;
function DecTime(T : TStTime; Hours, Minutes, Seconds : Byte) : TStTime;
{-Subtract the specified hours,minutes,seconds from T and return the result}
begin
Hours := Hours mod HoursInDay;
Dec(T, HMStoStTime(Hours, Minutes, Seconds));
if T < 0 then
Result := T+SecondsInDay
else
Result := T;
end;
function RoundToNearestHour(T : TStTime; Truncate : Boolean) : TStTime;
{-Round T to the nearest hour, or Truncate minutes and seconds from T}
var
Hours, Minutes, Seconds : Byte;
begin
StTimeToHMS(T, Hours, Minutes, Seconds);
Seconds := 0;
if not Truncate then
if Minutes >= (MinutesInHour div 2) then
Inc(Hours);
Minutes := 0;
Result := HMStoStTime(Hours, Minutes, Seconds);
end;
function RoundToNearestMinute(const T : TStTime; Truncate : Boolean) : TStTime;
{-Round T to the nearest minute, or Truncate seconds from T}
var
Hours, Minutes, Seconds : Byte;
begin
StTimeToHMS(T, Hours, Minutes, Seconds);
if not Truncate then
if Seconds >= (SecondsInMinute div 2) then
Inc(Minutes);
Seconds := 0;
Result := HMStoStTime(Hours, Minutes, Seconds);
end;
procedure DateTimeDiff(const DT1 : TStDateTimeRec; var DT2 : TStDateTimeRec; {!!.02}
var Days : LongInt; var Secs : LongInt);
{-Return the difference in days and seconds between two points in time}
var
tDT1, tDT2 : TStDateTimeRec;
begin
tDT1 := DT1;
tDT2 := DT2;
{swap if tDT1 later than tDT2}
if (tDT1.D > tDT2.D) or ((tDT1.D = tDT2.D) and (tDT1.T > tDT2.T)) then
ExchangeStructs(tDT1, tDT2,sizeof(TStDateTimeRec));
{the difference in days is easy}
Days := tDT2.D-tDT1.D;
{difference in seconds}
if tDT2.T < tDT1.T then begin
{subtract one day, add 24 hours}
Dec(Days);
Inc(tDT2.T, SecondsInDay);
end;
Secs := tDT2.T-tDT1.T;
end;
function DateTimeToStDate(DT : TDateTime) : TStDate;
{-Convert Delphi TDateTime to TStDate}
var
Day, Month, Year : Word;
begin
DecodeDate(DT, Year, Month, Day);
Result := DMYToStDate(Day, Month, Year, 0);
end;
function DateTimeToStTime(DT : TDateTime) : TStTime;
{-Convert Delphi TDateTime to TStTime}
var
Hour, Min, Sec, MSec : Word;
begin
DecodeTime(DT, Hour, Min, Sec, MSec);
Result := HMSToStTime(Hour, Min, Sec);
end;
function StDateToDateTime(D : TStDate) : TDateTime;
{-Convert TStDate to TDateTime}
var
Day, Month, Year : Integer;
begin
Result := 0;
if D <> BadDate then begin
StDateToDMY(D, Day, Month, Year);
Result := EncodeDate(Year, Month, Day);
end;
end;
function StTimeToDateTime(T : TStTime) : TDateTime;
{-Convert TStTime to TDateTime}
var
Hour, Min, Sec : Byte;
begin
Result := 0;
if T <> BadTime then begin
StTimeToHMS(T, Hour, Min, Sec);
Result := EncodeTime(Hour, Min, Sec, 0);
end;
end;
procedure IncDateTime(const DT1 : TStDateTimeRec; var DT2 : TStDateTimeRec; {!!.02}
Days : Integer; Secs : LongInt);
{-Increment (or decrement) DT1 by the specified number of days and seconds
and put the result in DT2}
begin
DT2 := DT1;
{date first}
Inc(DT2.D, LongInt(Days));
if Secs < 0 then begin
{change the sign}
Secs := -Secs;
{adjust the date}
Dec(DT2.D, Secs div SecondsInDay);
Secs := Secs mod SecondsInDay;
if Secs > DT2.T then begin
{subtract a day from DT2.D and add a day's worth of seconds to DT2.T}
Dec(DT2.D);
Inc(DT2.T, SecondsInDay);
end;
{now subtract the seconds}
Dec(DT2.T, Secs);
end
else begin
{increment the seconds}
Inc(DT2.T, Secs);
{adjust date if necessary}
Inc(DT2.D, DT2.T div SecondsInDay);
{force time to 0..SecondsInDay-1 range}
DT2.T := DT2.T mod SecondsInDay;
end;
end;
function Convert2ByteDate(TwoByteDate : Word) : TStDate;
begin
Result := LongInt(TwoByteDate) + Date1900;
end;
function Convert4ByteDate(FourByteDate : TStDate) : Word;
begin
Result := Word(FourByteDate - Date1900);
end;
procedure SetDefaultYear;
{-Initialize DefaultYear and DefaultMonth}
var
Month, Day, Year : Word;
T : TDateTime;
begin
T := Now;
DecodeDate(T, Year, Month, Day);
DefaultYear := Year;
DefaultMonth := Month;
end;
initialization
{initialize DefaultYear and DefaultMonth}
SetDefaultYear;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -