StaticFilter::isGoodFriday()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
cc 2
eloc 3
nc 2
nop 1
crap 2
1
<?php
2
3
namespace iansltx\BusinessDays;
4
5
/**
6
 * Class StaticFilter
7
 *
8
 * A library of static filter functions that can be used directly
9
 *
10
 * @package iansltx\BusinessDays
11
 */
12
class StaticFilter
13
{
14
    protected static $easterByYear = []; // cache of Easter DateTimeImmutable objects, indexed by year
15
16
    /**
17
     * Returns true if $dt is on a Saturday or Sunday, false otherwise
18
     *
19
     * @param \DateTimeInterface $dt
20
     * @return bool
21
     */
22 22
    public static function isWeekend(\DateTimeInterface $dt)
23
    {
24 22
        return in_array($dt->format('w'), [0, 6]);
25
    }
26
27
    /**
28
     * Returns true if $dt is the Monday after Western Easter, false otherwise
29
     *
30
     * @param \DateTimeInterface $dt
31
     * @return bool
32
     */
33 26
    public static function isEasterMonday(\DateTimeInterface $dt)
34
    {
35 26
        $easterMonday = static::getEasterDateTimeForYear($dt->format('Y'))->add(new \DateInterval('P1D'));
36 26
        return $easterMonday->format('m') === $dt->format('m') && $easterMonday->format('d') === $dt->format('d');
37
    }
38
39
    /**
40
     * Returns true if $dt is the Friday before Western Easter, false otherwise
41
     *
42
     * @param \DateTimeInterface $dt
43
     * @return bool
44
     */
45 26
    public static function isGoodFriday(\DateTimeInterface $dt)
46
    {
47 26
        $goodFriday = static::getEasterDateTimeForYear($dt->format('Y'))->sub(new \DateInterval('P2D'));
48 26
        return $goodFriday->format('m') === $dt->format('m') && $goodFriday->format('d') === $dt->format('d');
49
    }
50
51
    /**
52
     * Gets an immutable DateTime object set to midnight UTC of Western Easter
53
     * for a given year. Built because HHVM doesn't include easter_date() or
54
     * easter_day(). Credit to https://www.drupal.org/node/1180480 for the
55
     * original implementation.
56
     *
57
     * To get a runtime-agnostic result comparable to PHP4+'s easter_date(),
58
     * call getTimestamp() on the returned value of this function.
59
     *
60
     * @param int $year
61
     * @return \DateTimeImmutable
62
     */
63 34
    public static function getEasterDateTimeForYear($year) {
64 34
        if (!isset(static::$easterByYear[$year])) { // build cached value if it doesn't exist
65 4
            $century = intval($year / 100);
66 4
            $centuryOverFour = intval($century / 4);
67 4
            $centuryMod4 = $century % 4;
68
69 4
            $twoDigitYear = $year % 100;
70 4
            $twoDigitYearOver4 = intval($twoDigitYear / 4);
71 4
            $twoDigitYearMod4 = $twoDigitYear % 4;
72
73 4
            $yearMod19 = $year % 19;
74
75 4
            $interF = intval(($century + 8) / 25);
76 4
            $interG = intval(($century - $interF + 1) / 3);
77 4
            $interH = (19 * $yearMod19 + $century - $centuryOverFour - $interG + 15) % 30;
78 4
            $interL = (32 + 2 * $centuryMod4 + 2 * $twoDigitYearOver4 - $interH - $twoDigitYearMod4) % 7;
79 4
            $interM = intval(($yearMod19 + 11 * $interH + 22 * $interL) / 451);
80 4
            $interP = ($interH + $interL - 7 * $interM + 114) % 31;
81
82 4
            $monthNumber = intval(($interH + $interL - 7 * $interM + 114) / 31);
83 4
            $day = $interP + 1;
84
85 4
            static::$easterByYear[$year] = \DateTimeImmutable::createFromFormat(
86 4
                   'Y-m-d', $year . '-' . $monthNumber . '-' . $day, new \DateTimeZone('UTC'));
87 2
        }
88
89 34
        return static::$easterByYear[$year]; // return cached value
90
    }
91
}
92