1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2019 webtrees development team 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17declare(strict_types=1); 18 19namespace Fisharebest\Webtrees\Date; 20 21use Fisharebest\ExtCalendar\JulianCalendar; 22use Fisharebest\Webtrees\I18N; 23 24/** 25 * Definitions for proleptic Julian dates. 26 */ 27class JulianDate extends AbstractGregorianJulianDate 28{ 29 // GEDCOM calendar escape 30 public const ESCAPE = '@#DJULIAN@'; 31 32 /** @var bool True for dates recorded in new-style/old-style format, e.g. 2 FEB 1743/44 */ 33 private $new_old_style = false; 34 35 /** 36 * Create a date from either: 37 * a Julian day number 38 * day/month/year strings from a GEDCOM date 39 * another CalendarDate object 40 * 41 * @param array|int|AbstractCalendarDate $date 42 */ 43 public function __construct($date) 44 { 45 $this->calendar = new JulianCalendar(); 46 parent::__construct($date); 47 } 48 49 /** 50 * Most years are 1 more than the previous, but not always (e.g. 1BC->1AD) 51 * 52 * @param int $year 53 * 54 * @return int 55 */ 56 protected function nextYear(int $year): int 57 { 58 if ($year === -1) { 59 return 1; 60 } 61 62 return $year + 1; 63 } 64 65 /** 66 * Process new-style/old-style years and years BC 67 * 68 * @param string $year 69 * 70 * @return int 71 */ 72 protected function extractYear(string $year): int 73 { 74 if (preg_match('/^(\d\d\d\d)\/\d{1,4}$/', $year, $match)) { 75 // Assume the first year is correct 76 $this->new_old_style = true; 77 78 return (int) $match[1] + 1; 79 } 80 81 if (preg_match('/^(\d+) B\.C\.$/', $year, $match)) { 82 return - (int) $match[1]; 83 } 84 85 return (int) $year; 86 } 87 88 /** 89 * Generate the %Y format for a date. 90 * 91 * @return string 92 */ 93 protected function formatLongYear(): string 94 { 95 if ($this->year < 0) { 96 return /* I18N: BCE=Before the Common Era, for Julian years < 0. See http://en.wikipedia.org/wiki/Common_Era */ 97 I18N::translate('%s BCE', I18N::digits(-$this->year)); 98 } 99 100 if ($this->new_old_style) { 101 return I18N::translate('%s CE', I18N::digits(sprintf('%d/%02d', $this->year - 1, $this->year % 100))); 102 } 103 104 /* I18N: CE=Common Era, for Julian years > 0. See http://en.wikipedia.org/wiki/Common_Era */ 105 return I18N::translate('%s CE', I18N::digits($this->year)); 106 } 107 108 /** 109 * Generate the %E format for a date. 110 * 111 * @return string 112 */ 113 protected function formatGedcomYear(): string 114 { 115 if ($this->year < 0) { 116 return sprintf('%04d B.C.', -$this->year); 117 } 118 119 if ($this->new_old_style) { 120 return sprintf('%04d/%02d', $this->year - 1, $this->year % 100); 121 } 122 123 return sprintf('%04d', $this->year); 124 } 125} 126