Completed
Push — main ( 4395cf...13cc11 )
by Andreas
01:51
created

CalendarDay::setGregorianYear()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Copyright (c) Andreas Heigl<[email protected]>
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated documentation files (the "Software"), to deal
10
 * in the Software without restriction, including without limitation the rights
11
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
 * copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
 * THE SOFTWARE.
25
 *
26
 * @author    Andreas Heigl<[email protected]>
27
 * @copyright Andreas Heigl
28
 * @license   http://www.opensource.org/licenses/mit-license.php MIT-License
29
 * @since     20.02.2018
30
 * @link      http://github.com/heiglandreas/org.heigl.Holidaychecker
31
 */
32
33
namespace Org_Heigl\Holidaychecker;
34
35
use DateTimeInterface;
36
use IntlCalendar;
37
38
class CalendarDay
39
{
40
    /** @var int */
41
    private $day;
42
43
    /** @var int */
44
    private $month;
45
46
    /** @var int|null */
47
    private $year;
48
49
    /** @var IntlCalendar */
50
    private $calendar;
51
52
    public function __construct(int $day, int $month, IntlCalendar $calendar)
53
    {
54
        $this->day      = $day;
55
        $this->month    = $month;
56
        $this->year     = null;
57
        $this->calendar = $calendar;
58
        $this->calendar->set(IntlCalendar::FIELD_DAY_OF_MONTH, $day);
59
        $this->calendar->set(IntlCalendar::FIELD_MONTH, $month - 1);
60
        $this->calendar->set(IntlCalendar::FIELD_HOUR_OF_DAY, 12);
61
        $this->calendar->set(IntlCalendar::FIELD_MINUTE, 0);
62
        $this->calendar->set(IntlCalendar::FIELD_SECOND, 0);
63
        $this->calendar->set(IntlCalendar::FIELD_MILLISECOND, 0);
64
    }
65
66
    public function setYear(int $year): void
67
    {
68
        $this->year = $year;
69
        $this->calendar->set(IntlCalendar::FIELD_YEAR, $year);
70
    }
71
72
    public function setGregorianYear(int $year): void
73
    {
74
        $calendarYear = (int) $this->calendar->toDateTime()->format('Y');
75
76
        $diff = $year - $calendarYear;
77
        $realYear = $this->calendar->get(IntlCalendar::FIELD_YEAR);
78
79
        $this->year = $realYear + $diff;
80
        $this->calendar->add(IntlCalendar::FIELD_YEAR, $diff);
81
    }
82
83
    public function isSameDay(DateTimeInterface $dateTime): bool
84
    {
85
        $cal         = clone $this->calendar;
86
        $cal->setTime($dateTime->getTimestamp() * 1000);
87
88
        if (null !== $this->year &&
89
            $cal->get(IntlCalendar::FIELD_YEAR) !== $this->calendar->get(IntlCalendar::FIELD_YEAR)
90
        ) {
91
            return false;
92
        }
93
94
        if ($cal->get(IntlCalendar::FIELD_MONTH) !== $this->calendar->get(IntlCalendar::FIELD_MONTH)) {
95
            return false;
96
        }
97
98
        return $cal->get(IntlCalendar::FIELD_DAY_OF_MONTH) === $this->calendar->get(IntlCalendar::FIELD_DAY_OF_MONTH);
99
    }
100
101
    public function isFollowUpDay(DateTimeInterface $dateTime, string $followUpDay): bool
102
    {
103
        $cal = clone $this->calendar;
104
        $cal->set(IntlCalendar::FIELD_YEAR, (int) $dateTime->format('Y'));
105
        $day = $cal->toDateTime();
106
        $day->modify('next ' . $followUpDay);
107
        $cal->setTime($day->getTimestamp() * 1000);
108
        $cal2         = clone $this->calendar;
109
        $cal2->setTime($dateTime->getTimestamp() * 1000);
110
111
        if (null !== $this->year && $cal->get(IntlCalendar::FIELD_YEAR) !== $cal2->get(IntlCalendar::FIELD_YEAR)) {
112
            return false;
113
        }
114
115
        if ($cal->get(IntlCalendar::FIELD_MONTH) !== $cal2->get(IntlCalendar::FIELD_MONTH)) {
116
            return false;
117
        }
118
119
        return $cal->get(IntlCalendar::FIELD_DAY_OF_MONTH) === $cal2->get(IntlCalendar::FIELD_DAY_OF_MONTH);
120
    }
121
122
    public function getWeekdayForGregorianYear(int $year): int
123
    {
124
        $cal = $this->getDayForGregorianYear($year);
125
126
        return $cal->get(IntlCalendar::FIELD_DAY_OF_WEEK);
127
    }
128
129
    private function getDayForGregorianYear(int $gregorianYear): IntlCalendar
130
    {
131
        $cal = clone $this->calendar;
132
133
        $datetime = $cal->toDateTime();
134
        $yearDiff = $gregorianYear - (int) $datetime->format('Y');
135
        $cal->set(IntlCalendar::FIELD_YEAR, $cal->get(IntlCalendar::FIELD_YEAR) + $yearDiff);
136
        $cal->set(IntlCalendar::FIELD_MONTH, $this->month - 1);
137
        $cal->set(IntlCalendar::FIELD_DAY_OF_MONTH, $this->day);
138
139
        return $cal;
140
    }
141
}
142