From 06e113919fb1cff5c6a54ca4215b89aadc49802d Mon Sep 17 00:00:00 2001 From: Nikola Kovacs Date: Wed, 10 Feb 2016 13:30:21 +0100 Subject: [PATCH] Fix locale inconsistencies between intl and moment The month names used by moment are different than the ones in intl, leading to validation errors. Get the month and weekday names from intl, and patch the moment locale to use those. --- DateTimePicker.php | 20 ++++++++++++++++ LocaleConverter.php | 56 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 LocaleConverter.php diff --git a/DateTimePicker.php b/DateTimePicker.php index 19ffc6b..341be7c 100644 --- a/DateTimePicker.php +++ b/DateTimePicker.php @@ -187,9 +187,29 @@ protected function registerLocale($view) if ($file === false) { return; } + $view->registerJsFile(Yii::$app->assetManager->publish($file)[1], [ 'depends' => '\nkovacs\datetimepicker\MomentAsset', ]); + + // use the same strings intl uses, to avoid validation errors. + if (extension_loaded('intl')) { + $weekdays = LocaleConverter::getWeekdays('EEEE', $this->locale); // dddd + $weekdaysShort = LocaleConverter::getWeekdays('EEE', $this->locale); // ddd + $weekdaysMin = LocaleConverter::getWeekdays('EEEEEE', $this->locale); // dd + $months = LocaleConverter::getMonths('MMMM', $this->locale); + $monthsShort = LocaleConverter::getMonths('MMM', $this->locale); + $override = Json::encode([ + 'months' => $months, + 'monthsShort' => $monthsShort, + 'weekdays' => $weekdays, + 'weekdaysShort' => $weekdaysShort, + 'weekdaysMin' => $weekdaysMin, + ]); + // POS_END is the default for js files. + $view->registerJs("moment.locale('$locale', $override)", \yii\web\View::POS_END); + } + $this->clientOptions['locale'] = $locale; } diff --git a/LocaleConverter.php b/LocaleConverter.php new file mode 100644 index 0000000..478236f --- /dev/null +++ b/LocaleConverter.php @@ -0,0 +1,56 @@ +language; + } + + if (!isset(static::$cache['months'][$locale][$format])) { + $formatter = new IntlDateFormatter($locale, IntlDateFormatter::NONE, IntlDateFormatter::NONE, Yii::$app->timeZone, null, $format); + $localized = []; + for ($month = 0; $month < 12; $month++) { + $localized[] = $formatter->format([ + 'tm_sec' => 0, + 'tm_min' => 0, + 'tm_hour' => 12, + 'tm_mday' => 15, + 'tm_mon' => $month, + 'tm_year' => 2016, + ]); + } + static::$cache['months'][$locale][$format] = $localized; + } + return static::$cache['months'][$locale][$format]; + } + + public static function getWeekdays($format, $locale = null) { + if ($locale === null) { + $locale = Yii::$app->language; + } + if (!isset(static::$cache['weekdays'][$locale][$format])) { + $formatter = new IntlDateFormatter($locale, IntlDateFormatter::NONE, IntlDateFormatter::NONE, Yii::$app->timeZone, null, $format); + $localized = []; + for ($day = 0; $day < 7; $day++) { + $localized[] = $formatter->format([ + 'tm_sec' => 0, + 'tm_min' => 0, + 'tm_hour' => 12, + 'tm_mon' => 6, + 'tm_year' => 2016, + 'tm_mday' => 2 + $day, // 2016-06-02 is a sunday + ]); + } + static::$cache['weekdays'][$locale][$format] = $localized; + } + return static::$cache['weekdays'][$locale][$format]; + } +}