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