/** * @see ValueFormatter::format * * Generates HTML representing the details of a TimeValue, * as an itemized list. * * @param TimeValue $value * * @throws InvalidArgumentException * @return string HTML */ public function format($value) { if (!$value instanceof TimeValue) { throw new InvalidArgumentException('Data value type mismatch. Expected a TimeValue.'); } $timeHtml = $this->getTimestampHtml($value->getTime()); $timeZone = $value->getTimezone(); $timeZoneHtml = is_int($timeZone) ? $this->getTimeZoneHtml($timeZone) : htmlspecialchars($timeZone); $calendarHtml = $this->getCalendarModelHtml($value->getCalendarModel()); $precision = $value->getPrecision(); $before = $value->getBefore(); $after = $value->getAfter(); if (is_int($precision) && is_int($before) && is_int($after)) { $precisionHtml = $this->getAmountAndPrecisionHtml($precision); $beforeHtml = $this->getAmountAndPrecisionHtml($precision, $before); $afterHtml = $this->getAmountAndPrecisionHtml($precision, $after); } else { $precisionHtml = htmlspecialchars($precision); $beforeHtml = htmlspecialchars($value->getBefore()); $afterHtml = htmlspecialchars($value->getAfter()); } $html = ''; $html .= Html::rawElement('h4', array('class' => 'wb-details wb-time-details wb-time-rendered'), $this->timeFormatter->format($value)); $html .= Html::openElement('table', array('class' => 'wb-details wb-time-details')); $html .= $this->getFieldHtml('isotime', $timeHtml); $html .= $this->getFieldHtml('timezone', $timeZoneHtml); $html .= $this->getFieldHtml('calendar', $calendarHtml); $html .= $this->getFieldHtml('precision', $precisionHtml); $html .= $this->getFieldHtml('before', $beforeHtml); $html .= $this->getFieldHtml('after', $afterHtml); $html .= Html::closeElement('table'); return $html; }
/** * @param TimeValue $value * * @return bool */ private function calendarNameNeeded(TimeValue $value) { // Loose check if the timestamp string is ISO-ish and starts with a year. if (!preg_match('/^[-+]?\\d+\\b/', $value->getTime(), $matches)) { return true; } // NOTE: PHP limits overly large values to PHP_INT_MAX. No overflow or wrap-around occurs. $year = (int) $matches[0]; $guessedCalendar = $this->getDefaultCalendar($year); // Always show the calendar if it's different from the "guessed" default. if ($value->getCalendarModel() !== $guessedCalendar) { return true; } // If precision is year or less precise, don't show the calendar. if ($value->getPrecision() <= TimeValue::PRECISION_YEAR) { return false; } // If the date is inside the "critical" range where Julian and Gregorian were used // in parallel, always show the calendar. Gregorian was made "official" in October 1582 but // may already be used earlier. Julian continued to be official until the 1920s in Russia // and Greece, see https://en.wikipedia.org/wiki/Julian_calendar. if ($year > 1580 && $year < 1930) { return true; } // Otherwise, the calendar is "unsurprising", so don't show it. return false; }
/** * @dataProvider validInputProvider */ public function testParse($value, TimeValue $expected, $languageCode) { $factory = $this->newTimeParserFactory($languageCode); $parser = $factory->getTimeParser(); $actual = $parser->parse($value); $this->assertEquals($expected->getArrayValue(), $actual->getArrayValue()); }
/** * @param TimeValue $timeValue * * @return string Text */ private function formatTimeValue(TimeValue $timeValue) { $isoTimestamp = $timeValue->getTime(); try { return $this->getLocalizedDate($isoTimestamp, $timeValue->getPrecision()); } catch (InvalidArgumentException $ex) { return $isoTimestamp; } }
/** * @dataProvider precisionDayProvider */ public function testPrecisionDayRoundtrip(TimeValue $timeValue, $formatted, $languageCode) { $formatterOptions = new FormatterOptions(array(ValueFormatter::OPT_LANG => $languageCode)); $formatter = new MwTimeIsoFormatter($formatterOptions); $parserOptions = new ParserOptions(array(ValueParser::OPT_LANG => $languageCode, IsoTimestampParser::OPT_PRECISION => $timeValue->getPrecision(), IsoTimestampParser::OPT_CALENDAR => $timeValue->getCalendarModel())); $factory = $this->newTimeParserFactory($parserOptions); $parser = $factory->getTimeParser(); $this->assertSame($formatted, $formatter->format($timeValue)); $this->assertEquals($timeValue, $parser->parse($formatted)); }
/** * @see ValueFormatter::format * * @param TimeValue $value * * @throws InvalidArgumentException * @return string Plain text */ public function format($value) { if (!$value instanceof TimeValue) { throw new InvalidArgumentException('Data value type mismatch. Expected a TimeValue.'); } $formatted = $value->getTime(); $isoFormatter = $this->getOption(self::OPT_TIME_ISO_FORMATTER); if ($isoFormatter instanceof ValueFormatter) { $formatted = $isoFormatter->format($value); } return $formatted; }
/** * Get standardized dateTime value, compatible with xsd:dateTime * If the value cannot be converted to it, returns null * * @param TimeValue $value * * @return string|null */ public function getStandardValue(TimeValue $value) { $calendar = $value->getCalendarModel(); if ($calendar == TimeValue::CALENDAR_GREGORIAN) { return $this->cleanupGregorianValue($value->getTime(), $value->getPrecision()); } elseif ($calendar == TimeValue::CALENDAR_JULIAN) { $precision = $value->getPrecision(); // If we are less precise than a day, no point to convert // Julian to Gregorian since we don't have enough information to do it anyway if ($precision >= TimeValue::PRECISION_DAY) { return $this->julianDateValue($value->getTime()); } else { return $this->cleanupGregorianValue($value->getTime(), $precision); } } return null; }
private function buildTimeValueForSearch(PropertyId $propertyId, TimeValue $timeValue) { $significantTimePart = preg_replace('/(-00)*T00:00:00Z$/', '', $timeValue->getTime()); return new MongoRegex('/^' . preg_quote($propertyId->getSerialization() . '-' . $significantTimePart, '/') . '/'); }
/** * This returns a Unix timestamp from a TimeValue similar to PHP's mk_time() (or strtotime()), * but with no range limitations. Data type is float because PHP's 32 bit integer would * clip in the year 2038. * * @param TimeValue $timeValue * * @return float seconds since 1970-01-01T00:00:00Z */ public function getTimestamp(TimeValue $timeValue) { return $this->getSecondsSinceUnixEpoch($timeValue->getTime(), $timeValue->getTimezone()); }
/** * @dataProvider unpaddedYearsProvider */ public function testGivenUnpaddedYear_yearIsPadded($year, $expected) { $timeValue = new TimeValue($year . '-01-01T00:00:00Z', 0, 0, 0, TimeValue::PRECISION_DAY, 'Stardate'); $this->assertSame($expected . '-01-01T00:00:00Z', $timeValue->getTime()); }
/** * Returns if $a is a more (or equal) precise Time value than $b * Does not support time part of the timestamp */ private function isTimeValueMorePrecise(TimeValue $a, TimeValue $b) { if ($a->getPrecision() < $b->getPrecision()) { return false; } list($yearA, $monthA, $dayA) = $this->explodeTimestamp($a->getTime()); list($yearB, $monthB, $dayB) = $this->explodeTimestamp($b->getTime()); return $yearA === $yearB && !($b->getPrecision() >= TimeValue::PRECISION_MONTH && $monthA !== $monthB) && !($b->getPrecision() >= TimeValue::PRECISION_DAY && $dayA !== $dayB); }
/** * Get standardized dateTime value, compatible with xsd:dateTime * If the value cannot be converted to it, returns null * @param TimeValue $value * @return string|null */ public function getStandardValue(TimeValue $value) { return $this->cleanupGregorianValue($value->getTime(), $value->getPrecision()); }