@@ -183,7 +183,7 @@ public static function validateDate($datetime_str, $strict = FALSE) {
183
183
$ msgs = [];
184
184
185
185
if (strpos ($ datetime_str , 'T ' ) > -1 ) {
186
- list ( $ date , $ time) = explode ('T ' , $ datetime_str );
186
+ [ $ date , $ time] = explode ('T ' , $ datetime_str );
187
187
}
188
188
else {
189
189
$ date = (string ) $ datetime_str ;
@@ -216,22 +216,29 @@ public static function validateDate($datetime_str, $strict = FALSE) {
216
216
elseif (strlen (ltrim ($ parsed_date [self ::YEAR_BASE ], '- ' )) > 4 ) {
217
217
$ msgs [] = "Years longer than 4 digits must be prefixed with a 'Y'. " ;
218
218
}
219
- elseif (strlen ($ parsed_date [self ::YEAR_BASE ]) < 4 ) {
220
- $ msgs [] = "Years must be at least 4 characters long. " ;
221
- }
222
219
$ strict_pattern = 'Y ' ;
223
220
224
221
// Month.
225
222
if (array_key_exists (self ::MONTH , $ parsed_date ) && !empty ($ parsed_date [self ::MONTH ])) {
226
223
// Valid month values?
227
224
if (
228
- // Month doesn't exist in mapping or does exist in mapping, but is > 12
229
- // and there is a day part.
230
- (!array_key_exists ($ parsed_date [self ::MONTH ], self ::MONTHS_MAP ) ||
231
- (array_key_exists ($ parsed_date [self ::MONTH ], self ::MONTHS_MAP ) &&
232
- array_key_exists (self ::DAY , $ parsed_date ) &&
233
- $ parsed_date [self ::MONTH ] > 12 )) &&
234
- strpos ($ parsed_date [self ::MONTH ], 'X ' ) === FALSE ) {
225
+ // Month doesn't exist in mapping
226
+ // and isn't a valid unspecified month value.
227
+ (
228
+ !array_key_exists ($ parsed_date [self ::MONTH ], self ::MONTHS_MAP ) &&
229
+ (intval (str_replace ('X ' , '1 ' , $ parsed_date [self ::MONTH ])) > 12 )
230
+ ) ||
231
+ // Sub-year groupings with day values.
232
+ (
233
+ array_key_exists ($ parsed_date [self ::MONTH ], self ::MONTHS_MAP ) &&
234
+ array_key_exists (self ::DAY , $ parsed_date ) &&
235
+ $ parsed_date [self ::MONTH ] > 12
236
+ ) ||
237
+ // Unspecifed character comes before number.
238
+ (
239
+ preg_match ('/X+\d/ ' , $ parsed_date [self ::MONTH ])
240
+ )
241
+ ) {
235
242
$ msgs [] = "Provided month value ' " . $ parsed_date [self ::MONTH ] . "' is not valid. " ;
236
243
}
237
244
$ strict_pattern = 'Y-m ' ;
@@ -327,8 +334,28 @@ public static function expandYear($year_full, $year_base, $year_exponent) {
327
334
*/
328
335
public static function iso8601Value (string $ edtf ) {
329
336
337
+ if (count (self ::validate ($ edtf )) > 0 ) {
338
+ return '' ;
339
+ }
340
+ // Sets.
341
+ if (strpos ($ edtf , '[ ' ) !== FALSE || strpos ($ edtf , '{ ' ) !== FALSE ) {
342
+ // Use first in set.
343
+ $ dates = preg_split ('/(,|\.\.)/ ' , trim ($ edtf , '{}[] ' ));
344
+ return self ::iso8601Value (array_shift ($ dates ));
345
+ }
346
+ // Intervals.
347
+ if (str_contains ($ edtf , '/ ' )) {
348
+ $ dates = explode ('/ ' , $ edtf );
349
+ return self ::iso8601Value (array_shift ($ dates ));
350
+ }
351
+
330
352
$ date_time = explode ('T ' , $ edtf );
331
353
354
+ // Valid EDTF values with time portions are already ISO 8601 timestamps.
355
+ if (array_key_exists (1 , $ date_time ) && !empty ($ date_time [1 ])) {
356
+ return $ edtf ;
357
+ }
358
+
332
359
preg_match (EDTFUtils::DATE_PARSE_REGEX , $ date_time [0 ], $ parsed_date );
333
360
334
361
$ year = '' ;
@@ -358,17 +385,7 @@ public static function iso8601Value(string $edtf) {
358
385
$ day = str_replace ('X ' , '0 ' , $ day );
359
386
}
360
387
361
- $ formatted_date = implode ('- ' , array_filter ([$ year , $ month , $ day ]));
362
-
363
- // Time.
364
- if (array_key_exists (1 , $ date_time ) && !empty ($ date_time [1 ])) {
365
- $ formatted_date .= 'T ' . $ date_time [1 ];
366
- }
367
- else {
368
- $ formatted_date .= 'T00:00:00 ' ;
369
- }
370
-
371
- return $ formatted_date ;
388
+ return implode ('- ' , array_filter ([$ year , $ month , $ day ]));
372
389
373
390
}
374
391
0 commit comments