diff options
| author | Greg Roach <fisharebest@gmail.com> | 2014-09-13 13:26:26 +0100 |
|---|---|---|
| committer | Greg Roach <fisharebest@gmail.com> | 2014-09-13 13:26:26 +0100 |
| commit | 7630cce493bb9b4657907c5ab9da28069c587f5a (patch) | |
| tree | a4ab8b8863f8cef72446d0e849fc9ba4a85432a3 /library/fisharebest/ext-calendar/src/JulianCalendar.php | |
| parent | ed0b0fe23f53f3ab89c14f7029f1683abc969d25 (diff) | |
| download | webtrees-7630cce493bb9b4657907c5ab9da28069c587f5a.tar.gz webtrees-7630cce493bb9b4657907c5ab9da28069c587f5a.tar.bz2 webtrees-7630cce493bb9b4657907c5ab9da28069c587f5a.zip | |
Remove dependency on PHP's ext/calendar extension, and use our own
Diffstat (limited to 'library/fisharebest/ext-calendar/src/JulianCalendar.php')
| -rw-r--r-- | library/fisharebest/ext-calendar/src/JulianCalendar.php | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/library/fisharebest/ext-calendar/src/JulianCalendar.php b/library/fisharebest/ext-calendar/src/JulianCalendar.php new file mode 100644 index 0000000000..c74e82cda2 --- /dev/null +++ b/library/fisharebest/ext-calendar/src/JulianCalendar.php @@ -0,0 +1,179 @@ +<?php +namespace Fisharebest\ExtCalendar; + +/** + * class JulianCalendar - calculations for the Julian calendar. + * + * @author Greg Roach <fisharebest@gmail.com> + * @copyright (c) 2014 Greg Roach + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +class JulianCalendar extends Calendar implements CalendarInterface { + /** Same as PHP’s ext/calendar extension */ + const PHP_CALENDAR_NAME = 'Julian'; + + /** Same as PHP’s ext/calendar extension */ + const PHP_CALENDAR_NUMBER = 1; + + /** Same as PHP’s ext/calendar extension */ + const PHP_CALENDAR_SYMBOL = 'CAL_JULIAN'; + + /** See the GEDCOM specification */ + const GEDCOM_CALENDAR_ESCAPE = '@#DJULIAN@'; + + /** + * Month lengths for regular years and leap-years. + * + * @var int[][] + */ + protected static $DAYS_IN_MONTH = array( + 0 => array(1 => 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31), + 1 => array(1 => 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31), + ); + + /** + * English month names. + * + * @return string[] + */ + public function monthNames() { + return array( + 1 => 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', + ); + } + + /** + * Abbreviated English month names. + * + * @return string[] + */ + public function monthNamesAbbreviated() { + return array( + 1 => 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', + ); + } + + + /** + * Determine whether a year is a leap year. + * + * @param int $year + * @return bool + */ + public function leapYear($year) { + if ($year < 0) { + $year++; + } + + return $year % 4 == 0; + } + + /** + * Convert a Julian day number into a year/month/day. + * + * @param $jd + * + * @return int[]; + */ + public function jdToYmd($jd) { + $c = $jd + 32082; + $d = (int)((4 * $c + 3) / 1461); + $e = $c - (int)(1461 * $d / 4); + $m = (int)((5 * $e + 2) / 153); + $day = $e - (int)((153 * $m + 2) / 5) + 1; + $month = $m + 3 - 12 * (int)($m / 10); + $year = $d - 4800 + (int)($m / 10); + if ($year < 1) { + // 0=1BC, -1=2BC, etc. + $year--; + } + + return array($year, $month, $day); + } + + /** + * Convert a year/month/day into a Julian day number + * + * @param int $year + * @param int $month + * @param int $day + * + * @return int + */ + public function ymdToJd($year, $month, $day) { + if ($year < 0) { + // 1 B.C.E. => 0, 2 B.C.E> => 1, etc. + ++$year; + } + $a = (int)((14 - $month) / 12); + $year = $year + 4800 - $a; + $month = $month + 12 * $a - 3; + + return $day + (int)((153 * $month + 2) / 5) + 365 * $year + (int)($year / 4) - 32083; + } + + /** + * Calculate the number of days in a month. + * + * @param int $year + * @param int $month + * + * @return int + */ + public function daysInMonth($year, $month) { + if ($year == 0 || $month < 1 || $month > 12) { + return trigger_error('invalid date.', E_USER_WARNING); + } else { + return static::$DAYS_IN_MONTH[$this->leapYear($year)][$month]; + } + } + + /** + * Get the number of days after March 21 that easter falls, for a given year. + * + * Uses the algorithm found in PHP’s ext/calendar/easter.c + * + * @param int $year + * + * @return int + */ + public function easterDays($year) { + // The “golden” number + $golden = 1 + $year % 19; + + // The “dominical” number (finding a Sunday) + $dom = ($year + (int)($year / 4) + 5) % 7; + if ($dom < 0) { + $dom += 7; + } + + // The uncorrected “Paschal full moon” date + $pfm = (3 - 11 * $golden - 7) % 30; + if ($pfm < 0) { + $pfm += 30; + } + + // The corrected “Paschal full moon” date + if ($pfm == 29 || $pfm == 28 && $golden > 11) { + $pfm--; + } + + $tmp = (4 - $pfm - $dom) % 7; + if ($tmp < 0) { + $tmp += 7; + } + + return $pfm + $tmp + 1; + } +} |
