ChristianHolidays::easterMonday()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 12
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 4
1
<?php declare(strict_types=1);
2
/**
3
 * This file is part of the Yasumi package.
4
 *
5
 * Copyright (c) 2015 - 2020 AzuyaLabs
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @author Sacha Telgenhof <[email protected]>
11
 */
12
13
namespace Yasumi\Provider;
14
15
use DateInterval;
16
use DateTime;
17
use Yasumi\Exception\InvalidDateException;
18
use Yasumi\Exception\UnknownLocaleException;
19
use Yasumi\Holiday;
20
21
/**
22
 * Trait ChristianHolidays.
23
 *
24
 * Trait containing base Christian Western churches calendar based holidays.
25
 */
26
trait ChristianHolidays
27
{
28
    /**
29
     * Easter.
30
     *
31
     * Easter is a festival and holiday celebrating the resurrection of Jesus Christ from the dead. Easter is celebrated
32
     * on a date based on a certain number of days after March 21st. The date of Easter Day was defined by the Council
33
     * of Nicaea in AD325 as the Sunday after the first full moon which falls on or after the Spring Equinox.
34
     *
35
     * @link https://en.wikipedia.org/wiki/Easter
36
     *
37
     * @param int $year the year for which Easter need to be created
38
     * @param string $timezone the timezone in which Easter is celebrated
39
     * @param string $locale the locale for which Easter need to be displayed in.
40
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
41
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
42
     *
43
     * @return Holiday
44
     *
45
     * @throws InvalidDateException
46
     * @throws UnknownLocaleException
47
     * @throws \InvalidArgumentException
48
     * @throws \Exception
49
     */
50
    public function easter(
51
        int $year,
52
        string $timezone,
53
        string $locale,
54
        string $type = Holiday::TYPE_OFFICIAL
55
    ): Holiday {
56
        return new Holiday('easter', [], $this->calculateEaster($year, $timezone), $locale, $type);
57
    }
58
59
    /**
60
     * Calculates the date for Easter.
61
     *
62
     * Easter is a festival and holiday celebrating the resurrection of Jesus Christ from the dead. Easter is celebrated
63
     * on a date based on a certain number of days after March 21st.
64
     *
65
     * This function uses the standard PHP 'easter_days' function if the calendar extension is enabled. In case the
66
     * calendar function is not enabled, a fallback calculation has been implemented that is based on the same
67
     * 'easter_days' c function.
68
     *
69
     * Note: In calendrical calculations, frequently operations called integer division are used.
70
     *
71
     * @param int $year the year for which Easter needs to be calculated
72
     * @param string $timezone the timezone in which Easter is celebrated
73
     *
74
     * @return DateTime date of Easter
75
     * @throws \Exception
76
     * @see  easter_days
77
     *
78
     * @link https://github.com/php/php-src/blob/c8aa6f3a9a3d2c114d0c5e0c9fdd0a465dbb54a5/ext/calendar/easter.c
79
     * @link http://www.gmarts.org/index.php?go=415#EasterMallen
80
     * @link https://www.tondering.dk/claus/cal/easter.php
81
     */
82
    protected function calculateEaster(int $year, string $timezone): DateTime
83
    {
84
        if (\extension_loaded('calendar')) {
85
            $easterDays = \easter_days($year);
86
        } else {
87
            $golden = ($year % 19) + 1; // The Golden Number
88
89
            // The Julian calendar applies to the original method from 326AD. The Gregorian calendar was first
90
            // introduced in October 1582 in Italy. Easter algorithms using the Gregorian calendar apply to years
91
            // 1583 AD to 4099 (A day adjustment is required in or shortly after 4100 AD).
92
            // After 1752, most western churches have adopted the current algorithm.
93
            if ($year <= 1752) {
94
                $dom = ($year + (int) ($year / 4) + 5) % 7; // The 'Dominical number' - finding a Sunday
95
                if ($dom < 0) {
96
                    $dom += 7;
97
                }
98
99
                $pfm = (3 - (11 * $golden) - 7) % 30; // Uncorrected date of the Paschal full moon
100
                if ($pfm < 0) {
101
                    $pfm += 30;
102
                }
103
            } else {
104
                $dom = ($year + (int) ($year / 4) - (int) ($year / 100) + (int) ($year / 400)) % 7; // The 'Dominical number' - finding a Sunday
105
                if ($dom < 0) {
106
                    $dom += 7;
107
                }
108
109
                $solar = (int) (($year - 1600) / 100) - (int) (($year - 1600) / 400); // The solar correction
110
                $lunar = (int) (((int) (($year - 1400) / 100) * 8) / 25); // The lunar correction
111
112
                $pfm = (3 - (11 * $golden) + $solar - $lunar) % 30; // Uncorrected date of the Paschal full moon
113
                if ($pfm < 0) {
114
                    $pfm += 30;
115
                }
116
            }
117
118
            // Corrected date of the Paschal full moon, - days after 21st March
119
            if ((29 === $pfm) || (28 === $pfm && $golden > 11)) {
120
                --$pfm;
121
            }
122
123
            $tmp = (4 - $pfm - $dom) % 7;
124
            if ($tmp < 0) {
125
                $tmp += 7;
126
            }
127
128
            $easterDays = $pfm + $tmp + 1; // Easter as the number of days after 21st March
129
        }
130
131
        $easter = new DateTime("$year-3-21", DateTimeZoneFactory::getDateTimeZone($timezone));
132
        $easter->add(new DateInterval('P' . $easterDays . 'D'));
133
134
        return $easter;
135
    }
136
137
    /**
138
     * Easter Monday.
139
     *
140
     * Easter is a festival and holiday celebrating the resurrection of Jesus Christ from the dead. Easter is celebrated
141
     * on a date based on a certain number of days after March 21st. The date of Easter Day was defined by the Council
142
     * of Nicaea in AD325 as the Sunday after the first full moon which falls on or after the Spring Equinox.
143
     *
144
     * @link https://en.wikipedia.org/wiki/Easter
145
     *
146
     * @param int $year the year for which Easter Monday need to be created
147
     * @param string $timezone the timezone in which Easter Monday is celebrated
148
     * @param string $locale the locale for which Easter Monday need to be displayed in.
149
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
150
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
151
     *
152
     * @return Holiday
153
     *
154
     * @throws InvalidDateException
155
     * @throws UnknownLocaleException
156
     * @throws \InvalidArgumentException
157
     * @throws \Exception
158
     */
159
    public function easterMonday(
160
        int $year,
161
        string $timezone,
162
        string $locale,
163
        string $type = Holiday::TYPE_OFFICIAL
164
    ): Holiday {
165
        return new Holiday(
166
            'easterMonday',
167
            [],
168
            $this->calculateEaster($year, $timezone)->add(new DateInterval('P1D')),
169
            $locale,
170
            $type
171
        );
172
    }
173
174
    /**
175
     * Ascension Day.
176
     *
177
     * Ascension Day commemorates the bodily Ascension of Jesus into heaven. It is one of the ecumenical feasts of
178
     * Christian churches. Ascension Day is traditionally celebrated on a Thursday, the fortieth day of Easter although
179
     * some Catholic provinces have moved the observance to the following Sunday.
180
     *
181
     * @link https://en.wikipedia.org/wiki/Feast_of_the_Ascension
182
     *
183
     * @param int $year the year for which Ascension need to be created
184
     * @param string $timezone the timezone in which Ascension is celebrated
185
     * @param string $locale the locale for which Ascension need to be displayed in.
186
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
187
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
188
     *
189
     * @return Holiday
190
     *
191
     * @throws InvalidDateException
192
     * @throws UnknownLocaleException
193
     * @throws \InvalidArgumentException
194
     * @throws \Exception
195
     */
196
    public function ascensionDay(
197
        int $year,
198
        string $timezone,
199
        string $locale,
200
        string $type = Holiday::TYPE_OFFICIAL
201
    ): Holiday {
202
        return new Holiday(
203
            'ascensionDay',
204
            [],
205
            $this->calculateEaster($year, $timezone)->add(new DateInterval('P39D')),
206
            $locale,
207
            $type
208
        );
209
    }
210
211
    /**
212
     * Pentecost (Whitsunday).
213
     *
214
     * Pentecost a feast commemorating the descent of the Holy Spirit upon the Apostles and other followers of Jesus
215
     * Christ. It is celebrated 49 days after Easter and always takes place on Sunday.
216
     *
217
     * @param int $year the year for which Pentecost need to be created
218
     * @param string $timezone the timezone in which Pentecost is celebrated
219
     * @param string $locale the locale for which Pentecost need to be displayed in.
220
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
221
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
222
     *
223
     * @return Holiday
224
     *
225
     * @throws InvalidDateException
226
     * @throws UnknownLocaleException
227
     * @throws \InvalidArgumentException
228
     * @throws \Exception
229
     */
230
    public function pentecost(
231
        int $year,
232
        string $timezone,
233
        string $locale,
234
        string $type = Holiday::TYPE_OFFICIAL
235
    ): Holiday {
236
        return new Holiday(
237
            'pentecost',
238
            [],
239
            $this->calculateEaster($year, $timezone)->add(new DateInterval('P49D')),
240
            $locale,
241
            $type
242
        );
243
    }
244
245
    /**
246
     * Pentecost (Whitmonday).
247
     *
248
     * Pentecost a feast commemorating the descent of the Holy Spirit upon the Apostles and other followers of Jesus
249
     * Christ. It is celebrated 49 days after Easter and always takes place on Sunday.
250
     *
251
     * @param int $year the year for which Pentecost (Whitmonday) need to be created
252
     * @param string $timezone the timezone in which Pentecost (Whitmonday) is celebrated
253
     * @param string $locale the locale for which Pentecost (Whitmonday) need to be displayed in.
254
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
255
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
256
     *
257
     * @return Holiday
258
     *
259
     * @throws InvalidDateException
260
     * @throws UnknownLocaleException
261
     * @throws \InvalidArgumentException
262
     * @throws \Exception
263
     */
264
    public function pentecostMonday(
265
        int $year,
266
        string $timezone,
267
        string $locale,
268
        string $type = Holiday::TYPE_OFFICIAL
269
    ): Holiday {
270
        return new Holiday(
271
            'pentecostMonday',
272
            [],
273
            $this->calculateEaster($year, $timezone)->add(new DateInterval('P50D')),
274
            $locale,
275
            $type
276
        );
277
    }
278
279
    /**
280
     * Corpus Christi.
281
     *
282
     * The Feast of Corpus Christi (Latin for Body of Christ), also known as Corpus Domini, is a Latin Rite liturgical
283
     * solemnity celebrating the tradition and belief in the body and blood of Jesus Christ and his Real Presence in the
284
     * Eucharist. The feast is liturgically celebrated on the Thursday after Trinity Sunday or, "where the Solemnity of
285
     * The Most Holy Body and Blood of Christ is not a holy day of obligation, it is assigned to the Sunday after the
286
     * Most Holy Trinity as its proper day". This is 60 days after Easter.
287
     *
288
     * @param int $year the year for which Corpus Christi need to be created
289
     * @param string $timezone the timezone in which Corpus Christi is celebrated
290
     * @param string $locale the locale for which Corpus Christi need to be displayed in.
291
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
292
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default a type of 'other' is considered.
293
     *
294
     * @return Holiday
295
     *
296
     * @throws InvalidDateException
297
     * @throws UnknownLocaleException
298
     * @throws \InvalidArgumentException
299
     * @throws \Exception
300
     */
301
    public function corpusChristi(
302
        int $year,
303
        string $timezone,
304
        string $locale,
305
        string $type = Holiday::TYPE_OTHER
306
    ): Holiday {
307
        return new Holiday(
308
            'corpusChristi',
309
            [],
310
            $this->calculateEaster($year, $timezone)->add(new DateInterval('P60D')),
311
            $locale,
312
            $type
313
        );
314
    }
315
316
    /**
317
     * Christmas Eve.
318
     *
319
     * Christmas Eve refers to the evening or entire day preceding Christmas Day, a widely celebrated festival
320
     * commemorating the birth of Jesus of Nazareth.[4] Christmas Day is observed around the world, and Christmas Eve is
321
     * widely observed as a full or partial holiday in anticipation of Christmas Day. Together, both days are considered
322
     * one of the most culturally significant celebrations in Christendom and Western society.
323
     *
324
     * @link https://en.wikipedia.org/wiki/Christmas_Eve
325
     *
326
     * @param int $year the year for which Christmas Eve needs to be created
327
     * @param string $timezone the timezone in which Christmas Eve is celebrated
328
     * @param string $locale the locale for which Christmas Eve need to be displayed in.
329
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
330
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default observance is considered.
331
     *
332
     * @return Holiday
333
     *
334
     * @throws InvalidDateException
335
     * @throws UnknownLocaleException
336
     * @throws \InvalidArgumentException
337
     * @throws \Exception
338
     */
339
    public function christmasEve(
340
        int $year,
341
        string $timezone,
342
        string $locale,
343
        string $type = Holiday::TYPE_OBSERVANCE
344
    ): Holiday {
345
        return new Holiday(
346
            'christmasEve',
347
            [],
348
            new DateTime("$year-12-24", DateTimeZoneFactory::getDateTimeZone($timezone)),
349
            $locale,
350
            $type
351
        );
352
    }
353
354
    /**
355
     * Christmas Day.
356
     *
357
     * Christmas or Christmas Day (Old English: Crīstesmæsse, meaning "Christ's Mass") is an annual festival
358
     * commemorating the birth of Jesus Christ, observed most commonly on December 25 as a religious and cultural
359
     * celebration among billions of people around the world.
360
     *
361
     * @param int $year the year for which Christmas Day need to be created
362
     * @param string $timezone the timezone in which Christmas Day is celebrated
363
     * @param string $locale the locale for which Christmas Day need to be displayed in.
364
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
365
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
366
     *
367
     * @return Holiday
368
     *
369
     * @throws InvalidDateException
370
     * @throws UnknownLocaleException
371
     * @throws \InvalidArgumentException
372
     * @throws \Exception
373
     */
374
    public function christmasDay(
375
        int $year,
376
        string $timezone,
377
        string $locale,
378
        string $type = Holiday::TYPE_OFFICIAL
379
    ): Holiday {
380
        return new Holiday(
381
            'christmasDay',
382
            [],
383
            new DateTime("$year-12-25", DateTimeZoneFactory::getDateTimeZone($timezone)),
384
            $locale,
385
            $type
386
        );
387
    }
388
389
    /**
390
     * Second Christmas Day / Boxing Day.
391
     *
392
     * Christmas or Christmas Day (Old English: Crīstesmæsse, meaning "Christ's Mass") is an annual festival
393
     * commemorating the birth of Jesus Christ, observed most commonly on December 25 as a religious and cultural
394
     * celebration among billions of people around the world.
395
     *
396
     * @param int $year the year for which the Second Christmas Day / Boxing Day need to be created
397
     * @param string $timezone the timezone in which the Second Christmas Day / Boxing Day is celebrated
398
     * @param string $locale the locale for which the Second Christmas Day / Boxing Day need to be displayed in.
399
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
400
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
401
     *
402
     * @return Holiday
403
     *
404
     * @throws InvalidDateException
405
     * @throws UnknownLocaleException
406
     * @throws \InvalidArgumentException
407
     * @throws \Exception
408
     */
409
    public function secondChristmasDay(
410
        int $year,
411
        string $timezone,
412
        string $locale,
413
        string $type = Holiday::TYPE_OFFICIAL
414
    ): Holiday {
415
        return new Holiday(
416
            'secondChristmasDay',
417
            [],
418
            new DateTime("$year-12-26", DateTimeZoneFactory::getDateTimeZone($timezone)),
419
            $locale,
420
            $type
421
        );
422
    }
423
424
    /**
425
     * All Saints' Day.
426
     *
427
     * All Saints' Day, also known as All Hallows, Solemnity of All Saints, or Feast of All Saints is a solemnity
428
     * celebrated on 1 November by the Catholic Church and various Protestant denominations, and on the first Sunday
429
     * after Pentecost in Eastern Catholicism and Eastern Orthodoxy, in honour of all the saints, known and unknown.
430
     * The liturgical celebration begins at Vespers on the evening of 31 October and ends at the close of 1 November.
431
     *
432
     * @link https://en.wikipedia.org/wiki/All_Saints%27_Day
433
     *
434
     * @param int $year the year for which All Saints' Day need to be created
435
     * @param string $timezone the timezone in which All Saints' Day is celebrated
436
     * @param string $locale the locale for which All Saints' Day need to be displayed in.
437
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
438
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
439
     *
440
     * @return Holiday
441
     *
442
     * @throws InvalidDateException
443
     * @throws UnknownLocaleException
444
     * @throws \InvalidArgumentException
445
     * @throws \Exception
446
     */
447
    public function allSaintsDay(
448
        int $year,
449
        string $timezone,
450
        string $locale,
451
        string $type = Holiday::TYPE_OFFICIAL
452
    ): Holiday {
453
        return new Holiday('allSaintsDay', [], new DateTime("$year-11-1", DateTimeZoneFactory::getDateTimeZone($timezone)), $locale, $type);
454
    }
455
456
    /**
457
     * Day of the Assumption of Mary.
458
     *
459
     * The Assumption of the Virgin Mary into Heaven, informally known as the Assumption, was the bodily taking up
460
     * of the Virgin Mary into Heaven at the end of her earthly life. In the churches that observe it, the
461
     * Assumption is a major feast day, commonly celebrated on August 15.
462
     *
463
     * @link https://en.wikipedia.org/wiki/Assumption_of_Mary
464
     *
465
     * @param int $year the year for which the day of the Assumption of Mary need to be created
466
     * @param string $timezone the timezone in which the day of the Assumption of Mary is celebrated
467
     * @param string $locale the locale for which the day of the Assumption of Mary need to be displayed in.
468
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
469
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
470
     *
471
     * @return Holiday
472
     *
473
     * @throws InvalidDateException
474
     * @throws UnknownLocaleException
475
     * @throws \InvalidArgumentException
476
     * @throws \Exception
477
     */
478
    public function assumptionOfMary(
479
        int $year,
480
        string $timezone,
481
        string $locale,
482
        string $type = Holiday::TYPE_OFFICIAL
483
    ): Holiday {
484
        return new Holiday(
485
            'assumptionOfMary',
486
            [],
487
            new DateTime("$year-8-15", DateTimeZoneFactory::getDateTimeZone($timezone)),
488
            $locale,
489
            $type
490
        );
491
    }
492
493
    /**
494
     * Good Friday.
495
     *
496
     * Good Friday is a Christian religious holiday commemorating the crucifixion of Jesus Christ and his death at
497
     * Calvary. The holiday is observed during Holy Week as part of the Paschal Triduum on the Friday preceding Easter
498
     * Sunday, and may coincide with the Jewish observance of Passover.
499
     *
500
     * @param int $year the year for which Good Friday need to be created
501
     * @param string $timezone the timezone in which Good Friday is celebrated
502
     * @param string $locale the locale for which Good Friday need to be displayed in.
503
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
504
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
505
     *
506
     * @return Holiday
507
     *
508
     * @throws InvalidDateException
509
     * @throws UnknownLocaleException
510
     * @throws \InvalidArgumentException
511
     * @throws \Exception
512
     */
513
    public function goodFriday(
514
        int $year,
515
        string $timezone,
516
        string $locale,
517
        string $type = Holiday::TYPE_OFFICIAL
518
    ): Holiday {
519
        return new Holiday(
520
            'goodFriday',
521
            [],
522
            $this->calculateEaster($year, $timezone)->sub(new DateInterval('P2D')),
523
            $locale,
524
            $type
525
        );
526
    }
527
528
    /**
529
     * Epiphany.
530
     *
531
     * Epiphany is a Christian feast day that celebrates the revelation of God the Son as a human being in Jesus Christ.
532
     * The traditional date for the feast is January 6. However, since 1970, the celebration is held in some countries
533
     * on the Sunday after January 1. Eastern Churches following the Julian Calendar observe the Theophany feast on what
534
     * for most countries is January 19 because of the 13-day difference today between that calendar and the generally
535
     * used Gregorian calendar.
536
     *
537
     * @link https://en.wikipedia.org/wiki/Epiphany_(holiday)
538
     *
539
     * @param int $year the year for which Epiphany need to be created
540
     * @param string $timezone the timezone in which Epiphany is celebrated
541
     * @param string $locale the locale for which Epiphany need to be displayed in.
542
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
543
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
544
     *
545
     * @return Holiday
546
     *
547
     * @throws InvalidDateException
548
     * @throws UnknownLocaleException
549
     * @throws \InvalidArgumentException
550
     * @throws \Exception
551
     */
552
    public function epiphany(
553
        int $year,
554
        string $timezone,
555
        string $locale,
556
        string $type = Holiday::TYPE_OFFICIAL
557
    ): Holiday {
558
        return new Holiday('epiphany', [], new DateTime("$year-1-6", DateTimeZoneFactory::getDateTimeZone($timezone)), $locale, $type);
559
    }
560
561
    /**
562
     * Ash Wednesday.
563
     *
564
     * Ash Wednesday, a day of fasting, is the first day of Lent in Western Christianity. It occurs 46 days (40 fasting
565
     * days, if the 6 Sundays, which are not days of fast, are excluded) before Easter and can fall as early as 4
566
     * February or as late as 10 March.
567
     *
568
     * @link https://en.wikipedia.org/wiki/Ash_Wednesday
569
     *
570
     * @param int $year the year for which Ash Wednesday need to be created
571
     * @param string $timezone the timezone in which Ash Wednesday is celebrated
572
     * @param string $locale the locale for which Ash Wednesday need to be displayed in.
573
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
574
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
575
     *
576
     * @return Holiday
577
     *
578
     * @throws InvalidDateException
579
     * @throws UnknownLocaleException
580
     * @throws \InvalidArgumentException
581
     * @throws \Exception
582
     */
583
    public function ashWednesday(
584
        int $year,
585
        string $timezone,
586
        string $locale,
587
        string $type = Holiday::TYPE_OFFICIAL
588
    ): Holiday {
589
        return new Holiday(
590
            'ashWednesday',
591
            [],
592
            $this->calculateEaster($year, $timezone)->sub(new DateInterval('P46D')),
593
            $locale,
594
            $type
595
        );
596
    }
597
598
    /**
599
     * Immaculate Conception.
600
     *
601
     * The Feast of the Immaculate Conception celebrates the solemn belief in the Immaculate Conception of the Blessed
602
     * Virgin Mary. It is universally celebrated on December 8, nine months before the feast of the Nativity of Mary,
603
     * which is celebrated on September 8. It is one of the most important Marian feasts celebrated in the liturgical
604
     * calendar of the Roman Catholic Church.
605
     *
606
     * @link https://en.wikipedia.org/wiki/Feast_of_the_Immaculate_Conception
607
     *
608
     * @param int $year the year for which Immaculate Conception need to be created
609
     * @param string $timezone the timezone in which Immaculate Conception is celebrated
610
     * @param string $locale the locale for which Immaculate Conception need to be displayed in.
611
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
612
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
613
     *
614
     * @return Holiday
615
     *
616
     * @throws InvalidDateException
617
     * @throws UnknownLocaleException
618
     * @throws \InvalidArgumentException
619
     * @throws \Exception
620
     */
621
    public function immaculateConception(
622
        int $year,
623
        string $timezone,
624
        string $locale,
625
        string $type = Holiday::TYPE_OFFICIAL
626
    ): Holiday {
627
        return new Holiday(
628
            'immaculateConception',
629
            [],
630
            new DateTime("$year-12-8", DateTimeZoneFactory::getDateTimeZone($timezone)),
631
            $locale,
632
            $type
633
        );
634
    }
635
636
    /**
637
     * St. Stephen's Day.
638
     *
639
     * St. Stephen's Day, or the Feast of St. Stephen, is a Christian saint's day to commemorate Saint Stephen, the
640
     * first Christian martyr or protomartyr, celebrated on 26 December in the Western Church and 27 December in the
641
     * Eastern Church. Many Eastern Orthodox churches adhere to the Julian calendar and mark St. Stephen's Day on 27
642
     * December according to that calendar, which places it on 8 January of the Gregorian calendar used in secular
643
     * contexts.
644
     *
645
     * @link https://en.wikipedia.org/wiki/St._Stephen%27s_Day
646
     *
647
     * @param int $year the year for which St. Stephen's Day need to be created
648
     * @param string $timezone the timezone in which St. Stephen's Day is celebrated
649
     * @param string $locale the locale for which St. Stephen's Day need to be displayed in.
650
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
651
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
652
     *
653
     * @return Holiday
654
     *
655
     * @throws InvalidDateException
656
     * @throws UnknownLocaleException
657
     * @throws \InvalidArgumentException
658
     * @throws \Exception
659
     */
660
    public function stStephensDay(
661
        int $year,
662
        string $timezone,
663
        string $locale,
664
        string $type = Holiday::TYPE_OFFICIAL
665
    ): Holiday {
666
        return new Holiday(
667
            'stStephensDay',
668
            [],
669
            new DateTime("$year-12-26", DateTimeZoneFactory::getDateTimeZone($timezone)),
670
            $locale,
671
            $type
672
        );
673
    }
674
675
    /**
676
     * St. Joseph's Day.
677
     *
678
     * Saint Joseph's Day, March 19, the Feast of St. Joseph is in Western Christianity the principal feast day of Saint
679
     * Joseph, husband of the Blessed Virgin Mary. He is the foster-father of Jesus Christ. March 19 was dedicated to
680
     * Saint Joseph in several Western calendars by the 10th century, and this custom was established in Rome by 1479.
681
     * Pope St. Pius V extended its use to the entire Roman Rite by his Apostolic Constitution Quo primum
682
     * (July 14, 1570). Since 1969, Episcopal Conferences may, if they wish, transfer it to a date outside Lent.
683
     *
684
     * @link https://en.wikipedia.org/wiki/St_Joseph's_Day
685
     *
686
     * @param int $year the year for which St. Joseph's Day need to be created
687
     * @param string $timezone the timezone in which St. Joseph's Day is celebrated
688
     * @param string $locale the locale for which St. Joseph's Day need to be displayed in.
689
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
690
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
691
     *
692
     * @return Holiday
693
     *
694
     * @throws InvalidDateException
695
     * @throws UnknownLocaleException
696
     * @throws \InvalidArgumentException
697
     * @throws \Exception
698
     */
699
    public function stJosephsDay(
700
        int $year,
701
        string $timezone,
702
        string $locale,
703
        string $type = Holiday::TYPE_OFFICIAL
704
    ): Holiday {
705
        return new Holiday('stJosephsDay', [], new DateTime("$year-3-19", DateTimeZoneFactory::getDateTimeZone($timezone)), $locale, $type);
706
    }
707
708
    /**
709
     * Maundy Thursday.
710
     *
711
     * Maundy Thursday (also known as Holy Thursday, Covenant Thursday, Great and Holy Thursday, Sheer Thursday, and
712
     * Thursday of Mysteries) is the Christian holy day falling on the Thursday before Easter. It commemorates the
713
     * Maundy and Last Supper of Jesus Christ with the Apostles as described in the Canonical gospels. It is the fifth
714
     * day of Holy Week, and is preceded by Holy Wednesday and followed by Good Friday.
715
     *
716
     * @link https://en.wikipedia.org/wiki/Maundy_Thursday
717
     *
718
     * @param int $year the year for which Maundy Thursday need to be created
719
     * @param string $timezone the timezone in which Maundy Thursday is celebrated
720
     * @param string $locale the locale for which Maundy Thursday need to be displayed in.
721
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
722
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
723
     *
724
     * @return Holiday
725
     *
726
     * @throws InvalidDateException
727
     * @throws UnknownLocaleException
728
     * @throws \InvalidArgumentException
729
     * @throws \Exception
730
     */
731
    public function maundyThursday(
732
        int $year,
733
        string $timezone,
734
        string $locale,
735
        string $type = Holiday::TYPE_OFFICIAL
736
    ): Holiday {
737
        return new Holiday(
738
            'maundyThursday',
739
            [],
740
            $this->calculateEaster($year, $timezone)->sub(new DateInterval('P3D')),
741
            $locale,
742
            $type
743
        );
744
    }
745
746
    /**
747
     * St. George's Day.
748
     *
749
     * Saint George's Day is the feast day of Saint George. It is celebrated by various Christian Churches and by the
750
     * several nations, kingdoms, countries, and cities of which Saint George is the patron saint. Saint George's Day is
751
     * celebrated on 23 April, the traditionally accepted date of Saint George's death in 303 AD. For Eastern Orthodox
752
     * Churches (which use the Julian calendar), '23 April' currently falls on 6 May of the Gregorian calendar.
753
     *
754
     * @link https://en.wikipedia.org/wiki/St_George%27s_Day
755
     *
756
     * @param int $year the year for which St. George's Day need to be created
757
     * @param string $timezone the timezone in which St. George's Day is celebrated
758
     * @param string $locale the locale for which St. George's Day need to be displayed in.
759
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
760
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
761
     *
762
     * @return Holiday
763
     *
764
     * @throws InvalidDateException
765
     * @throws UnknownLocaleException
766
     * @throws \InvalidArgumentException
767
     * @throws \Exception
768
     */
769
    public function stGeorgesDay(
770
        int $year,
771
        string $timezone,
772
        string $locale,
773
        string $type = Holiday::TYPE_OFFICIAL
774
    ): Holiday {
775
        return new Holiday('stGeorgesDay', [], new DateTime("$year-4-23", DateTimeZoneFactory::getDateTimeZone($timezone)), $locale, $type);
776
    }
777
778
    /**
779
     * St. John's Day.
780
     *
781
     * The Nativity of John the Baptist (or Birth of John the Baptist, or Nativity of the Forerunner) is a Christian
782
     * feast day celebrating the birth of John the Baptist, a prophet who foretold the coming of the Messiah in the
783
     * person of Jesus, whom he later baptised. The Nativity of John the Baptist on June 24 comes three months after the
784
     * celebration on March 25 of the Annunciation, when the angel Gabriel told Mary that her cousin Elizabeth was in
785
     * her sixth month of pregnancy.
786
     *
787
     * @link https://en.wikipedia.org/wiki/Nativity_of_St_John_the_Baptist
788
     *
789
     * @param int $year the year for which St. John's Day need to be created
790
     * @param string $timezone the timezone in which St. John's Day is celebrated
791
     * @param string $locale the locale for which St. John's Day need to be displayed in.
792
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
793
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
794
     *
795
     * @return Holiday
796
     *
797
     * @throws InvalidDateException
798
     * @throws UnknownLocaleException
799
     * @throws \InvalidArgumentException
800
     * @throws \Exception
801
     */
802
    public function stJohnsDay(
803
        int $year,
804
        string $timezone,
805
        string $locale,
806
        string $type = Holiday::TYPE_OFFICIAL
807
    ): Holiday {
808
        return new Holiday('stJohnsDay', [], new DateTime("$year-06-24", DateTimeZoneFactory::getDateTimeZone($timezone)), $locale, $type);
809
    }
810
811
    /**
812
     * Annunciation.
813
     *
814
     * The Annunciation, also referred to as the Annunciation to the Blessed Virgin Mary, the Annunciation of Our
815
     * Lady or the Annunciation of the Lord, is the Christian celebration of the announcement by the angel Gabriel to
816
     * the Virgin Mary that she would conceive and become the mother of Jesus, the Son of God, marking his Incarnation.
817
     * Many Christians observe this event with the Feast of the Annunciation on 25 March, an approximation of the
818
     * northern vernal equinox nine full months before Christmas, the ceremonial birthday of Jesus.
819
     *
820
     * @link https://en.wikipedia.org/wiki/Annunciation
821
     *
822
     * @param int $year the year for which the Annunciation needs to be created
823
     * @param string $timezone the timezone in which the Annunciation is celebrated
824
     * @param string $locale the locale for which the Annunciation need to be displayed in.
825
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
826
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
827
     *
828
     * @return Holiday
829
     *
830
     * @throws InvalidDateException
831
     * @throws UnknownLocaleException
832
     * @throws \InvalidArgumentException
833
     * @throws \Exception
834
     */
835
    public function annunciation(
836
        int $year,
837
        string $timezone,
838
        string $locale,
839
        string $type = Holiday::TYPE_OFFICIAL
840
    ): Holiday {
841
        return new Holiday(
842
            'annunciation',
843
            [],
844
            new DateTime("$year-03-25", DateTimeZoneFactory::getDateTimeZone($timezone)),
845
            $locale,
846
            $type
847
        );
848
    }
849
850
    /**
851
     * Calculate the Easter date for Orthodox churches.
852
     *
853
     * @param int $year the year for which Easter needs to be calculated
854
     * @param string $timezone the timezone in which Easter is celebrated
855
     *
856
     * @return DateTime date of Orthodox Easter
857
     *
858
     * @throws \Exception
859
     * @link https://en.wikipedia.org/wiki/Computus#Meeus.27s_Julian_algorithm
860
     * @link https://www.php.net/manual/en/function.easter-date.php#83794
861
     */
862
    public function calculateOrthodoxEaster(int $year, string $timezone): DateTime
863
    {
864
        $a = $year % 4;
865
        $b = $year % 7;
866
        $c = $year % 19;
867
        $d = (19 * $c + 15) % 30;
868
        $e = (2 * $a + 4 * $b - $d + 34) % 7;
869
        $month = \floor(($d + $e + 114) / 31);
870
        $day = (($d + $e + 114) % 31) + 1;
871
872
        return (new DateTime("$year-$month-$day", DateTimeZoneFactory::getDateTimeZone($timezone)))->add(new DateInterval('P13D'));
873
    }
874
875
    /**
876
     * Calculates the day of the reformation.
877
     *
878
     * Reformation Day is a religious holiday celebrated on October 31, alongside All Hallows' Eve, in remembrance
879
     * of the Reformation. It is celebrated among various Protestants, especially by Lutheran and Reformed church
880
     * communities.
881
     * It is a civic holiday in the German states of Brandenburg, Mecklenburg-Vorpommern, Saxony, Saxony-Anhalt and
882
     * Thuringia. Slovenia celebrates it as well due to the profound contribution of the Reformation to that nation's
883
     * cultural development, although Slovenes are mainly Roman Catholics. With the increasing influence of
884
     * Protestantism in Latin America (particularly newer groups such as various Evangelical Protestants, Pentecostals
885
     * or Charismatics), it has been declared a national holiday in Chile in 2009.
886
     *
887
     * @link https://en.wikipedia.org/wiki/Reformation_Day
888
     * @link https://de.wikipedia.org/wiki/Reformationstag#Ursprung_und_Geschichte
889
     *
890
     * @param int $year the year for which St. John's Day need to be created
891
     * @param string $timezone the timezone in which St. John's Day is celebrated
892
     * @param string $locale the locale for which St. John's Day need to be displayed in.
893
     * @param string $type The type of holiday. Use the following constants: TYPE_OFFICIAL, TYPE_OBSERVANCE,
894
     *                         TYPE_SEASON, TYPE_BANK or TYPE_OTHER. By default an official holiday is considered.
895
     *
896
     * @return Holiday
897
     *
898
     * @throws InvalidDateException
899
     * @throws UnknownLocaleException
900
     * @throws \InvalidArgumentException
901
     * @throws \Exception
902
     */
903
    public function reformationDay(
904
        int $year,
905
        string $timezone,
906
        string $locale,
907
        string $type = Holiday::TYPE_OFFICIAL
908
    ): Holiday {
909
        return new Holiday(
910
            'reformationDay',
911
            [],
912
            new DateTime("$year-10-31", DateTimeZoneFactory::getDateTimeZone($timezone)),
913
            $locale,
914
            $type
915
        );
916
    }
917
}
918