1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330: 331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369: 370: 371: 372: 373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410: 411: 412: 413:
| unit Holidays;
interface
uses Classes, Controls, SysUtils;
type TRegion = (rBadenWuertenberg, rBayern, rBerlin, rBrandenburg, rBremen, rHamburg, rHessen, rMecklenburgVorpommern, rNiedersachsen, rNordrheinWestfalen, rRheinlandPfalz, rSaarland, rSachsen, rSachsenAnhalt, rSchleswigHolstein, rThueringen);
THolidayEvent = procedure(Sender: TObject; AHolidayName: string) of object; TSpecialDayEvent = procedure(Sender: TObject; ASpecialdayName: string) of object;
THolidays = class(TComponent) private FDate: TDate; FHoliday: array of Integer; FHolidayName: string; FSpecialdayName: string; FRegion: TRegion; FOnHoliday: THolidayEvent; FOnSpecialday: TSpecialdayEvent; FOnInvalidDate: TNotifyEvent; procedure CalcHolidays; procedure SetDate(const Value: TDate); procedure SetRegion(const Value: TRegion); public constructor Create(AOwner: TComponent); override; function IsHoliday: Boolean; function IsSpecialday: Boolean; published property Date: TDate read FDate write SetDate; property HolidayName: string read FHolidayName; property SpecialdayName: string read FSpecialdayName; property Region: TRegion read FRegion write SetRegion; property OnHoliday: THolidayEvent read FOnHoliday write FOnHoliday; property OnSpecialday: TSpecialdayEvent read FOnSpecialday write FOnSpecialday; property OnInvalidDate: TNotifyEvent read FOnInvalidDate write FOnInvalidDate; end;
procedure Register;
implementation
uses DateUtils, Dialogs;
const HOLIDAY_NAME: array[1..19] of string[25] = ('Neujahr', 'Maifeiertag', 'Tag der deutschen Einheit', 'Allerheiligen', 'Totensonntag', 'Volkstrauertag', '1. Weihnachtstag', '2. Weihnachtstag', 'Karfreitag', 'Ostersonntag', 'Ostermontag', 'Christi Himmelfahrt', 'Pfingstsonntag', 'Pfingstmontag', 'Fronleichnam', 'Heilige 3 Könige', 'Mariä Himmelfahrt', 'Reformationstag', 'Buß- und Bettag'); SPECIALDAY_NAME: array[1..24] of string[25] = ('Mariä Lichtmeß', 'Valentinstag', 'Weiberfastnacht', 'Rosenmontag', 'Fastnacht', 'Aschermittwoch', 'Mariä Verkündigung', 'Palmsonntag', 'Gründonnerstag', 'Muttertag', 'Peter und Paul', 'Mariä Geburt', 'Erntedankfest', 'Mariä Empfängnis', 'Silvester', '1. Advent', '2. Advent', '3. Advent', '4. Advent', 'Heiligabend', 'Frühlingsanfang', 'Sommmeranfang', 'Herbstanfang', 'Winteranfang');
procedure Register; begin RegisterComponents('Samples', [THolidays]); end;
procedure THolidays.CalcHolidays; var d, dw, om, aw, year: Word; dat: TDate; Eastern: TDate; Christmas: TDate;
function GetEasternSunday: TDate; var a, b, c, d, e, tag, monat: Integer; begin a := year mod 19; b := year mod 4; c := year mod 7; d := (19 * a + 24) mod 30; e := (2 * b + 4 * c + 6 * d + 5) mod 7; tag := 22 + d + e; monat := 3; if Tag > 31 then begin tag := d + e - 9; monat := 4; end; if (tag = 26) and (monat = 4) then tag := 19; if (tag = 25) and (monat = 4) and (d = 28) and (e = 6) and (a > 10) then tag := 18; try Result := EncodeDate(year, monat, tag); except Result := 0; end; end;
begin for d := 1 to High(FHoliday) do FHoliday[d] := 0;
year := YearOf(FDate);
Eastern := GetEasternSunday; try DecodeDate(Eastern, year, om, d); except om := 4; end;
try Christmas := EncodeDate(year, 12, 25); if (DayOfWeek(Christmas) - 1) = 0 then dw := 7 else dw := DayOfWeek(Christmas) - 1; except Christmas := -1; dw := 0; end;
dat := EncodeDate(year, 2, 2); FHoliday[DayOfTheYear(dat)] := -1;
dat := Encodedate(year, 2, 14); FHoliday[DayOfTheYear(dat)] := -2;
dat := Eastern - 45; while DayOfWeek(dat) <> 2 do dat := dat - 1; FHoliday[DayOfTheYear(dat) - 4] := -3;
FHoliday[DayOfTheYear(dat)] := -4;
FHoliday[DayOfTheYear(dat) + 1] := -5;
FHoliday[DayOfTheYear(dat) + 2] := -6;
dat := Encodedate(year, 3, 25); FHoliday[DayOfTheYear(dat)] := -7;
FHoliday[DayOfTheYear(Eastern) - 7] := -8;
FHoliday[DayOfTheYear(Eastern) - 3] := -9;
dat := EncodeDate(year, 4, 30); aw := DayOfWeek(dat) - 1; dat := dat - aw + 14; if dat = Eastern + 49 then dat := dat - 7; FHoliday[DayOfTheYear(dat)] := -10;
dat := EncodeDate(year, 6, 29); FHoliday[DayOfTheYear(dat)] := -11;
dat := EncodeDate(year, 9, 8); FHoliday[DayOfTheYear(dat)] := -12;
dat := EncodeDate(year, 10, 1); while DayOfWeek(dat) <> 1 do dat := dat + 1;
FHoliday[DayOfTheYear(dat)] := -13;
dat := EncodeDate(year, 12, 8); FHoliday[DayOfTheYear(dat)] := -14;
dat := EncodeDate(year, 12, 31); FHoliday[DayOfTheYear(dat)] := -15;
dat := Christmas; while DayOfWeek(dat) <> 1 do dat := dat - 1; FHoliday[DayOfTheYear(dat) - 21] := -16;
FHoliday[DayOfTheYear(dat) - 14] := -17;
FHoliday[DayOfTheYear(dat) - 7] := -18;
FHoliday[DayOfTheYear(dat)] := -19;
FHoliday[DayOfTheYear(Christmas) - 1] := -20;
dat := EncodeDate(year, 3, 21); FHoliday[DayOfTheYear(dat)] := -21;
dat := EncodeDate(year, 6, 21); FHoliday[DayOfTheYear(dat)] := -22;
dat := EncodeDate(year, 9, 23); FHoliday[DayOfTheYear(dat)] := -23;
dat := EncodeDate(year, 12, 22); FHoliday[DayOfTheYear(dat)] := -24;
FHoliday[1] := 1;
dat := EncodeDate(year, 5, 1); FHoliday[DayOfTheYear(dat)] := 2;
dat := EncodeDate(year, 10, 3); FHoliday[DayOfTheYear(dat)] := 3;
if (FRegion = rBayern) or (FRegion = rBadenWuertenberg) or (FRegion = rNordrheinWestfalen) or (FRegion = rRheinlandPfalz) or (FRegion = rSaarland) then begin dat := EncodeDate(year, 11, 1); FHoliday[DayOfTheYear(dat)] := 4; end;
if (Christmas >= 0) then FHoliday[DayOfTheYear(Christmas - dw - 28)] := 5;
if (FRegion = rSachsen) then FHoliday[DayOfTheYear(Christmas - dw - 32)] := 19;
if (Christmas >= 0) then FHoliday[DayOfTheYear(Christmas - dw - 35)] := 6;
if (Christmas >= 0) then FHoliday[DayOfTheYear(Christmas)] := 7;
if (Christmas >= 0) then FHoliday[DayOfTheYear(Christmas) + 1] := 8;
FHoliday[DayOfTheYear(Eastern) - 2] := 9;
FHoliday[DayOfTheYear(Eastern)] := 10;
FHoliday[DayOfTheYear(Eastern) + 1] := 11;
FHoliday[DayOfTheYear(Eastern) + 39] := 12;
FHoliday[DayOfTheYear(Eastern) + 49] := 13;
FHoliday[DayOfTheYear(Eastern) + 50] := 14;
if (FRegion = rBerlin) or ((FRegion = rNordrheinWestfalen) and (FRegion <= rSachsen)) or (FRegion = rThueringen) then FHoliday[DayOfTheYear(Eastern) + 60] := 15;
if (FRegion = rBadenWuertenberg) or (FRegion = rBayern) or (FRegion = rSachsenAnhalt) then FHoliday[6] := 16;
if (FRegion = rBayern) or (FRegion = rSaarland) then begin dat := EncodeDate(year, 8, 15); FHoliday[DayOfTheYear(dat)] := 17; end;
if (FRegion = rBrandenburg) or (FRegion = rMecklenburgVorpommern) or (FRegion = rSachsen) or (FRegion = rSachsenAnhalt) or (FRegion = rThueringen) then begin dat := EncodeDate(year, 10, 31); FHoliday[DayOfTheYear(dat)] := 18; end; end;
constructor THolidays.Create(AOwner: TComponent); begin inherited;
SetLength(FHoliday, DaysInYear(Now)+1);
FRegion := rSachsenAnhalt; SetDate(Now); end;
function THolidays.IsHoliday: Boolean; begin Result := (FHolidayName <> ''); end;
function THolidays.IsSpecialday: Boolean; begin Result := (FSpecialdayName <> ''); end;
procedure THolidays.SetDate(const Value: TDate); var h, y1, y2: Integer; begin y1 := YearOf(FDate); y2 := YearOf(Value);
if not IsValidDate(y2, MonthOf(Value), DayOf(Value)) or (Value <= 0) then begin if Assigned(FOnInvalidDate) then FOnInvalidDate(Self); Exit; end;
FDate := Value; if (y1 <> y2) then CalcHolidays;
FHolidayName := ''; FSpecialDayName := ''; h := FHoliday[DayOfTheYear(FDate)]; if (h > 0) then begin FHolidayName := HOLIDAY_NAME[h]; if Assigned(FOnHoliday) then FOnHoliday(Self, FHolidayName); end else if (h < 0) then begin FSpecialDayName := SPECIALDAY_NAME[-h]; if Assigned(FOnSpecialDay) then FOnSpecialDay(Self, FSpecialDayName); end; end;
procedure THolidays.SetRegion(const Value: TRegion); begin FRegion := Value; CalcHolidays; SetDate(FDate); end;
end. |