Completed
Push — master ( 6fde37...d12889 )
by
unknown
02:24
created

YearTimeParser   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 5
c 1
b 0
f 0
lcom 1
cbo 6
dl 0
loc 74
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 2
A stringParse() 0 20 3
1
<?php
2
3
namespace ValueParsers;
4
5
use DataValues\TimeValue;
6
7
/**
8
 * A straight parser that accepts various strings representing a year, and only a year. Accepts
9
 * years before common era as well as optional thousands separators. Should be called after
10
 * YearMonthTimeParser when you want to accept both formats, because strings like "1 999" may either
11
 * represent a month and a year or a year with digit grouping.
12
 *
13
 * @since 0.8.4
14
 *
15
 * @license GPL-2.0+
16
 * @author Addshore
17
 * @author Thiemo Mättig
18
 */
19
class YearTimeParser extends StringValueParser {
20
21
	const FORMAT_NAME = 'year';
22
23
	/**
24
	 * Option to allow parsing of years with localized digit group separators. For example, the
25
	 * English year -10,000 (with a comma) is written as -10.000 (with a dot) in German.
26
	 */
27
	const OPT_DIGIT_GROUP_SEPARATOR = 'digitGroupSeparator';
28
29
	/**
30
	 * Default, canonical digit group separator, as in the year -10,000.
31
	 */
32
	const CANONICAL_DIGIT_GROUP_SEPARATOR = ',';
33
34
	/**
35
	 * @var ValueParser
36
	 */
37
	private $eraParser;
38
39
	/**
40
	 * @var ValueParser
41
	 */
42
	private $isoTimestampParser;
43
44
	/**
45
	 * @param ValueParser|null $eraParser
46
	 * @param ParserOptions|null $options
47
	 */
48
	public function __construct( ValueParser $eraParser = null, ParserOptions $options = null ) {
49
		parent::__construct( $options );
50
51
		$this->defaultOption(
52
			self::OPT_DIGIT_GROUP_SEPARATOR,
53
			self::CANONICAL_DIGIT_GROUP_SEPARATOR
54
		);
55
56
		$this->eraParser = $eraParser ?: new EraParser( $this->options );
57
		$this->isoTimestampParser = new IsoTimestampParser(
58
			new CalendarModelParser( $this->options ),
59
			$this->options
60
		);
61
	}
62
63
	/**
64
	 * Parses the provided string and returns the result.
65
	 *
66
	 * @param string $value
67
	 *
68
	 * @throws ParseException
69
	 * @return TimeValue
70
	 */
71
	protected function stringParse( $value ) {
72
		list( $sign, $year ) = $this->eraParser->parse( $value );
73
74
		// Negative dates usually don't have a month, assume non-digits are thousands separators
75
		if ( $sign === '-' ) {
76
			$separator = $this->getOption( self::OPT_DIGIT_GROUP_SEPARATOR );
77
			// Always accept ISO (e.g. "1 000 BC") as well as programming style (e.g. "-1_000")
78
			$year = preg_replace(
79
				'/(?<=\d)[' . preg_quote( $separator, '/' ) . '\s_](?=\d)/',
80
				'',
81
				$year
82
			);
83
		}
84
85
		if ( !preg_match( '/^\d+$/', $year ) ) {
86
			throw new ParseException( 'Failed to parse year', $value, self::FORMAT_NAME );
87
		}
88
89
		return $this->isoTimestampParser->parse( $sign . $year . '-00-00T00:00:00Z' );
90
	}
91
92
}
93