xref: /webtrees/app/Date/JulianDate.php (revision 6bdf767435631ad1dc27ec1ffd855d43dbdce907)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2017 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 */
16namespace Fisharebest\Webtrees\Date;
17
18use Fisharebest\ExtCalendar\JulianCalendar;
19use Fisharebest\Webtrees\I18N;
20
21/**
22 * Definitions for the Julian Proleptic calendar
23 * (Proleptic means we extend it backwards, prior to its introduction in 46BC)
24 */
25class JulianDate extends CalendarDate {
26	/** @var bool True for dates recorded in new-style/old-style format, e.g. 2 FEB 1743/44 */
27	private $new_old_style = false;
28
29	/**
30	 * Create a date from either:
31	 * a Julian day number
32	 * day/month/year strings from a GEDCOM date
33	 * another CalendarDate object
34	 *
35	 * @param array|int|CalendarDate $date
36	 */
37	public function __construct($date) {
38		$this->calendar = new JulianCalendar;
39		parent::__construct($date);
40	}
41
42	/**
43	 * Most years are 1 more than the previous, but not always (e.g. 1BC->1AD)
44	 *
45	 * @param int $year
46	 *
47	 * @return int
48	 */
49	protected function nextYear($year) {
50		if ($year == -1) {
51			return 1;
52		} else {
53			return $year + 1;
54		}
55	}
56
57	/**
58	 * Process new-style/old-style years and years BC
59	 *
60	 * @param string $year
61	 *
62	 * @return int
63	 */
64	protected function extractYear($year) {
65		if (preg_match('/^(\d\d\d\d)\/\d{1,4}$/', $year, $match)) {
66			// Assume the first year is correct
67			$this->new_old_style = true;
68
69			return $match[1] + 1;
70		} elseif (preg_match('/^(\d+) B\.C\.$/', $year, $match)) {
71			return -$match[1];
72		} else {
73			return (int) $year;
74		}
75	}
76
77	/**
78	 * Generate the %Y format for a date.
79	 *
80	 * @return string
81	 */
82	protected function formatLongYear() {
83		if ($this->y < 0) {
84			return /*  I18N: BCE=Before the Common Era, for Julian years < 0. See http://en.wikipedia.org/wiki/Common_Era */
85				I18N::translate('%s&nbsp;BCE', I18N::digits(-$this->y));
86		} else {
87			if ($this->new_old_style) {
88				return I18N::translate('%s&nbsp;CE', I18N::digits(sprintf('%d/%02d', $this->y - 1, $this->y % 100)));
89			} else {
90				return /* I18N: CE=Common Era, for Julian years > 0. See http://en.wikipedia.org/wiki/Common_Era */
91					I18N::translate('%s&nbsp;CE', I18N::digits($this->y));
92			}
93		}
94	}
95
96	/**
97	 * Generate the %E format for a date.
98	 *
99	 * @return string
100	 */
101	protected function formatGedcomYear() {
102		if ($this->y < 0) {
103			return sprintf('%04d B.C.', -$this->y);
104		} else {
105			if ($this->new_old_style) {
106				return sprintf('%04d/%02d', $this->y - 1, $this->y % 100);
107			} else {
108				return sprintf('%04d', $this->y);
109			}
110		}
111	}
112}
113