4
4
5
5
use DataValues \IllegalValueException ;
6
6
use DataValues \TimeValue ;
7
+ use ValueParsers \CalendarModelParser ;
8
+ use ValueParsers \IsoTimestampParser ;
7
9
use ValueParsers \ParseException ;
8
10
use ValueParsers \ParserOptions ;
9
11
use ValueParsers \StringValueParser ;
@@ -44,6 +46,9 @@ class DateFormatParser extends StringValueParser {
44
46
*/
45
47
public const OPT_PRECISION = 'precision ' ;
46
48
49
+ /** @var IsoTimestampParser */
50
+ private $ isoTimestampParser ;
51
+
47
52
public function __construct ( ParserOptions $ options = null ) {
48
53
parent ::__construct ( $ options );
49
54
@@ -52,6 +57,11 @@ public function __construct( ParserOptions $options = null ) {
52
57
$ this ->defaultOption ( self ::OPT_DIGIT_TRANSFORM_TABLE , null );
53
58
$ this ->defaultOption ( self ::OPT_MONTH_NAMES , null );
54
59
$ this ->defaultOption ( self ::OPT_PRECISION , null );
60
+
61
+ $ this ->isoTimestampParser = new IsoTimestampParser (
62
+ new CalendarModelParser ( $ this ->options ),
63
+ $ this ->options
64
+ );
55
65
}
56
66
57
67
/**
@@ -109,8 +119,14 @@ protected function stringParse( $value ) {
109
119
110
120
$ timestamp = vsprintf ( '+%04s-%02s-%02sT%02s:%02s:%02sZ ' , $ time );
111
121
122
+ // Use IsoTimestampParser to detect the correct calendar model.
123
+ $ iso = $ this ->isoTimestampParser ->parse ( $ timestamp );
124
+
112
125
try {
113
- return new TimeValue ( $ timestamp , 0 , 0 , 0 , $ precision , TimeValue::CALENDAR_GREGORIAN );
126
+ // We intentionally do not re-use the precision from IsoTimestampParser here,
127
+ // because it reduces precision for values with zeros in the right-most fields.
128
+ // Our above method of determining the precision is therefore better.
129
+ return new TimeValue ( $ timestamp , 0 , 0 , 0 , $ precision , $ iso ->getCalendarModel () );
114
130
} catch ( IllegalValueException $ ex ) {
115
131
throw new ParseException ( $ ex ->getMessage (), $ value , self ::FORMAT_NAME );
116
132
}
0 commit comments