@@ -231,26 +231,39 @@ protected function formatDate($edtf_text) {
231
231
}
232
232
233
233
// Unspecified.
234
- $ unspecified = [];
234
+ $ unspecified = [
235
+ 'fullyear ' => FALSE ,
236
+ 'year ' => FALSE ,
237
+ 'century ' => FALSE ,
238
+ 'decade ' => FALSE ,
239
+ 'month ' => FALSE ,
240
+ 'day ' => FALSE ,
241
+ ];
242
+ $ unspecified_count = 0 ;
243
+
235
244
if (strpos ($ parsed_date [EDTFUtils::YEAR_BASE ], 'XXXX ' ) !== FALSE ) {
236
- $ unspecified [] = t ('year ' );
245
+ $ unspecified ['fullyear ' ] = TRUE ;
246
+ $ unspecified_count ++;
237
247
}
238
248
elseif (strpos ($ parsed_date [EDTFUtils::YEAR_BASE ], 'XXX ' ) !== FALSE ) {
239
- $ unspecified [] = t ('century ' );
249
+ $ unspecified ['century ' ] = TRUE ;
250
+ $ unspecified_count ++;
240
251
}
241
252
elseif (strpos ($ parsed_date [EDTFUtils::YEAR_BASE ], 'XX ' ) !== FALSE ) {
242
- $ unspecified [] = t ('decade ' );
253
+ $ unspecified ['decade ' ] = TRUE ;
254
+ $ unspecified_count ++;
243
255
}
244
256
elseif (strpos ($ parsed_date [EDTFUtils::YEAR_BASE ], 'X ' ) !== FALSE ) {
245
- $ unspecified [] = t ('year ' );
257
+ $ unspecified ['year ' ] = TRUE ;
258
+ $ unspecified_count ++;
246
259
}
247
- // Clean-up unspecified year/decade.
248
- $ year = str_replace ( ' X ' , ' 0 ' , $ parsed_date [EDTFUtils::YEAR_BASE ]) ;
260
+
261
+ $ year = $ parsed_date [EDTFUtils::YEAR_BASE ];
249
262
250
263
if (array_key_exists (EDTFUtils::MONTH , $ parsed_date )) {
251
264
if (strpos ($ parsed_date [EDTFUtils::MONTH ], 'X ' ) !== FALSE ) {
252
- $ unspecified [] = t ( ' month ' ) ;
253
- // Month remains blank for output.
265
+ $ unspecified [' month ' ] = TRUE ;
266
+ $ unspecified_count ++;
254
267
}
255
268
elseif ($ settings ['month_format ' ] === 'mmm ' || $ settings ['month_format ' ] === 'mmmm ' ) {
256
269
$ month = EDTFUtils::MONTHS_MAP [$ parsed_date [EDTFUtils::MONTH ]][$ settings ['month_format ' ]];
@@ -269,7 +282,8 @@ protected function formatDate($edtf_text) {
269
282
270
283
if (array_key_exists (EDTFUtils::DAY , $ parsed_date )) {
271
284
if (strpos ($ parsed_date [EDTFUtils::DAY ], 'X ' ) !== FALSE ) {
272
- $ unspecified [] = t ('day ' );
285
+ $ unspecified ['day ' ] = TRUE ;
286
+ $ unspecified_count ++;
273
287
}
274
288
elseif ($ settings ['day_format ' ] === 'd ' ) {
275
289
$ day = ltrim ($ parsed_date [EDTFUtils::DAY ], ' 0 ' );
@@ -294,6 +308,32 @@ protected function formatDate($edtf_text) {
294
308
}
295
309
}
296
310
311
+ // Replace Xs with 0s and format date parts.
312
+ if ($ unspecified_count > 0 ) {
313
+ if (strpos ($ year , 'X ' ) !== FALSE ) {
314
+ $ year = str_replace ('X ' , '0 ' , $ year ) . 's ' ;
315
+ }
316
+
317
+ if ($ unspecified ['fullyear ' ]) {
318
+ $ year = 'unknown year ' ;
319
+ }
320
+ elseif ($ unspecified ['year ' ]) {
321
+ $ year = "unknown year in the decade of the $ year " ;
322
+ }
323
+ elseif ($ unspecified ['decade ' ]) {
324
+ $ year = "unknown year in the century of the $ year " ;
325
+ }
326
+ elseif ($ unspecified ['century ' ]) {
327
+ $ year = "unknown year in the millennium of the $ year " ;
328
+ }
329
+ if ($ unspecified ['month ' ]) {
330
+ $ month = 'unknown month ' ;
331
+ }
332
+ if ($ unspecified ['day ' ]) {
333
+ $ day = 'unknown day ' ;
334
+ }
335
+ }
336
+
297
337
// Put the parts back together.
298
338
if ($ settings ['date_order ' ] === 'little_endian ' ) {
299
339
$ parts_in_order = [$ day , $ month , $ year ];
@@ -306,15 +346,111 @@ protected function formatDate($edtf_text) {
306
346
$ parts_in_order = [$ year , $ month , $ day ];
307
347
}
308
348
309
- // Special case for dates such as "Dec 29, 2021".
349
+ // Special cases for middle endian dates with spaces and months spelled out.
350
+ // Full dates will have a comma before the year, like January 1, 1999.
351
+ // Dates with Xs in them will be written out more verbosely.
352
+ $ d = intval ($ day );
353
+ $ day_suffix = date ('S ' , mktime (1 , 1 , 1 , 1 , ((($ d >= 10 ) + ($ d >= 20 ) + ($ d == 0 )) * 10 + $ d % 10 )));
310
354
if ($ settings ['date_order ' ] === 'middle_endian ' &&
311
355
!preg_match ('/\d/ ' , $ month ) &&
312
356
self ::DELIMITERS [$ settings ['date_separator ' ]] == ' ' &&
313
- count (array_filter ([$ year , $ day ])) == 2 ) {
314
- $ formatted_date = "$ month $ day, $ year " ;
357
+ count (array_filter ([$ month , $ day ])) > 0 ) {
358
+ // Unknown year only.
359
+ if (!$ unspecified ['day ' ] && !$ unspecified ['month ' ] && $ unspecified_count === 1 ) {
360
+ $ formatted_date = t ("@md, of an @year " , [
361
+ "@md " => trim ("$ month $ day " ),
362
+ "@year " => $ year ,
363
+ ]);
364
+ }
365
+ // Unknown month only.
366
+ elseif ($ unspecified ['month ' ] && $ unspecified_count === 1 ) {
367
+ if ($ day !== '' ) {
368
+ $ day .= "$ day_suffix day of an " ;
369
+ }
370
+ $ formatted_date = t ("@dm, in @year " , [
371
+ "@dm " => trim ("$ day $ month " ),
372
+ "@year " => $ year ,
373
+ ]);
374
+ }
375
+ // Unknown day only.
376
+ elseif ($ unspecified ['day ' ] && $ unspecified_count === 1 ) {
377
+ $ formatted_date = t ("@day in @month, @year " , [
378
+ "@day " => $ day ,
379
+ "@month " => $ month ,
380
+ "@year " => $ year ,
381
+ ]);
382
+ }
383
+ // Unknown year and month only.
384
+ elseif (!$ unspecified ['day ' ] && $ unspecified_count === 2 ) {
385
+ if ($ day !== '' ) {
386
+ $ day .= "$ day_suffix day of an " ;
387
+ }
388
+ if ($ year == 'unknown year ' ) {
389
+ $ formatted_date = t ("@day @month, in an @year " , [
390
+ "@day " => $ day ,
391
+ "@month " => $ month ,
392
+ "@year " => $ year ,
393
+ ]);
394
+ }
395
+ else {
396
+ $ formatted_date = t ("@dm, in the @year " , [
397
+ "@dm " => trim ("$ day $ month " ),
398
+ "@year " => str_replace ('unknown year in the ' , '' , $ year ),
399
+ ]);
400
+ }
401
+ }
402
+ // Unknown year and day only.
403
+ elseif (!$ unspecified ['month ' ] && $ unspecified_count === 2 ) {
404
+ if ($ year == 'unknown year ' ) {
405
+ $ formatted_date = t ("@day in @month, in an @year " , [
406
+ "@day " => $ day ,
407
+ "@month " => $ month ,
408
+ "@year " => $ year ,
409
+ ]);
410
+ }
411
+ else {
412
+ $ formatted_date = t ("@day in @month, in the @year " , [
413
+ "@day " => $ day ,
414
+ "@month " => $ month ,
415
+ "@year " => str_replace ('unknown year in the ' , '' , $ year ),
416
+ ]);
417
+ }
418
+ }
419
+ // Unknown day and month only.
420
+ elseif ($ unspecified ['day ' ] && $ unspecified ['month ' ] && $ unspecified_count === 2 ) {
421
+ $ formatted_date = t ("Unknown date, in @year " , [
422
+ "@year " => $ year ,
423
+ ]);
424
+ }
425
+ // Unknown year, month, and day.
426
+ elseif ($ unspecified_count === 3 ) {
427
+ if ($ year == 'unknown year ' ) {
428
+ $ formatted_date = t ("Unknown day, month, and year " );
429
+ }
430
+ else {
431
+ $ formatted_date = t ("Unknown date, in the @year " , [
432
+ "@year " => str_replace ('unknown year in the ' , '' , $ year ),
433
+ ]);
434
+ }
435
+ }
436
+ // No unknown segments.
437
+ // Adds a comma after the month & day.
438
+ else {
439
+ $ formatted_date = t ("@md, @year " , [
440
+ "@md " => trim ("$ month $ day " ),
441
+ "@year " => $ year ,
442
+ ]);
443
+ }
315
444
}
316
445
else {
317
- $ formatted_date = implode (self ::DELIMITERS [$ settings ['date_separator ' ]], array_filter ($ parts_in_order ));
446
+ $ formatted_date = t ("@date " , [
447
+ "@date " => implode (self ::DELIMITERS [$ settings ['date_separator ' ]], array_filter ($ parts_in_order )),
448
+ ]);
449
+ }
450
+
451
+ // Capitalize first letter for unknown dates.
452
+ if ($ unspecified_count > 0 ) {
453
+ $ formatted_date = ucfirst ($ formatted_date );
318
454
}
319
455
320
456
// Time.
@@ -323,34 +459,6 @@ protected function formatDate($edtf_text) {
323
459
$ formatted_date .= ' ' . $ date_time [1 ];
324
460
}
325
461
326
- // Unspecified.
327
- // Year = 1, Month = 2, Day = 4.
328
- switch (count ($ unspecified )) {
329
- case 1 :
330
- $ formatted_date = t ('unspecified @time_unit in @date ' , [
331
- '@time_unit ' => $ unspecified [0 ],
332
- '@date ' => $ formatted_date ,
333
- ]);
334
- break ;
335
-
336
- case 2 :
337
- $ formatted_date = t ('unspecified @time_unit1 and @time_unit2 in @date ' , [
338
- '@time_unit1 ' => $ unspecified [0 ],
339
- '@time_unit2 ' => $ unspecified [1 ],
340
- '@date ' => $ formatted_date ,
341
- ]);
342
- break ;
343
-
344
- case 3 :
345
- $ formatted_date = t ('unspecified @time_unit1, @time_unit2, and @time_unit3 in @date ' , [
346
- '@time_unit1 ' => $ unspecified [0 ],
347
- '@time_unit2 ' => $ unspecified [1 ],
348
- '@time_unit3 ' => $ unspecified [2 ],
349
- '@date ' => $ formatted_date ,
350
- ]);
351
- break ;
352
- }
353
-
354
462
// Qualified.
355
463
// This is ugly and terrible, but I'm out of ideas for simplifying it.
356
464
$ qualifiers = [
0 commit comments