private function formatDateTimeValue($value, $format, $type) { $timeZone = $this->timeZone; // avoid time zone conversion for date-only values if ($type === 'date') { list($timestamp, $hasTimeInfo) = $this->normalizeDatetimeValue($value, true); if (!$hasTimeInfo) { $timeZone = $this->defaultTimeZone; } } else { $timestamp = $this->normalizeDatetimeValue($value); } if ($timestamp === null) { return $this->nullDisplay; } // intl does not work with dates >=2038 or <=1901 on 32bit machines, fall back to PHP $year = $timestamp->format('Y'); if ($this->_intlLoaded && !(PHP_INT_SIZE == 4 && ($year <= 1901 || $year >= 2038))) { if (strncmp($format, 'php:', 4) === 0) { $format = FormatConverter::convertDatePhpToIcu(substr($format, 4)); } if (isset($this->_dateFormats[$format])) { if ($type === 'date') { $formatter = new IntlDateFormatter($this->locale, $this->_dateFormats[$format], IntlDateFormatter::NONE, $timeZone); } elseif ($type === 'time') { $formatter = new IntlDateFormatter($this->locale, IntlDateFormatter::NONE, $this->_dateFormats[$format], $timeZone); } else { $formatter = new IntlDateFormatter($this->locale, $this->_dateFormats[$format], $this->_dateFormats[$format], $timeZone); } } else { $formatter = new IntlDateFormatter($this->locale, IntlDateFormatter::NONE, IntlDateFormatter::NONE, $timeZone, null, $format); } if ($formatter === null) { throw new InvalidConfigException(intl_get_error_message()); } // make IntlDateFormatter work with DateTimeImmutable if ($timestamp instanceof \DateTimeImmutable) { $timestamp = new DateTime($timestamp->format(DateTime::ISO8601), $timestamp->getTimezone()); } return $formatter->format($timestamp); } else { if (strncmp($format, 'php:', 4) === 0) { $format = substr($format, 4); } else { $format = FormatConverter::convertDateIcuToPhp($format, $type, $this->locale); } if ($timeZone != null) { if ($timestamp instanceof \DateTimeImmutable) { $timestamp = $timestamp->setTimezone(new DateTimeZone($timeZone)); } else { $timestamp->setTimezone(new DateTimeZone($timeZone)); } } return $timestamp->format($format); } }
public function evaluateAttributes($event) { if (strncmp($this->sourceFormat, 'php:', 4) === 0) { $sourceFormat = FormatConverter::convertDatePhpToIcu(substr($this->sourceFormat, 4)); } else { $sourceFormat = $this->sourceFormat; } $formatter = new \IntlDateFormatter(Yii::$app->formatter->locale, null, null, Yii::$app->formatter->timeZone, Yii::$app->formatter->calendar, $sourceFormat); foreach ($this->attributes as $attribute) { $value = $this->owner->{$attribute}; if (empty($value)) { continue; } $this->owner->{$attribute} = Yii::$app->formatter->asDateTime($formatter->parse($value), $this->destinationFormat); } }
/** * @throws \yii\base\InvalidConfigException */ public function init() { if (!isset($this->options['id'])) { $this->options['id'] = $this->getId(); $this->name = $this->getId(); } if (!$this->hasModel()) { throw new InvalidConfigException("DateRangePicker requires a model, check docs for usage."); } Html::addCssClass($this->options, ['date-range-picker', 'form-control']); if (!$this->dateFormat) { $this->dateFormat = Yii::$app->formatter->dateFormat; } if ($this->getDate('start') && $this->getDate('end')) { $this->clientOptions['startDate'] = new JsExpression('moment("' . $this->getDate('start') . '")'); $this->clientOptions['endDate'] = new JsExpression('moment("' . $this->getDate('end') . '")'); } $dateFormat = $this->dateFormat; if (strncmp($this->dateFormat, 'php:', 4) === 0) { $dateFormat = FormatConverter::convertDatePhpToIcu(substr($this->dateFormat, 4)); } $this->clientOptions['locale'] = ['format' => MomentFormatConverter::convert($dateFormat)]; }
/** * @param $value array - a fuzzy date in array form (having keys 'y', 'm', and 'd'). * @param null $format - see $fuzzyDateFormat; if null $fuzzyDateFormat is used * @return string - the formatted fuzzy date * @throws NotSupportedException */ public function asFuzzyDate($value, $format = null) { $_dateFormats = ['short' => IntlDateFormatter::SHORT, 'medium' => IntlDateFormatter::MEDIUM, 'long' => IntlDateFormatter::LONG, 'full' => IntlDateFormatter::FULL]; if ($value === null) { return $this->nullDisplay; } if (!is_array($value)) { throw new InvalidParamException('Formatting fuzzy date failed.'); } if (!extension_loaded('intl')) { // can't use $this->_intlLoaded (private) throw new NotSupportedException('Extension \'Intl\' not loaded'); } if (!$format) { $format = $this->fuzzyDateFormat; } $granularity = 'full'; if (!isset($value['d']) || empty($value['d'])) { $granularity = isset($value['m']) && !empty($value['m']) ? 'month' : 'year'; } $dt = new DateTime(); $tokens = null; switch ($granularity) { case 'month': $dt->setDate($value['y'], $value['m'], 1); $tokens = 'cDdEeFWw'; // ICU-tokens having to do with day break; case 'year': $dt->setDate($value['y'], 1, 1); $tokens = 'cDdEeFLMWw'; // ICU-tokens having to do with day or month break; default: // 'full', finest granularity, use full pattern $dt->setDate($value['y'], $value['m'], $value['d']); break; } $formatter = null; if (is_array($format)) { $pattern = $format[$granularity]; } else { if (isset($_dateFormats[$format])) { $formatter = new IntlDateFormatter($this->locale, $_dateFormats[$format], IntlDateFormatter::NONE); $format = $formatter->getPattern(); } else { if (strncmp($format, 'php:', 4) === 0) { $format = FormatConverter::convertDatePhpToIcu(substr($format, 4)); } } if ($tokens) { // use PCRE_UTF8 modifier ('u') for regular expressions $pattern = preg_replace("/'[^']+'\\s?[{$tokens}]+\\S?\\s?|(?:('[^']+')|[{$tokens}]+\\S?\\s?)/u", '$1', $format); // remove tokens, possibly // with prepended quoted string, possibly with appended non-space and space, unless in single quoted string $pattern = preg_replace('/^(\'[^\']*\'\\s*)+|(\\s*\'[^\']*\')+$|\\W$/u', '', $pattern); // remove (possibly multiple) quoted strings at begin or end, non-word character from end } else { $pattern = $format; } } if (!$formatter) { $formatter = new IntlDateFormatter($this->locale, IntlDateFormatter::NONE, IntlDateFormatter::NONE); } // New in 1.0.1 : fall back to PHP if 32 bits and 'extreme' date if (PHP_INT_SIZE > 4 || $value['y'] > 1901 && $value['y'] < 2038) { $formatter->setPattern($pattern); return $formatter->format($dt); } else { return $dt->format(FormatConverter::convertDateIcuToPhp($pattern)); } }
/** * @param integer|string|DateTime $value the value to be formatted. The following * types of value are supported: * * - an integer representing a UNIX timestamp * - a string that can be [parsed to create a DateTime object](http://php.net/manual/en/datetime.formats.php). * The timestamp is assumed to be in UTC unless a timezone is explicitly given. * - a PHP [DateTime](http://php.net/manual/en/class.datetime.php) object * * @param string $format the format used to convert the value into a date string. * @param string $type 'date', 'time', or 'datetime'. * @throws InvalidConfigException if the date format is invalid. * @return string the formatted result. */ private function formatDateTimeValue($value, $format, $type) { $timestamp = $this->normalizeDatetimeValue($value); if ($timestamp === null) { return $this->nullDisplay; } if ($this->_intlLoaded) { if (strncmp($format, 'php:', 4) === 0) { $format = FormatConverter::convertDatePhpToIcu(substr($format, 4)); } if (isset($this->_dateFormats[$format])) { if ($type === 'date') { $formatter = new IntlDateFormatter($this->locale, $this->_dateFormats[$format], IntlDateFormatter::NONE, $this->timeZone); } elseif ($type === 'time') { $formatter = new IntlDateFormatter($this->locale, IntlDateFormatter::NONE, $this->_dateFormats[$format], $this->timeZone); } else { $formatter = new IntlDateFormatter($this->locale, $this->_dateFormats[$format], $this->_dateFormats[$format], $this->timeZone); } } else { $formatter = new IntlDateFormatter($this->locale, IntlDateFormatter::NONE, IntlDateFormatter::NONE, $this->timeZone, null, $format); } if ($formatter === null) { throw new InvalidConfigException(intl_get_error_message()); } return $formatter->format($timestamp); } else { if (strncmp($format, 'php:', 4) === 0) { $format = substr($format, 4); } else { $format = FormatConverter::convertDateIcuToPhp($format, $type, $this->locale); } if ($this->timeZone != null) { $timestamp->setTimezone(new DateTimeZone($this->timeZone)); } return $timestamp->format($format); } }
private function parseDateTimeValue($value, $format, $type) { if ($value === null || $value == '') { return null; } $timeZone = $this->formatter->timeZone; if ($this->_intlLoaded) { if (strncmp($format, 'php:', 4) === 0) { $format = FormatConverter::convertDatePhpToIcu(substr($format, 4)); } if (isset($this->_dateFormats[$format])) { if ($type === 'date') { $formatter = new IntlDateFormatter($this->formatter->locale, $this->_dateFormats[$format], IntlDateFormatter::NONE, $timeZone); } elseif ($type === 'time') { $formatter = new IntlDateFormatter($this->formatter->locale, IntlDateFormatter::NONE, $this->_dateFormats[$format], $timeZone); } else { $formatter = new IntlDateFormatter($this->formatter->locale, $this->_dateFormats[$format], $this->_dateFormats[$format], $timeZone); } } else { $formatter = new IntlDateFormatter($this->formatter->locale, IntlDateFormatter::NONE, IntlDateFormatter::NONE, $timeZone, null, $format); } if ($formatter === null) { throw new InvalidConfigException(intl_get_error_message()); } if (($result = $formatter->parse($value)) === false) { throw new InvalidParamException('Parsing date/time value failed: ' . $formatter->getErrorCode() . ' ' . $formatter->getErrorMessage()); } return $result; } else { throw new InvalidConfigException('Parse as Date/Time is only supported when PHP intl extension is installed.'); } }
/** * @param string|array $format * @param Formatter $formatter * @throws InvalidParamException * @return array|string */ public static function normalizeIcuFormat($format, $formatter) { if (is_string($format)) { switch ($format) { case 'date': $format = $formatter->dateFormat; if (strncmp($format, 'php:', 4) === 0) { $format = FormatConverter::convertDatePhpToIcu(substr($format, 4)); } return ['date', $format]; case 'time': $format = $formatter->timeFormat; if (strncmp($format, 'php:', 4) === 0) { $format = FormatConverter::convertDatePhpToIcu(substr($format, 4)); } return ['time', $format]; case 'datetime': $format = $formatter->datetimeFormat; if (strncmp($format, 'php:', 4) === 0) { $format = FormatConverter::convertDatePhpToIcu(substr($format, 4)); } return ['datetime', $format]; default: throw new InvalidParamException('$format has incorrect value'); } } elseif (is_array($format) && count($format) < 2) { throw new InvalidParamException('When $format is presented in array form, it must have at least two elements'); } return $format; }