Completed
Push — master ( 7462e3...8bf86b )
by Daniel
02:34
created

Romanian::readTypeFromJsonFileUniversal()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 2
1
<?php
2
3
/**
4
 *
5
 * The MIT License (MIT)
6
 *
7
 * Copyright (c) 2015 Daniel Popiniuc
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
10
 * of this software and associated documentation files (the "Software"), to deal
11
 * in the Software without restriction, including without limitation the rights
12
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
 * copies of the Software, and to permit persons to whom the Software is
14
 * furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included in all
17
 * copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
 * SOFTWARE.
26
 *
27
 */
28
29
namespace danielgp\bank_holidays;
30
31
/**
32
 * Return a list of all Romanian Holidays between 2001 and 2020
33
 *
34
 * @author Daniel Popiniuc
35
 */
36
trait Romanian
37
{
38
39
    /**
40
     *
41
     * @param int $year
42
     * @return type
43
     */
44
    private function getEasterDatetime($year)
45
    {
46
        $base = new \DateTime("$year-03-21");
47
        $days = easter_days($year);
48
        return $base->add(new \DateInterval("P{$days}D"));
49
    }
50
51
    /**
52
     * returns an array with non-standard holidays from a JSON file
53
     *
54
     * @param string $fileBaseName
55
     * @return mixed
56
     */
57
    protected function readTypeFromJsonFileUniversal($filePath, $fileBaseName)
58
    {
59
        $fName       = __DIR__ . DIRECTORY_SEPARATOR . $filePath . DIRECTORY_SEPARATOR . $fileBaseName . '.min.json';
60
        $fJson       = fopen($fName, 'r');
61
        $jSonContent = fread($fJson, filesize($fName));
62
        fclose($fJson);
63
        return json_decode($jSonContent, true);
64
    }
65
66
    /**
67
     * List of legal holidays
68
     *
69
     * @param \DateTime $lngDate
70
     * @param boolean $inclCatholicEaster
71
     * @return array
72
     */
73
    protected function setHolidays(\DateTime $lngDate, $inclCatholicEaster = false, $inclWorkingHolidays = false)
74
    {
75
        $givenYear = $lngDate->format('Y');
76
        $daying    = array_merge($this->setHolidaysOrthodoxEaster($lngDate), $this->setHolidaysFixed($lngDate));
77
        if ($inclWorkingHolidays) {
78
            $daying = array_merge($daying, $this->setHolidaysFixedButWorking($lngDate));
79
        }
80
        if ($inclCatholicEaster) { // Catholic easter is already known by PHP
81
            $firstEasterDate  = strtotime($this->getEasterDatetime($givenYear)->format('Y-m-d'));
82
            $secondEasterDate = strtotime('+1 day', $firstEasterDate);
83
            $daying           = array_merge($daying, [
84
                $firstEasterDate,
85
                $secondEasterDate,
86
            ]);
87
        }
88
        sort($daying);
89
        return array_unique($daying); // remove duplicate for when catholic and orthodox easter match
90
    }
91
92
    /**
93
     * List of all Romanian fixed holidays
94
     * (where fixed means every single year occur on same day of the month)
95
     *
96
     * @param \DateTime $lngDate
97
     * @return array
98
     */
99
    private function setHolidaysFixed(\DateTime $lngDate)
100
    {
101
        $givenYear = $lngDate->format('Y');
102
        $daying    = [
103
            mktime(0, 0, 0, 1, 1, $givenYear), // Happy New Year
104
            mktime(0, 0, 0, 1, 2, $givenYear), // recovering from New Year party
105
            mktime(0, 0, 0, 5, 1, $givenYear), // May 1st
106
            mktime(0, 0, 0, 12, 1, $givenYear), // Romanian National Day
107
            mktime(0, 0, 0, 12, 25, $givenYear), // Christmas Day
108
            mktime(0, 0, 0, 12, 26, $givenYear), // Christmas 2nd Day
109
        ];
110
        if ($givenYear >= 2009) {
111
            $daying[] = mktime(0, 0, 0, 8, 15, $givenYear); // St. Marry
112
        }
113
        if ($givenYear >= 2012) {
114
            $daying[] = mktime(0, 0, 0, 11, 30, $givenYear); // St. Andrew
115
        }
116
        sort($daying);
117
        return $daying;
118
    }
119
120
    /**
121
     * List of Romanian fixed holidays that are still working (weird ones)
122
     * (where fixed means every single year occur on same day of the month)
123
     *
124
     * @param \DateTime $lngDate
125
     * @return array
126
     */
127
    private function setHolidaysFixedButWorking(\DateTime $lngDate)
128
    {
129
        $daying    = [];
130
        $givenYear = $lngDate->format('Y');
131
        if ($givenYear >= 2015) {
132
            $daying[] = mktime(0, 0, 0, 1, 24, $givenYear); // Unirea Principatelor Romane
133
        }
134
        if ($givenYear >= 2016) {
135
            $daying[] = mktime(0, 0, 0, 2, 19, $givenYear); // Constantin Brancusi birthday
136
        }
137
        return $daying;
138
    }
139
140
    /**
141
     * List of all Orthodox holidays and Pentecost
142
     *
143
     * @param \DateTime $lngDate
144
     * @return array
145
     */
146
    private function setHolidaysOrthodoxEaster(\DateTime $lngDate)
147
    {
148
        $givenYear      = $lngDate->format('Y');
149
        $daying         = [];
150
        $statmentsArray = $this->readTypeFromJsonFileUniversal('json', 'RomanianBankHolidays');
151
        if (array_key_exists($givenYear, $statmentsArray)) {
152
            foreach ($statmentsArray[$givenYear] as $value) {
153
                $daying[] = strtotime($value);
154
            }
155
        }
156
        return $daying;
157
    }
158
159
    /**
160
     * returns bank holidays in a given month
161
     *
162
     * @param \DateTime $lngDate
163
     * @param boolean $inclCatholicEaster
164
     * @return int
165
     */
166
    protected function setHolidaysInMonth(\DateTime $lngDate, $inclCatholicEaster = false)
167
    {
168
        $holidaysInGivenYear = $this->setHolidays($lngDate, $inclCatholicEaster);
169
        $thisMonthDayArray   = $this->setMonthAllDaysIntoArray($lngDate);
170
        $holidays            = 0;
171
        foreach ($thisMonthDayArray as $value) {
172
            if (in_array($value, $holidaysInGivenYear)) {
173
                $holidays += 1;
174
            }
175
        }
176
        return $holidays;
177
    }
178
179
    /**
180
     * return an array with all days within a month from a given date
181
     *
182
     * @param \DateTime $lngDate
183
     * @return array
184
     */
185
    protected function setMonthAllDaysIntoArray(\DateTime $lngDate)
186
    {
187
        $firstDayGivenMonth  = strtotime($lngDate->modify('first day of this month')->format('Y-m-d'));
188
        $lastDayInGivenMonth = strtotime($lngDate->modify('last day of this month')->format('Y-m-d'));
189
        $secondsInOneDay     = 24 * 60 * 60;
190
        return range($firstDayGivenMonth, $lastDayInGivenMonth, $secondsInOneDay);
191
    }
192
193
    /**
194
     * returns working days in a given month
195
     *
196
     * @param \DateTime $lngDate
197
     * @param boolean $inclCatholicEaster
198
     * @return int
199
     */
200
    protected function setWorkingDaysInMonth(\DateTime $lngDate, $inclCatholicEaster = false)
201
    {
202
        $holidaysInGivenYear = $this->setHolidays($lngDate, $inclCatholicEaster);
203
        $thisMonthDayArray   = $this->setMonthAllDaysIntoArray($lngDate);
204
        $workingDays         = 0;
205
        foreach ($thisMonthDayArray as $value) {
206
            if (!in_array(strftime('%w', $value), [0, 6]) && !in_array($value, $holidaysInGivenYear)) {
207
                $workingDays += 1;
208
            }
209
        }
210
        return $workingDays;
211
    }
212
}
213