📄 iddatetimestamp.pas
字号:
AddYears(IdYearsInCentury);
ANumber := ANumber - Cardinal(IdDaysInCentury);
end;
end;
end;
if ANumber >= IdDaysInShortLeapYearCycle then begin
i := ANumber div IdDaysInShortLeapYearCycle;
AddYears(i * IdYearsInShortLeapYearCycle);
ANumber := ANumber - Cardinal(i * IdDaysInShortLeapYearCycle);
end;
i := GetDaysInYear;
while Integer(ANumber) > i do begin
AddYears(1);
Dec(ANumber, i);
i := GetDaysInYear;
end;
if FDay + Integer(ANumber) > i then begin
AddYears(1);
Dec(ANumber, i - FDay);
FDay := ANumber;
end else begin
Inc(FDay, ANumber);
end;
end;
procedure TIdDateTimeStamp.AddHours;
var
i : Cardinal;
begin
i := ANumber div IdHoursInDay;
AddDays(i);
Dec(ANumber, i * IdHoursInDay);
AddSeconds(ANumber * IdSecondsInHour);
end;
procedure TIdDateTimeStamp.AddMilliseconds;
var
i : Cardinal;
begin
i := ANumber div IdMillisecondsInDay;
if i > 0 then begin
AddDays(i);
Dec(ANumber, i * IdMillisecondsInDay);
end;
i := ANumber div IdMillisecondsInSecond;
if i > 0 then begin
AddSeconds(i);
Dec(ANumber, i * IdMillisecondsInSecond);
end;
Inc(FMillisecond, ANumber);
while FMillisecond > IdMillisecondsInSecond do begin
// Should only happen once...
AddSeconds(1);
Dec(FMillisecond, IdMillisecondsInSecond);
end;
end;
procedure TIdDateTimeStamp.AddMinutes;
begin
// Convert down to seconds
while ANumber > MaxMinutesAdd do begin
AddSeconds(MaxMinutesAdd);
Dec(ANumber, MaxMinutesAdd);
end;
AddSeconds(ANumber * IdSecondsInMinute);
end;
procedure TIdDateTimeStamp.AddMonths;
var
i : Integer;
begin
i := ANumber div IdMonthsInYear;
AddYears(i);
Dec(ANumber, i * IdMonthsInYear);
while ANumber > 0 do begin
i := MonthOfYear;
if i = 12 then begin
i := 1;
end;
if (i = 2) and (IsLeapYear) then begin
AddDays(IdDaysInMonth[i] + 1);
end else begin
AddDays(IdDaysInMonth[i]);
end;
Dec(ANumber);
end;
end;
procedure TIdDateTimeStamp.AddSeconds;
var
i : Cardinal;
begin
i := ANumber Div IdSecondsInDay;
if i > 0 then begin
AddDays(i);
ANumber := ANumber - (i * IdSecondsInDay);
end;
Inc(FSecond, ANumber);
while FSecond > IdSecondsInDay do begin
// Should only ever happen once...
AddDays(1);
Dec(FSecond, IdSecondsInDay);
end;
end;
procedure TIdDateTimeStamp.AddTDateTime;
begin
AddTTimeStamp(DateTimeToTimeStamp(ADateTime));
end;
procedure TIdDateTimeStamp.AddTIdDateTimeStamp;
begin
{ TODO : Check for accuracy }
AddYears(AIdDateTime.Year);
AddDays(AIdDateTime.Day);
AddSeconds(AIdDateTime.Second);
AddMilliseconds(AIdDateTime.Millisecond);
end;
procedure TIdDateTimeStamp.AddTTimeStamp;
var
TId : TIdDateTimeStamp;
begin
TId := TIdDateTimeStamp.Create(Self);
try
TId.SetFromTTimeStamp(ATimeStamp);
Self.AddTIdDateTimeStamp(TId);
finally
TId.Free;
end;
end;
procedure TIdDateTimeStamp.AddWeeks;
begin
// Cannot add years as there are not exactly 52 weeks in the year and there
// is no exact match between weeks and the 400 year leap cycle
// Convert down to days...
while ANumber > MaxWeekAdd do begin
AddDays(MaxWeekAdd);
Dec(ANumber, MaxWeekAdd);
end;
AddDays(ANumber * IdDaysInWeek);
end;
procedure TIdDateTimeStamp.AddYears;
begin
{TODO: Capture overflow because adding Cardinal to Integer }
if (FYear <= -1) and (Integer(ANumber) >= -FYear) then begin
Inc(ANumber);
end;
Inc(FYear, ANumber);
CheckLeapYear;
end;
procedure TIdDateTimeStamp.CheckLeapYear;
begin
// Nested if done to prevent unnecessary calcs on slower machines
if FYear mod 4 = 0 then begin
if FYear mod 100 = 0 then begin
if FYear mod 400 = 0 then begin
FIsLeapYear := True;
end else begin
FIsLeapYear := False;
end;
end else begin
FIsLeapYear := True;
end;
end else begin
FIsLeapYear := False;
end;
{TODO : If (FIsLeapYear = false) and (FDay = IdDaysInLeapYear) then begin
and, do what?
}
end;
function TIdDateTimeStamp.GetAsISO8601Calendar;
begin
result := IntToStr(FYear) + '-'; {Do not Localize}
result := result + IntToStr(MonthOfYear) + '-'; {Do not Localize}
result := result + IntToStr(DayOfMonth) + 'T'; {Do not Localize}
result := result + AsTimeOfDay;
end;
function TIdDateTimeStamp.GetAsISO8601Ordinal : String;
begin
result := IntToStr(FYear) + '-'; {Do not Localize}
result := result + IntToStr(FDay) + 'T'; {Do not Localize}
result := result + AsTimeOfDay;
end;
function TIdDateTimeStamp.GetAsISO8601Week : String;
begin
result := IntToStr(FYear) + '-W'; {Do not Localize}
result := result + IntToStr(WeekOfYear) + '-'; {Do not Localize}
result := result + IntToStr(DayOfWeek) + 'T'; {Do not Localize}
result := result + AsTimeOfDay;
end;
function TIdDateTimeStamp.GetAsRFC822;
begin
result := IdDayShortNames[DayOfWeek] + ', '; {Do not Localize}
result := result + IntToStr(DayOfMonth) + ' '; {Do not Localize}
result := result + IdMonthShortNames[MonthOfYear] + ' '; {Do not Localize}
result := result + IntToStr(Year) + ' '; {Do not Localize}
result := result + AsTimeOfDay + ' '; {Do not Localize}
result := result + TimeZoneAsString;
end;
function TIdDateTimeStamp.GetAsTDateTime;
begin
result := TimeStampToDateTime(GetAsTTimeStamp);
end;
function TIdDateTimeStamp.GetAsTTimeStamp;
var
NonLeap, Leap : Integer;
begin
// Every four years is a leap year
Leap := FYear div 4;
// Every hundred is not
NonLeap := FYear div 100;
Leap := Leap - NonLeap;
// Every four-hundred is.
NonLeap := FYear div 400;
Leap := Leap + NonLeap;
// Don't count the first year as whole {Do not Localize}
NonLeap := (FYear - 1) - Leap;
result.Date := (Leap * IdDaysInLeapYear) + (NonLeap * IdDaysInYear) +
Integer(FDay); // Not accurate for all dates (i.e., not Julian calender,
// < ~1500), but good enough for Internet use
if (FYear mod 4 = 0) then
begin
if (FYear mod 100) = 0 then
begin
if (FYear mod 400) = 0 then
begin
result.Date := result.Date - 1;
end;
end else
begin
result.Date := result.Date - 1;
end;
end;
result.Time := (FSecond * IdMillisecondsInSecond) + FMillisecond;
end;
function TIdDateTimeStamp.GetAsTimeOfDay;
var
i : Integer;
begin
i := HourOf24Day;
if i < 10 then begin
result := result + '0' + IntToStr(i) + ':'; {Do not Localize}
end else begin
result := result + IntToStr(i) + ':'; {Do not Localize}
end;
i := MinuteOfHour;
if i < 10 then begin
result := result + '0' + IntToStr(i) + ':'; {Do not Localize}
end else begin
result := result + IntToStr(i) + ':'; {Do not Localize}
end;
i := SecondOfMinute;
if i < 10 then begin
result := result + '0' + IntToStr(i); {Do not Localize}
end else begin
result := result + IntToStr(i); {Do not Localize}
end;
end;
function TIdDateTimeStamp.GetBeatOfDay;
var
i64 : Int64;
DTS : TIdDateTimeStamp;
begin
// Check
if FTimeZone <> TZ_MET then
begin
// Rather than messing about with this instance, create
// a new one.
DTS := TIdDateTimeStamp.Create(Self);
try
DTS.SetYear(FYear);
DTS.SetDay(FDay);
DTS.SetSecond(FSecond);
DTS.SetMillisecond(FMillisecond);
DTS.SetTimeZone(TZ_MET);
DTS.AddMinutes( (TZ_MET * IdMinutesInHour) - FTimeZone);
result := DTS.GetBeatOfDay;
finally
DTS.Free;
end;
end else
begin
i64 := (FSecond * IdMillisecondsInSecond) + FMillisecond;
i64 := i64 * IdBeatsInDay;
i64 := i64 div IdMillisecondsInDay;
result := Integer(i64);
end;
end;
function TIdDateTimeStamp.GetDaysInYear;
begin
if IsLeapYear then begin
result := IdDaysInLeapYear;
end else begin
result := IdDaysInYear;
end;
end;
function TIdDateTimeStamp.GetDayOfMonth;
var
count, mnth, days : Integer;
begin
mnth := MonthOfYear;
if IsLeapYear and (mnth > 2) then begin
days := 1;
end else begin
days := 0;
end;
for count := 1 to mnth - 1 do begin
Inc(days, IdDaysInMonth[count]);
end;
days := Day - days;
if days < 0 then begin
result := 0;
end else begin
result := days;
end;
end;
function TIdDateTimeStamp.GetDayOfWeek;
var
a, y, m, d, mnth : Integer;
begin
// Thanks to the "FAQ About Calendars" by Claus T鴑dering for this algorithm
// http://www.tondering.dk/claus/calendar.html
mnth := MonthOfYear;
a := (14 - mnth) div 12;
y := Year - a;
m := mnth + (12 * a) - 2;
d := DayOfMonth + y + (y div 4) - (y div 100) + (y div 400) + ((31 * m) div 12);
d := d mod 7;
result := d + 1;
end;
function TIdDateTimeStamp.GetDayOfWeekName;
begin
result := IdDayNames[GetDayOfWeek];
end;
function TIdDateTimeStamp.GetDayOfWeekShortName;
begin
result := IdDayShortNames[GetDayOfWeek];
end;
function TIdDateTimeStamp.GetHourOf12Day;
var
hr : Integer;
begin
hr := GetHourOf24Day;
if hr > IdHoursInHalfDay then begin
Dec(hr, IdHoursInHalfDay);
end;
result := hr;
end;
function TIdDateTimeStamp.GetHourOf24Day;
begin
result := (Second) div IdSecondsInHour;
end;
function TIdDateTimeStamp.GetIsMorning;
begin
if Second <= (IdSecondsInHalFDay + 1) then begin
result := True;
end else begin
result := False;
end;
end;
function TIdDateTimeStamp.GetMinuteOfDay;
begin
result := Second div IdSecondsInMinute;
end;
function TIdDateTimeStamp.GetMinuteOfHour;
begin
result := GetMinuteOfDay - (IdMinutesInHour * (GetHourOf24Day));
end;
function TIdDateTimeStamp.GetMonthOfYear;
var
AddOne, Count : Byte;
Today : Integer;
begin
if IsLeapYear then begin
AddOne := 1;
end else begin
AddOne := 0;
end;
Today := Day;
Count := 1;
result := 0;
while Count <> 13 do begin
if Count = 2 then begin
if Today > IdDaysInMonth[Count] + AddOne then begin
Dec(Today, IdDaysInMonth[Count] + AddOne);
end else begin
result := Count;
break;
end;
end else begin
if Today > IdDaysInMonth[Count] then begin
Dec(Today, IdDaysInMonth[Count]);
end else begin
result := Count;
break;
end;
end;
Inc(Count);
end;
end;
function TIdDateTimeStamp.GetMonthName;
begin
result := IdMonthNames[MonthOfYear];
end;
function TIdDateTimeStamp.GetMonthShortName;
begin
result := IdMonthShortNames[MonthOfYear];
end;
function TIdDateTimeStamp.GetSecondsInYear;
begin
if IsLeapYear then begin
result := IdSecondsInLeapYear;
end else begin
result := IdSecondsInYear;
end;
end;
function TIdDateTimeStamp.GetSecondOfMinute;
begin
result := FSecond - (GetMinuteOfDay * IdSecondsInMinute);
end;
function TIdDateTimeStamp.GetTimeZoneAsString: String;
var
i : Integer;
begin
i := GetTimeZoneHour;
if i < 0 then
begin
if i < -9 then
begin
result := IntToStr(i);
end else
begin
result := '-0' + IntToStr(Abs(i)); {Do not Localize}
end;
end else
begin
if i <= 9 then
begin
result := '+0' + IntToStr(i); {Do not Localize}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -