GregorianCalendar   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 124
Duplicated Lines 1.61 %

Coupling/Cohesion

Components 0
Dependencies 1

Importance

Changes 0
Metric Value
dl 2
loc 124
rs 10
c 0
b 0
f 0
wmc 18
lcom 0
cbo 1

5 Methods

Rating   Name   Duplication   Size   Complexity  
A gedcomCalendarEscape() 0 4 1
A isLeapYear() 0 8 4
A jdToYmd() 0 19 2
A ymdToJd() 2 16 4
B easterDays() 0 35 7

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
namespace Fisharebest\ExtCalendar;
3
4
use InvalidArgumentException;
5
6
/**
7
 * class GregorianCalendar - calculations for the (proleptic) Gregorian calendar.
8
 *
9
 * @author    Greg Roach <[email protected]>
10
 * @copyright (c) 2014-2020 Greg Roach
11
 * @license   This program is free software: you can redistribute it and/or modify
12
 *            it under the terms of the GNU General Public License as published by
13
 *            the Free Software Foundation, either version 3 of the License, or
14
 *            (at your option) any later version.
15
 *
16
 *            This program is distributed in the hope that it will be useful,
17
 *            but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 *            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 *            GNU General Public License for more details.
20
 *
21
 *            You should have received a copy of the GNU General Public License
22
 *            along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 */
24
class GregorianCalendar extends JulianCalendar implements CalendarInterface
25
{
26
    /**
27
     * The escape sequence used to indicate this calendar in GEDCOM files.
28
     *
29
     * @return string
30
     */
31
    public function gedcomCalendarEscape()
32
    {
33
        return '@#DGREGORIAN@';
34
    }
35
36
    /**
37
     * @param int $year
38
     *
39
     * @return bool
40
     */
41
    public function isLeapYear($year)
42
    {
43
        if ($year < 0) {
44
            $year++;
45
        }
46
47
        return $year % 4 == 0 && $year % 100 != 0 || $year % 400 == 0;
48
    }
49
50
    /**
51
     * Convert a Julian day number into a year/month/day.
52
     *
53
     * @param int $julian_day
54
     *
55
     * @return int[]
56
     */
57
    public function jdToYmd($julian_day)
58
    {
59
        $a = $julian_day + 32044;
60
        $b = (int) ((4 * $a + 3) / 146097);
61
        $c = $a - (int) ($b * 146097 / 4);
62
        $d = (int) ((4 * $c + 3) / 1461);
63
        $e = $c - (int) ((1461 * $d) / 4);
64
        $m = (int) ((5 * $e + 2) / 153);
65
66
        $day   = $e - (int) ((153 * $m + 2) / 5) + 1;
67
        $month = $m + 3 - 12 * (int) ($m / 10);
68
        $year  = $b * 100 + $d - 4800 + (int) ($m / 10);
69
        if ($year < 1) {
70
            // 0 is 1 BCE, -1 is 2 BCE, etc.
71
            $year--;
72
        }
73
74
        return array($year, $month, $day);
75
    }
76
77
    /**
78
     * Convert a year/month/day into a Julian day number
79
     *
80
     * @param int $year
81
     * @param int $month
82
     * @param int $day
83
     *
84
     * @return int
85
     */
86
    public function ymdToJd($year, $month, $day)
87
    {
88 View Code Duplication
        if ($month < 1 || $month > $this->monthsInYear()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
89
            throw new InvalidArgumentException('Month ' . $month . ' is invalid for this calendar');
90
        }
91
92
        if ($year < 0) {
93
            // 1 BCE is 0, 2 BCE is -1, etc.
94
            ++$year;
95
        }
96
        $a     = (int) ((14 - $month) / 12);
97
        $year  = $year + 4800 - $a;
98
        $month = $month + 12 * $a - 3;
99
100
        return $day + (int) ((153 * $month + 2) / 5) + 365 * $year + (int) ($year / 4) - (int) ($year / 100) + (int) ($year / 400) - 32045;
101
    }
102
103
    /**
104
     * Get the number of days after March 21 that easter falls, for a given year.
105
     *
106
     * Uses the algorithm found in PHP’s ext/calendar/easter.c
107
     *
108
     * @param int $year
109
     *
110
     * @return int
111
     */
112
    public function easterDays($year)
113
    {
114
        // The “golden” number
115
        $golden = $year % 19 + 1;
116
117
        // The “dominical” number (finding a Sunday)
118
        $dom = ($year + (int) ($year / 4) - (int) ($year / 100) + (int) ($year / 400)) % 7;
119
        if ($dom < 0) {
120
            $dom += 7;
121
        }
122
123
        // The solar correction
124
        $solar = (int) (($year - 1600) / 100) - (int) (($year - 1600) / 400);
125
126
        // The lunar correction
127
        $lunar = (int) ((int) (($year - 1400) / 100) * 8) / 25;
128
129
        // The uncorrected “Paschal full moon” date
130
        $pfm = (3 - 11 * $golden + $solar - $lunar) % 30;
131
        if ($pfm < 0) {
132
            $pfm += 30;
133
        }
134
135
        // The corrected “Paschal full moon” date
136
        if ($pfm === 29 || $pfm === 28 && $golden > 11) {
137
            $pfm--;
138
        }
139
140
        $tmp = (4 - $pfm - $dom) % 7;
141
        if ($tmp < 0) {
142
            $tmp += 7;
143
        }
144
145
        return $pfm + $tmp + 1;
146
    }
147
}
148