initial commit
[rofl0r-KOL.git] / units / indy / IdDateTimeStamp.pas
blob48000dfa1c5238e92c4eabea692f38832ffd4438
1 // 29-nov-2002
2 unit IdDateTimeStamp;
4 interface
6 uses KOL { ,
7 Classes } ,
8 IdBaseComponent,
9 SysConst, SysUtils;
11 const
13 IdMilliSecondsInSecond = 1000;
14 IdSecondsInMinute = 60;
15 IdMinutesInHour = 60;
16 IdHoursInDay = 24;
18 IdDaysInWeek = 7;
19 IdDaysInYear = 365;
20 IdDaysInLeapYear = 366;
21 IdYearsInShortLeapYearCycle = 4;
22 IdDaysInShortLeapYearCycle = IdDaysInLeapYear + (IdDaysInYear * 3);
23 IdDaysInShortNonLeapYearCycle = IdDaysInYear * IdYearsInShortLeapYearCycle;
24 IdDaysInFourYears = IdDaysInShortLeapYearCycle;
25 IdYearsInCentury = 100;
26 IdDaysInCentury = (25 * IdDaysInFourYears) - 1;
27 IdDaysInLeapCentury = IdDaysInCentury + 1;
28 IdYearsInLeapYearCycle = 400;
29 IdDaysInLeapYearCycle = IdDaysInCentury * 4 + 1;
31 IdMonthsInYear = 12;
33 IdBeatsInDay = 1000;
35 IdHoursInHalfDay = IdHoursInDay div 2;
37 IdSecondsInHour = IdSecondsInMinute * IdMinutesInHour;
38 IdSecondsInDay = IdSecondsInHour * IdHoursInDay;
39 IdSecondsInHalfDay = IdSecondsInHour * IdHoursInHalfDay;
40 IdSecondsInWeek = IdDaysInWeek * IdSecondsInDay;
41 IdSecondsInYear = IdSecondsInDay * IdDaysInYear;
42 IdSecondsInLeapYear = IdSecondsInDay * IdDaysInLeapYear;
44 IdMillisecondsInMinute = IdSecondsInMinute * IdMillisecondsInSecond;
45 IdMillisecondsInHour = IdSecondsInHour * IdMillisecondsInSecond;
46 IdMillisecondsInDay = IdSecondsInDay * IdMillisecondsInSecond;
47 IdMillisecondsInWeek = IdSecondsInWeek * IdMillisecondsInSecond;
49 IdDaysInMonth: array[1..IdMonthsInYear] of byte =
51 31, 28, 31, 30, 31, 30,
52 31, 31, 30, 31, 30, 31
55 IdMonthNames: array[0..IdMonthsInYear] of string =
56 ('',
57 SLongMonthNameJan, SLongMonthNameFeb, SLongMonthNameMar,
58 SLongMonthNameApr, SLongMonthNameMay, SLongMonthNameJun,
59 SLongMonthNameJul, SLongMonthNameAug, SLongMonthNameSep,
60 SLongMonthNameOct, SLongMonthNameNov, SLongMonthNameDec);
62 IdMonthShortNames: array[0..IdMonthsInYear] of string =
63 ('',
64 SShortMonthNameJan, SShortMonthNameFeb, SShortMonthNameMar,
65 SShortMonthNameApr, SShortMonthNameMay, SShortMonthNameJun,
66 SShortMonthNameJul, SShortMonthNameAug, SShortMonthNameSep,
67 SShortMonthNameOct, SShortMonthNameNov, SShortMonthNameDec);
69 IdDayNames: array[0..IdDaysInWeek] of string =
70 ('', SLongDayNameSun, SLongDayNameMon, SLongDayNameTue,
71 SLongDayNameWed, SLongDayNameThu, SLongDayNameFri,
72 SLongDayNameSat);
74 IdDayShortNames: array[0..IdDaysInWeek] of string =
75 ('', SShortDayNameSun, SShortDayNameMon, SShortDayNameTue,
76 SShortDayNameWed, SShortDayNameThu, SShortDayNameFri,
77 SShortDayNameSat);
79 // Area Time Zones
80 TZ_NZDT = 13; // New Zealand Daylight Time
81 TZ_IDLE = 12; // International Date Line East
82 TZ_NZST = TZ_IDLE; // New Zealand Standard Time
83 TZ_NZT = TZ_IDLE; // New Zealand Time
84 TZ_EADT = 11; // Eastern Australian Daylight Time
85 TZ_GST = 10; // Guam Standard Time / Russia Zone 9
86 TZ_JST = 9; // Japan Standard Time / Russia Zone 8
87 TZ_CCT = 8; // China Coast Time / Russia Zone 7
88 TZ_WADT = TZ_CCT; // West Australian Daylight Time
89 TZ_WAST = 7; // West Australian Standard Time / Russia Zone 6
90 TZ_ZP6 = 6; // Chesapeake Bay / Russia Zone 5
91 TZ_ZP5 = 5; // Chesapeake Bay / Russia Zone 4
92 TZ_ZP4 = 4; // Russia Zone 3
93 TZ_BT = 3; // Baghdad Time / Russia Zone 2
94 TZ_EET = 2; // Eastern European Time / Russia Zone 1
95 TZ_MEST = TZ_EET; // Middle European Summer Time
96 TZ_MESZ = TZ_EET; // Middle European Summer Zone
97 TZ_SST = TZ_EET; // Swedish Summer Time
98 TZ_FST = TZ_EET; // French Summer Time
99 TZ_CET = 1; // Central European Time
100 TZ_FWT = TZ_CET; // French Winter Time
101 TZ_MET = TZ_CET; // Middle European Time
102 TZ_MEWT = TZ_CET; // Middle European Winter Time
103 TZ_SWT = TZ_CET; // Swedish Winter Time
104 TZ_GMT = 0; // Greenwich Meanttime
105 TZ_UT = TZ_GMT; // Universla Time
106 TZ_UTC = TZ_GMT; // Universal Time Co-ordinated
107 TZ_WET = TZ_GMT; // Western European Time
108 TZ_WAT = -1; // West Africa Time
109 TZ_BST = TZ_WAT; // British Summer Time
110 TZ_AT = -2; // Azores Time
111 TZ_ADT = -3; // Atlantic Daylight Time
112 TZ_AST = -4; // Atlantic Standard Time
113 TZ_EDT = TZ_AST; // Eastern Daylight Time
114 TZ_EST = -5; // Eastern Standard Time
115 TZ_CDT = TZ_EST; // Central Daylight Time
116 TZ_CST = -6; // Central Standard Time
117 TZ_MDT = TZ_CST; // Mountain Daylight Time
118 TZ_MST = -7; // Mountain Standard Time
119 TZ_PDT = TZ_MST; // Pacific Daylight Time
120 TZ_PST = -8; // Pacific Standard Time
121 TZ_YDT = TZ_PST; // Yukon Daylight Time
122 TZ_YST = -9; // Yukon Standard Time
123 TZ_HDT = TZ_YST; // Hawaii Daylight Time
124 TZ_AHST = -10; // Alaska-Hawaii Standard Time
125 TZ_CAT = TZ_AHST; // Central Alaska Time
126 TZ_HST = TZ_AHST; // Hawaii Standard Time
127 TZ_EAST = TZ_AHST; // East Australian Standard Time
128 TZ_NT = -11; // -None-
129 TZ_IDLW = -12; // International Date Line West
131 // Military Time Zones
132 TZM_A = TZ_WAT;
133 TZM_Alpha = TZM_A;
134 TZM_B = TZ_AT;
135 TZM_Bravo = TZM_B;
136 TZM_C = TZ_ADT;
137 TZM_Charlie = TZM_C;
138 TZM_D = TZ_AST;
139 TZM_Delta = TZM_D;
140 TZM_E = TZ_EST;
141 TZM_Echo = TZM_E;
142 TZM_F = TZ_CST;
143 TZM_Foxtrot = TZM_F;
144 TZM_G = TZ_MST;
145 TZM_Golf = TZM_G;
146 TZM_H = TZ_PST;
147 TZM_Hotel = TZM_H;
148 TZM_J = TZ_YST;
149 TZM_Juliet = TZM_J;
150 TZM_K = TZ_AHST;
151 TZM_Kilo = TZM_K;
152 TZM_L = TZ_NT;
153 TZM_Lima = TZM_L;
154 TZM_M = TZ_IDLW;
155 TZM_Mike = TZM_M;
156 TZM_N = TZ_CET;
157 TZM_November = TZM_N;
158 TZM_O = TZ_EET;
159 TZM_Oscar = TZM_O;
160 TZM_P = TZ_BT;
161 TZM_Papa = TZM_P;
162 TZM_Q = TZ_ZP4;
163 TZM_Quebec = TZM_Q;
164 TZM_R = TZ_ZP5;
165 TZM_Romeo = TZM_R;
166 TZM_S = TZ_ZP6;
167 TZM_Sierra = TZM_S;
168 TZM_T = TZ_WAST;
169 TZM_Tango = TZM_T;
170 TZM_U = TZ_CCT;
171 TZM_Uniform = TZM_U;
172 TZM_V = TZ_JST;
173 TZM_Victor = TZM_V;
174 TZM_W = TZ_GST;
175 TZM_Whiskey = TZM_W;
176 TZM_X = TZ_NT;
177 TZM_XRay = TZM_X;
178 TZM_Y = TZ_IDLE;
179 TZM_Yankee = TZM_Y;
180 TZM_Z = TZ_GMT;
181 TZM_Zulu = TZM_Z;
183 type
185 TDays = (TDaySun, TDayMon, TDayTue, TDayWed, TDayThu, TDayFri, TDaySat);
186 TMonths = (TMthJan, TMthFeb, TMthMar, TMthApr, TMthMay, TMthJun,
187 TMthJul, TMthAug, TMthSep, TMthOct, TMthNov, TMthDec);
189 TIdDateTimeStamp = object(TIdBaseComponent)
190 protected
191 FDay: Integer;
192 FIsLeapYear: Boolean;
193 FMillisecond: Integer;
194 FRequestedTimeZone: Integer;
195 FSecond: Integer;
196 FTimeZone: Integer;
197 FYear: Integer;
199 procedure CheckLeapYear;
200 public
201 { constructor Create(AOwner: TComponent); override;
202 } destructor Destroy;
204 virtual; procedure AddDays(ANumber: Cardinal);
205 procedure AddHours(ANumber: Cardinal);
206 procedure AddMilliseconds(ANumber: Cardinal);
207 procedure AddMinutes(ANumber: Cardinal);
208 procedure AddMonths(ANumber: Cardinal);
209 procedure AddSeconds(ANumber: Cardinal);
210 procedure AddTDateTime(ADateTime: TDateTime);
211 procedure AddTIdDateTimeStamp(AIdDateTime: TIdDateTimeStamp);
212 procedure AddTTimeStamp(ATimeStamp: TTimeStamp);
213 procedure AddWeeks(ANumber: Cardinal);
214 procedure AddYears(ANumber: Cardinal);
216 function GetAsISO8601Calendar: string;
217 function GetAsISO8601Ordinal: string;
218 function GetAsISO8601Week: string;
219 function GetAsRFC882: string;
221 function GetAsTDateTime: TDateTime;
222 function GetAsTTimeStamp: TTimeStamp;
223 function GetAsTimeOFDay: string; // HH:MM:SS
225 function GetBeatOFDay: Integer;
226 function GetDaysInYear: Integer;
227 function GetDayOfMonth: Integer;
228 function GetDayOfWeek: Integer;
229 function GetDayOfWeekName: string;
230 function GetDayOfWeekShortName: string;
231 function GetHourOf12Day: Integer;
232 function GetHourOf24Day: Integer;
233 function GetIsMorning: Boolean;
234 function GetMinuteOFDay: Integer;
235 function GetMinuteOfHour: Integer;
236 function GetMonthOFYear: Integer;
237 function GetMonthName: string;
238 function GetMonthShortName: string;
239 function GetSecondsInYear: Integer;
240 function GetSecondOfMinute: Integer;
241 function GetWeekOFYear: Integer;
243 procedure SetFromTDateTime(ADateTime: TDateTime);
244 procedure SetFromTTimeStamp(ATimeStamp: TTimeStamp);
246 procedure SetDay(ANumber: Integer);
247 procedure SetMillisecond(ANumber: Integer);
248 procedure SetSecond(ANumber: Integer);
249 procedure SetYear(ANumber: Integer);
251 procedure SubtractDays(ANumber: Cardinal);
252 procedure SubtractHours(ANumber: Cardinal);
253 procedure SubtractMilliseconds(ANumber: Cardinal);
254 procedure SubtractMinutes(ANumber: Cardinal);
255 procedure SubtractMonths(ANumber: Cardinal);
256 procedure SubtractSeconds(ANumber: Cardinal);
257 procedure SubtractTDateTime(ADateTime: TDateTime);
258 procedure SubtractTIdDateTimeStamp(AIdDateTime: TIdDateTimeStamp);
259 procedure SubtractTTimeStamp(ATimeStamp: TTimeStamp);
260 procedure SubtractWeeks(ANumber: Cardinal);
261 procedure SubtractYears(ANumber: Cardinal);
263 property AsISO8601Calendar: string read GetAsISO8601Calendar;
264 property AsISO8601Ordinal: string read GetAsISO8601Ordinal;
265 property AsISO8601Week: string read GetAsISO8601Week;
266 property AsRFC822: string read GetAsRFC882;
267 property AsTDateTime: TDateTime read GetAsTDateTime;
268 property AsTTimeStamp: TTimeStamp read GetAsTTimeStamp;
269 property AsTimeOFDay: string read GetAsTimeOFDay;
270 property BeatOFDay: Integer read GetBeatOFDay;
271 property Day: Integer read FDay write FDay;
272 property DaysInYear: Integer read GetDaysInYear;
273 property DayOfMonth: Integer read GetDayOfMonth;
274 property DayOfWeek: Integer read GetDayOfWeek;
275 property DayOfWeekName: string read GetDayOfWeekName;
276 property DayOfWeekShortName: string read GetDayOfWeekShortName;
277 property HourOf12Day: Integer read GetHourOf12Day;
278 property HourOf24Day: Integer read GetHourOf24Day;
279 property IsLeapYear: Boolean read FIsLeapYear;
280 property IsMorning: Boolean read GetIsMorning;
281 property Second: Integer read FSecond write FSecond;
282 property SecondsInYear: Integer read GetSecondsInYear;
283 property SecondOfMinute: Integer read GetSecondOfMinute;
284 property MinuteOFDay: Integer read GetMinuteOFDay;
285 property MinuteOfHour: Integer read GetMinuteOfHour;
286 property MonthOFYear: Integer read GetMonthOFYear;
287 property MonthName: string read GetMonthName;
288 property MonthShortName: string read GetMonthShortName;
289 property Millisecond: Integer read FMillisecond write FMillisecond;
290 property TimeZone: Integer read FTimeZone write FTimeZone;
291 property Year: Integer read FYear write SetYear;
292 property WeekOFYear: Integer read GetWeekOFYear;
293 end;
294 PIdDateTimeStamp=^TIdDateTimeStamp;
295 function NewIdDateTimeStamp(AOwner: PControl):PIdDateTimeStamp;
298 implementation
300 const
301 MaxWeekAdd: Cardinal = $FFFFFFFF div IdDaysInWeek;
302 MaxMinutesAdd: Cardinal = $FFFFFFFF div IdSecondsInMinute;
304 //constructor TIdDateTimeStamp.Create;
305 function NewIdDateTimeStamp(AOwner: PControl):PIdDateTimeStamp;
306 begin
307 New( Result, Create );
308 with Result^ do
309 begin
310 // inherited Create(AOwner);
311 FYear := 1;
312 FDay := 1;
313 FSecond := 1;
314 FMillisecond := 1;
315 FTimeZone := 0;
316 FRequestedTimeZone := 0;
317 end;
318 end;
320 destructor TIdDateTimeStamp.Destroy;
321 begin
322 inherited;
323 end;
325 procedure TIdDateTimeStamp.AddDays;
327 i: Integer;
328 begin
329 if (ANumber > Cardinal(DaysInYear - FDay)) and (not (FDay = 1)) then
330 begin
331 ANumber := ANumber - Cardinal(DaysInYear - FDay);
332 FDay := 1;
333 AddYears(1);
335 else
336 begin
337 FDay := FDay + Integer(ANumber);
338 Exit;
339 end;
341 if ANumber >= IdDaysInLeapYearCycle then
342 begin
343 i := ANumber div IdDaysInLeapYearCycle;
344 AddYears(i * IdYearsInLeapYearCycle);
345 ANumber := ANumber - Cardinal(i * IdDaysInLeapYearCycle);
346 end;
348 if ANumber >= IdDaysInLeapCentury then
349 begin
350 while ANumber >= IDDaysInLeapCentury do
351 begin
352 i := FYear div 100;
354 if i mod 4 = 0 then
355 begin
356 AddYears(IdYearsInCentury);
357 ANumber := ANumber - Cardinal(IdDaysInLeapCentury);
359 else
360 begin
361 AddYears(IdYearsInCentury);
362 ANumber := ANumber - Cardinal(IdDaysInCentury);
363 end;
364 end;
365 end;
367 if ANumber >= IdDaysInShortLeapYearCycle then
368 begin
369 i := ANumber div IdDaysInShortLeapYearCycle;
370 AddYears(i * IdYearsInShortLeapYearCycle);
371 ANumber := ANumber - Cardinal(i * IdDaysInShortLeapYearCycle);
372 end;
374 i := GetDaysInYear;
375 while Integer(ANumber) > i do
376 begin
377 AddYears(1);
378 Dec(ANumber, i);
379 i := GetDaysInYear;
380 end;
382 if FDay + Integer(ANumber) > i then
383 begin
384 AddYears(1);
385 Dec(ANumber, i - FDay);
386 FDay := ANumber;
388 else
389 begin
390 Inc(FDay, ANumber);
391 end;
392 end;
394 procedure TIdDateTimeStamp.AddHours;
396 i: Cardinal;
397 begin
398 i := ANumber div IdHoursInDay;
399 AddDays(i);
400 Dec(ANumber, i * IdHoursInDay);
401 AddSeconds(ANumber * IdSecondsInHour);
402 end;
404 procedure TIdDateTimeStamp.AddMilliseconds;
406 i: Cardinal;
407 begin
408 i := ANumber div IdMillisecondsInDay;
409 if i > 0 then
410 begin
411 AddDays(i);
412 Dec(ANumber, i * IdMillisecondsInDay);
413 end;
415 i := ANumber div IdMillisecondsInSecond;
416 if i > 0 then
417 begin
418 AddSeconds(i);
419 Dec(ANumber, i * IdMillisecondsInSecond);
420 end;
422 Inc(FMillisecond, ANumber);
423 while FMillisecond > IdMillisecondsInSecond do
424 begin
425 AddSeconds(1);
426 Dec(FMillisecond, IdMillisecondsInSecond);
427 end;
428 end;
430 procedure TIdDateTimeStamp.AddMinutes;
431 begin
432 while ANumber > MaxMinutesAdd do
433 begin
434 AddSeconds(MaxMinutesAdd);
435 Dec(ANumber, MaxMinutesAdd);
436 end;
438 AddSeconds(ANumber * IdSecondsInMinute);
439 end;
441 procedure TIdDateTimeStamp.AddMonths;
443 i: Integer;
444 begin
445 i := ANumber div IdMonthsInYear;
446 AddYears(i);
447 Dec(ANumber, i * IdMonthsInYear);
449 while ANumber > 0 do
450 begin
451 i := MonthOFYear;
452 if i = 12 then
453 begin
454 i := 1;
455 end;
456 if (i = 2) and (IsLeapYear) then
457 begin
458 AddDays(IdDaysInMonth[i] + 1);
460 else
461 begin
462 AddDays(IdDaysInMonth[i]);
463 end;
465 Dec(ANumber);
466 end;
467 end;
469 procedure TIdDateTimeStamp.AddSeconds;
471 i: Cardinal;
472 begin
473 i := ANumber div IdSecondsInDay;
474 if i > 0 then
475 begin
476 AddDays(i);
477 ANumber := ANumber - (i * IdSecondsInDay);
478 end;
480 Inc(FSecond, ANumber);
481 while FSecond > IdSecondsInDay do
482 begin
483 AddDays(1);
484 Dec(FSecond, IdSecondsInDay);
485 end;
486 end;
488 procedure TIdDateTimeStamp.AddTDateTime;
489 begin
490 AddTTimeStamp(DateTimeToTimeStamp(ADateTime));
491 end;
493 procedure TIdDateTimeStamp.AddTIdDateTimeStamp;
494 begin
495 AddYears(AIdDateTime.Year);
496 AddDays(AIdDateTime.Day);
497 AddSeconds(AIdDateTime.Second);
498 AddMilliseconds(AIdDateTime.Millisecond);
499 end;
501 procedure TIdDateTimeStamp.AddTTimeStamp;
503 TId: TIdDateTimeStamp;
504 begin
505 { TId := TIdDateTimeStamp.Create(Self);
507 TId.SetFromTTimeStamp(ATimeStamp);
508 Self.AddTIdDateTimeStamp(TId);
509 finally
510 TId.Free;
511 end;}
512 end;
514 procedure TIdDateTimeStamp.AddWeeks;
515 begin
516 while ANumber > MaxWeekAdd do
517 begin
518 AddDays(MaxWeekAdd);
519 Dec(ANumber, MaxWeekAdd);
520 end;
522 AddDays(ANumber * IdDaysInWeek);
523 end;
525 procedure TIdDateTimeStamp.AddYears;
526 begin
527 if (FYear <= -1) and (Integer(ANumber) >= -FYear) then
528 begin
529 Inc(ANumber);
530 end;
531 Inc(FYear, ANumber);
532 CheckLeapYear;
533 end;
535 procedure TIdDateTimeStamp.CheckLeapYear;
536 begin
537 if FYear mod 4 = 0 then
538 begin
539 if FYear mod 100 = 0 then
540 begin
541 if FYear mod 400 = 0 then
542 begin
543 FIsLeapYear := True;
545 else
546 begin
547 FIsLeapYear := False;
548 end;
550 else
551 begin
552 FIsLeapYear := True;
553 end;
555 else
556 begin
557 FIsLeapYear := False;
558 end;
559 end;
561 function TIdDateTimeStamp.GetAsISO8601Calendar;
562 begin
563 result := IntToStr(FYear) + '-';
564 result := result + IntToStr(MonthOFYear) + '-';
565 result := result + IntToStr(DayOfMonth) + 'T';
566 result := result + AsTimeOFDay;
567 end;
569 function TIdDateTimeStamp.GetAsISO8601Ordinal: string;
570 begin
571 result := IntToStr(FYear) + '-';
572 result := result + IntToStr(FDay) + 'T';
573 result := result + AsTimeOFDay;
574 end;
576 function TIdDateTimeStamp.GetAsISO8601Week: string;
577 begin
578 result := IntToStr(FYear) + '-W';
579 result := result + IntToStr(WeekOFYear) + '-';
580 result := result + IntToStr(DayOfWeek) + 'T';
581 result := result + AsTimeOFDay;
582 end;
584 function TIdDateTimeStamp.GetAsRFC882;
585 begin
586 result := IdDayShortNames[DayOfWeek] + ', ';
587 result := result + IntToStr(DayOfMonth) + ' ';
588 result := result + IdMonthShortNames[MonthOFYear] + ' ';
589 result := result + IntToStr(Year) + ' ';
590 result := result + AsTimeOFDay + ' ';
591 if FTimeZone < -9 then
592 begin
593 result := result + IntToStr(FTimeZone) + '00';
595 else
596 if FTimeZone > 9 then
597 begin
598 result := result + '+' + IntToStr(FTimeZone) + '00';
600 else
601 if FTimeZone >= 0 then
602 begin
603 result := result + '+0' + IntToStr(FTimeZone) + '00';
605 else
606 begin
607 result := result + '-0' + IntToStr(0 - FTimeZone) + '00';
608 end;
610 end;
612 function TIdDateTimeStamp.GetAsTDateTime;
613 begin
614 result := TimeStampToDateTime(GetAsTTimeStamp);
615 end;
617 function TIdDateTimeStamp.GetAsTTimeStamp;
619 NonLeap, Leap: Integer;
620 begin
621 Leap := FYear div 400;
622 NonLeap := (FYear div 100) - Leap;
623 Leap := (FYear div 4) - NonLeap;
624 result.Date := (Leap * IdDaysInLeapYear) + (NonLeap * IdDaysInYear) +
625 Integer(FDay);
626 result.Time := (FSecond * IdMillisecondsInSecond) + FMillisecond;
627 end;
629 function TIdDateTimeStamp.GetAsTimeOFDay;
631 i: Integer;
632 begin
633 i := HourOf24Day;
634 if i < 10 then
635 begin
636 result := result + '0' + IntToStr(i) + ':';
638 else
639 begin
640 result := result + IntToStr(i) + ':';
641 end;
642 i := MinuteOfHour - 1;
643 if i < 10 then
644 begin
645 result := result + '0' + IntToStr(i) + ':';
647 else
648 begin
649 result := result + IntToStr(i) + ':';
650 end;
651 i := SecondOfMinute - 1;
652 if i < 10 then
653 begin
654 result := result + '0' + IntToStr(i) + ' ';
656 else
657 begin
658 result := result + IntToStr(i) + ' ';
659 end;
660 end;
662 function TIdDateTimeStamp.GetBeatOFDay;
664 i64: Int64;
666 begin
667 // i64 := (FSecond) * IdBeatsInDay;
668 // i64 := i64 div IdSecondsInDay;
669 // result := Integer(i64);
670 end;
672 function TIdDateTimeStamp.GetDaysInYear;
673 begin
674 if IsLeapYear then
675 begin
676 result := IdDaysInLeapYear;
678 else
679 begin
680 result := IdDaysInYear;
681 end;
682 end;
684 function TIdDateTimeStamp.GetDayOfMonth;
686 count, mnth, days: Integer;
687 begin
688 mnth := MonthOFYear;
689 if IsLeapYear and (mnth > 2) then
690 begin
691 days := 1;
693 else
694 begin
695 days := 0;
696 end;
697 for count := 1 to mnth - 1 do
698 begin
699 Inc(days, IdDaysInMonth[count]);
700 end;
701 days := Day - days;
702 if days < 0 then
703 begin
704 result := 0;
706 else
707 begin
708 result := days;
709 end;
710 end;
712 function TIdDateTimeStamp.GetDayOfWeek;
714 a, y, m, d, mnth: Integer;
715 begin
716 // Thanks to the "FAQ About Calendars" by Claus Tøndering for this algorithm
717 // http://www.tondering.dk/claus/calendar.html
718 mnth := MonthOFYear;
719 a := (14 - mnth) div 12;
720 y := Year - a;
721 m := mnth + (12 * a) - 2;
722 d := DayOfMonth + y + (y div 4) - (y div 100) + (y div 400) + ((31 * m) div
723 12);
724 d := d mod 7;
725 result := d + 1;
726 end;
728 function TIdDateTimeStamp.GetDayOfWeekName;
729 begin
730 result := IdDayNames[GetDayOfWeek];
731 end;
733 function TIdDateTimeStamp.GetDayOfWeekShortName;
734 begin
735 result := IdDayShortNames[GetDayOfWeek];
736 end;
738 function TIdDateTimeStamp.GetHourOf12Day;
740 hr: Integer;
741 begin
742 hr := GetHourOf24Day;
743 if hr > 12 then
744 begin
745 Dec(hr, 12);
746 end;
747 result := hr;
748 end;
750 function TIdDateTimeStamp.GetHourOf24Day;
751 begin
752 result := (Second - 1) div IdSecondsInHour;
753 end;
755 function TIdDateTimeStamp.GetIsMorning;
756 begin
757 if Second <= (IdSecondsInHalFDay + 1) then
758 begin
759 result := True;
761 else
762 begin
763 result := False;
764 end;
765 end;
767 function TIdDateTimeStamp.GetMinuteOFDay;
768 begin
769 result := Second div IdSecondsInMinute;
770 end;
772 function TIdDateTimeStamp.GetMinuteOfHour;
773 begin
774 result := GetMinuteOFDay - (IdMinutesInHour * (GetHourOf24Day));
775 end;
777 function TIdDateTimeStamp.GetMonthOFYear;
779 AddOne, Count: Byte;
780 Today: Integer;
781 begin
782 if IsLeapYear then
783 begin
784 AddOne := 1;
786 else
787 begin
788 AddOne := 0;
789 end;
790 Today := Day;
791 Count := 1;
792 result := 0;
793 while Count <> 13 do
794 begin
795 if Count = 2 then
796 begin
797 if Today > IdDaysInMonth[Count] + AddOne then
798 begin
799 Dec(Today, IdDaysInMonth[Count] + AddOne);
801 else
802 begin
803 result := Count;
804 break;
805 end;
807 else
808 begin
809 if Today > IdDaysInMonth[Count] then
810 begin
811 Dec(Today, IdDaysInMonth[Count]);
813 else
814 begin
815 result := Count;
816 break;
817 end;
818 end;
819 Inc(Count);
820 end;
821 end;
823 function TIdDateTimeStamp.GetMonthName;
824 begin
825 result := IdMonthNames[MonthOFYear];
826 end;
828 function TIdDateTimeStamp.GetMonthShortName;
829 begin
830 result := IdMonthShortNames[MonthOFYear];
831 end;
833 function TIdDateTimeStamp.GetSecondsInYear;
834 begin
835 if IsLeapYear then
836 begin
837 result := IdSecondsInLeapYear;
839 else
840 begin
841 result := IdSecondsInYear;
842 end;
843 end;
845 function TIdDateTimeStamp.GetSecondOfMinute;
846 begin
847 result := FSecond - (GetMinuteOFDay * IdSecondsInMinute);
848 end;
850 function TIdDateTimeStamp.GetWeekOFYear;
852 w: Integer;
853 DT: TIdDateTimeStamp;
854 begin
855 { DT := TIdDateTimeStamp.Create(Self);
857 DT.SetYear(Year);
858 w := DT.DayOfWeek;
859 w := w + Day - 2;
860 w := w div 7;
861 result := w + 1;
862 finally
863 DT.Free;
864 end;}
865 end;
867 procedure TIdDateTimeStamp.SetFromTDateTime;
868 begin
869 SetFromTTimeStamp(DateTimeToTimeStamp(ADateTime));
870 end;
872 procedure TIdDateTimeStamp.SetFromTTimeStamp;
873 begin
874 SetYear(1);
875 SetDay(1);
876 SetSecond(0);
877 SetMillisecond(ATimeStamp.Time);
878 SetDay(ATimeStamp.Date);
879 end;
881 procedure TIdDateTimeStamp.SetDay;
882 begin
883 FDay := 0;
884 AddDays(ANumber);
885 end;
887 procedure TIdDateTimeStamp.SetMillisecond;
888 begin
889 FMillisecond := 0;
890 AddMilliseconds(ANumber);
891 end;
893 procedure TIdDateTimeStamp.SetSecond;
894 begin
895 FSecond := 0;
896 AddSeconds(ANumber);
897 end;
899 procedure TIdDateTimeStamp.SetYear;
900 begin
901 if ANumber = 0 then
902 begin
903 exit;
904 end;
905 FYear := ANumber;
906 CheckLeapYear;
907 end;
909 procedure TIdDateTimeStamp.SubtractDays;
911 i: Integer;
912 begin
913 if ANumber >= Cardinal(FDay - 1) then
914 begin
915 ANumber := ANumber - Cardinal(FDay - 1);
916 FDay := 1;
918 else
919 begin
920 FDay := FDay - Integer(ANumber);
921 end;
923 if ANumber >= IdDaysInLeapYearCycle then
924 begin
925 i := ANumber div IdDaysInLeapYearCycle;
926 SubtractYears(i * IdYearsInLeapYearCycle);
927 ANumber := ANumber - Cardinal(i * IdDaysInLeapYearCycle);
928 end;
930 if ANumber >= IdDaysInLeapCentury then
931 begin
932 while ANumber >= IdDaysInLeapCentury do
933 begin
934 i := FYear div 100;
936 if i mod 4 = 0 then
937 begin
938 SubtractYears(IdYearsInCentury);
939 ANumber := ANumber - Cardinal(IdDaysInLeapCentury);
941 else
942 begin
943 SubtractYears(IdYearsInCentury);
944 ANumber := ANumber - Cardinal(IdDaysInCentury);
945 end;
946 end;
947 end;
949 if ANumber >= IdDaysInShortLeapYearCycle then
950 begin
951 while ANumber >= IdDaysInShortLeapYearCycle do
952 begin
954 i := (FYear shr 2) shl 2;
956 if SysUtils.IsLeapYear(i) then
957 begin
958 SubtractYears(IdYearsInShortLeapYearCycle);
959 ANumber := ANumber - Cardinal(IdDaysInShortLeapYearCycle);
961 else
962 begin
963 SubtractYears(IdYearsInShortLeapYearCycle);
964 ANumber := ANumber - Cardinal(IdDaysInShortNonLeapYearCycle);
965 end;
966 end;
967 end;
969 while ANumber > Cardinal(DaysInYear) do
970 begin
971 SubtractYears(1);
972 Dec(ANumber, DaysInYear);
973 if Self.IsLeapYear then
974 begin
975 AddDays(1);
976 end;
977 end;
979 if ANumber >= Cardinal(FDay) then
980 begin
981 SubtractYears(1);
982 ANumber := ANumber - Cardinal(FDay);
983 Day := DaysInYear - Integer(ANumber);
985 else
986 begin
987 Dec(FDay, ANumber);
988 end;
990 end;
992 procedure TIdDateTimeStamp.SubtractHours;
994 i: Cardinal;
995 begin
996 i := ANumber div IdHoursInDay;
997 SubtractDays(i);
998 Dec(ANumber, i * IdHoursInDay);
1000 SubtractSeconds(ANumber * IdSecondsInHour);
1001 end;
1003 procedure TIdDateTimeStamp.SubtractMilliseconds;
1005 i: Cardinal;
1006 begin
1007 i := ANumber div IdMillisecondsInDay;
1008 SubtractDays(i);
1009 Dec(ANumber, i * IdMillisecondsInDay);
1011 i := ANumber div IdMillisecondsInSecond;
1012 SubtractSeconds(i);
1013 Dec(ANumber, i * IdMillisecondsInSecond);
1015 Dec(FMillisecond, ANumber);
1016 while FMillisecond <= 0 do
1017 begin
1018 SubtractSeconds(1);
1019 FMillisecond := IdMillisecondsInSecond - FMillisecond;
1020 end;
1021 end;
1023 procedure TIdDateTimeStamp.SubtractMinutes(ANumber: Cardinal);
1024 begin
1025 while ANumber > MaxMinutesAdd do
1026 begin
1027 SubtractSeconds(MaxMinutesAdd * IdSecondsInMinute);
1028 Dec(ANumber, MaxMinutesAdd);
1029 end;
1030 SubtractSeconds(ANumber * IdSecondsInMinute);
1031 end;
1033 procedure TIdDateTimeStamp.SubtractMonths;
1035 i: Integer;
1036 begin
1037 i := ANumber div IdMonthsInYear;
1038 SubtractYears(i);
1039 Dec(ANumber, i * IdMonthsInYear);
1041 while ANumber > 0 do
1042 begin
1043 i := MonthOFYear;
1044 if i = 1 then
1045 begin
1046 i := 13;
1047 end;
1048 if (i = 3) and (IsLeapYear) then
1049 begin
1050 SubtractDays(IdDaysInMonth[2] + 1);
1052 else
1053 begin
1054 SubtractDays(IdDaysInMonth[i - 1]);
1055 end;
1056 Dec(ANumber);
1057 end;
1058 end;
1060 procedure TIdDateTimeStamp.SubtractSeconds(ANumber: Cardinal);
1062 i: Cardinal;
1063 begin
1064 i := ANumber div IdSecondsInDay;
1065 SubtractDays(i);
1066 Dec(ANumber, i * IdSecondsInDay);
1068 Dec(FSecond, ANumber);
1069 if FSecond <= 0 then
1070 begin
1071 SubtractDays(1);
1072 FSecond := IdSecondsInDay + FSecond;
1073 end;
1074 end;
1076 procedure TIdDateTimeStamp.SubtractTDateTime;
1077 begin
1078 SubtractTTimeStamp(DateTimeToTimeStamp(ADateTime));
1079 end;
1081 procedure TIdDateTimeStamp.SubtractTIdDateTimeStamp;
1082 begin
1083 SubtractYears(AIdDateTime.Year);
1084 SubtractDays(AIdDateTime.Day);
1085 SubtractSeconds(AIdDateTime.Second);
1086 SubtractMilliseconds(AIdDateTime.Millisecond);
1087 end;
1089 procedure TIdDateTimeStamp.SubtractTTimeStamp;
1091 TId: TIdDateTimeStamp;
1092 begin
1093 { TId := TIdDateTimeStamp.Create(Self);
1095 TId.SetFromTTimeStamp(ATimeStamp);
1096 Self.SubtractTIdDateTimeStamp(TId);
1097 finally
1098 TId.Free;
1099 end;}
1100 end;
1102 procedure TIdDateTimeStamp.SubtractWeeks(ANumber: Cardinal);
1103 begin
1104 while ANumber > MaxWeekAdd do
1105 begin
1106 SubtractDays(MaxWeekAdd * IdDaysInWeek);
1107 Dec(ANumber, MaxWeekAdd * IdDaysInWeek);
1108 end;
1109 SubtractDays(ANumber * IdDaysInWeek);
1110 end;
1112 procedure TIdDateTimeStamp.SubtractYears;
1113 begin
1114 if (FYear > 0) and (ANumber >= Cardinal(FYear)) then
1115 begin
1116 Inc(ANumber);
1117 end;
1119 FYear := FYear - Integer(ANumber);
1120 CheckLeapYear;
1121 end;
1123 end.