Чтобы предложить ответ на мой вопрос: нет, похоже, ничего подобного.
Итак, я продолжил и реализовал функцию, которая делает то, что мне нужно. Я отказался от черновика класса WikidataDate
, так как просто создавал десятки из них, чтобы просто преобразовать одну строку в другую ...
Спасибо за ваш отзыв, не стесняйтесь предлагать улучшения или другие решения!
const CALENDARMODEL = 'http://www.wikidata.org/entity/Q1985727';
const WIKIDATA_DATE_FORMAT = '/^[+]?(-?\d{1,11})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/';
const PRECISION_YEAR = 9;
const PRECISION_YEAR_AND_MONTH = 10;
const PRECISION_DATE = 11;
const PRECISIONS = [
self::PRECISION_YEAR,
self::PRECISION_YEAR_AND_MONTH,
self::PRECISION_DATE,
];
/**
* Parse a date object (a "value" node) coming from parsing Wikidata JSON.
*
* Example string outputs:
* - "2018-12-31" the last day of 2018
* - "333-11" the month of the battle of Issos
* - "-53" the year in which Lutetia (Paris) was first mentioned
* - "-13798000000" the beginning of the universe
*
* @param \stdClass $object
*
* @return string
*
* @throws \Exception
*/
private function parseWikidataDate(\stdClass $object): string
{
if (!WikidataEntityDenormalizer::validateObjectProperties($object, ['time', 'precision', 'calendarmodel'])) {
throw new \Exception('Object missing necessary properties');
}
if (!in_array($object->precision, static::PRECISIONS)) {
throw new \Exception('Unexpected precision: '.$object->precision);
}
if (static::CALENDARMODEL !== $object->calendarmodel) {
throw new \Exception('Unexpected calendar model');
}
$result = [];
preg_match(static::WIKIDATA_DATE_FORMAT, $object->time, $result);
if (7 !== count($result)) {
throw new \Exception(sprintf('Could not parse Wikidata date: %s', $object->time));
}
$date = $result[1];
if ('00' !== $result[2]) {
$date .= '-'.$result[2];
}
if ('00' !== $result[3]) {
$date .= '-'.$result[3];
}
return $date;
}