From 8b0962e1926445734ea8102bca0958e1457ced6c Mon Sep 17 00:00:00 2001 From: Kevin Papst Date: Sun, 14 Nov 2021 18:18:26 +0100 Subject: [PATCH] configure am/pm time-format as user preference (#2789) --- .env.dist | 34 +++++--------- UPGRADING.md | 7 +++ composer.json | 3 +- config/packages/kimai.yaml | 18 -------- src/API/ConfigurationController.php | 3 +- src/API/Model/I18nConfig.php | 18 -------- src/Configuration/LanguageFormattings.php | 33 -------------- src/DependencyInjection/Configuration.php | 10 ++++- src/Entity/User.php | 14 ++++++ src/Entity/UserPreference.php | 1 + .../UserPreferenceSubscriber.php | 7 +++ src/Form/Type/DateTimePickerType.php | 21 ++++++--- src/Twig/LocaleFormatExtensions.php | 36 ++++++++++++--- src/Utils/DateFormatConverter.php | 33 ++++++++++++++ src/Utils/LocaleFormats.php | 23 +--------- src/Utils/LocaleFormatter.php | 45 ++++++++----------- src/Utils/MomentFormatConverter.php | 6 ++- templates/base.html.twig | 2 +- templates/export/renderer/default.html.twig | 2 +- tests/API/ConfigurationControllerTest.php | 4 +- tests/API/Model/I18nConfigTest.php | 1 - .../Configuration/LanguageFormattingsTest.php | 41 ----------------- tests/Controller/ProfileControllerTest.php | 2 +- tests/Entity/UserTest.php | 12 +++++ .../UserPreferenceSubscriberTest.php | 1 + .../Export/Renderer/AbstractRendererTest.php | 6 ++- tests/Export/Renderer/HtmlRendererTest.php | 14 ++++++ .../Export/Timesheet/AbstractRendererTest.php | 6 ++- tests/Twig/LocaleFormatExtensionsTest.php | 29 +++++------- tests/Utils/LocaleFormatsTest.php | 34 -------------- translations/messages.de.xlf | 6 ++- translations/messages.en.xlf | 4 ++ 32 files changed, 216 insertions(+), 260 deletions(-) create mode 100644 src/Utils/DateFormatConverter.php diff --git a/.env.dist b/.env.dist index 3e7a4dea..4b785509 100644 --- a/.env.dist +++ b/.env.dist @@ -1,30 +1,16 @@ -### DATABASE CONFIGURATION -# Replace "user", "password" and "database" with your database connection. -# Configure the server version, MariaDB requires the "mariadb-" prefix, eg: -# for MySQL "serverVersion=5.7" and for MariaDB "serverVersion=mariadb-10.5.8" +# Configure your database connection and set the correct server version: +# for MySQL "serverVersion=5.7" and for MariaDB "serverVersion=mariadb-10.5.8" DATABASE_URL=mysql://user:password@127.0.0.1:3306/database?charset=utf8&serverVersion=5.7 - -### EMAIL CONFIGURATION -# Emails will be sent "from": +# Email will be sent with this address as sender MAILER_FROM=kimai@example.com - -# Email connection (disabled by default with MAILER_URL=null://null) -# SMTP: smtp://localhost:25?encryption=&auth_mode= -# Google: gmail://username:password@default -# Amazon: ses://ACCESS_KEY:SECRET_KEY@default?region=eu-west-1 -# Mailchimp: mandrill://KEY@default -# Mailgun: mailgun://KEY:DOMAIN@default -# Postmark: postmark://ID@default -# Sendgrid: sendgrid://KEY@default -# Disable emails: null://null +# Email connection (disabled by default) more info at https://www.kimai.org/documentation/emails.html MAILER_URL=null://null - -### APPLICATION CONFIGURATION +# do not change, unless you are developing for Kimai APP_ENV=prod +# should be changed to a unique character sequence APP_SECRET=change_this_to_something_unique - -# Running in a "special" environment, eg. behind reverse proxies? -# Check those: -# TRUSTED_PROXIES=127.0.0.1,127.0.0.2 -# TRUSTED_HOSTS=localhost,example.com +# unlikely, that you need to change this one CORS_ALLOW_ORIGIN=^https?://localhost(:[0-9]+)?$ +# Running behind reverse proxies? Use those: +# TRUSTED_PROXIES=127.0.0.1,127.0.0.2 +# TRUSTED_HOSTS=localhost,example.com diff --git a/UPGRADING.md b/UPGRADING.md index 55ec7045..16d3f60f 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -8,6 +8,13 @@ you can upgrade your Kimai installation to the latest stable release. Check below if there are more version specific steps required, which need to be executed after the normal update process. Perform EACH version specific task between your version and the new one, otherwise you risk data inconsistency or a broken installation. + +## [1.16](https://github.com/kevinpapst/kimai2/releases/tag/1.16) + +**DEVELOPER** + +- Removed `formDateTime` field from API model `I18nConfig` + ## [1.15](https://github.com/kevinpapst/kimai2/releases/tag/1.15) **Many database changes: don't forget to [run the updater](https://www.kimai.org/documentation/updates.html).** diff --git a/composer.json b/composer.json index 9c325f56..955ea923 100644 --- a/composer.json +++ b/composer.json @@ -165,7 +165,8 @@ "bin/console lint:xliff translations", "bin/console doctrine:schema:validate --skip-sync -vvv --no-interaction" ], - "kimai:tests": "vendor/bin/phpunit tests/", + "tests": "vendor/bin/phpunit tests/", + "kimai:tests": "@tests", "kimai:tests-unit": "vendor/bin/phpunit --exclude-group integration tests/", "kimai:tests-integration": "vendor/bin/phpunit --group integration tests/", "kimai:phpstan": "@phpstan", diff --git a/config/packages/kimai.yaml b/config/packages/kimai.yaml index 7e1f2a0f..a147624a 100644 --- a/config/packages/kimai.yaml +++ b/config/packages/kimai.yaml @@ -214,91 +214,74 @@ kimai: # -------------------------------------------------------------------------------- languages: cs: - date_time_type: 'dd.MM.yyyy HH:mm' date_type: 'dd.MM.yyyy' date: 'd.m.Y' date_time: 'd.m H:i' da: - date_time_type: 'dd.MM.yyyy HH:mm' date_type: 'dd.MM.yyyy' date: 'd.m.Y' date_time: 'd.m. H:i' de: - date_time_type: 'dd.MM.yyyy HH:mm' date_type: 'dd.MM.yyyy' date: 'd.m.Y' date_time: 'd.m. H:i' de_AT: - date_time_type: 'dd.MM.yyyy HH:mm' date_type: 'dd.MM.yyyy' date: 'd.m.Y' date_time: 'd.m. H:i' de_CH: - date_time_type: 'dd.MM.yyyy HH:mm' date_type: 'dd.MM.yyyy' date: 'd.m.Y' date_time: 'd.m. H:i' el: - date_time_type: 'dd.MM.yyyy HH:mm' date_type: 'dd.MM.yyyy' date: 'd.m.Y' date_time: 'd.m. H:i' en: - date_time_type: 'yyyy-MM-dd HH:mm' date_type: 'yyyy-MM-dd' date: 'Y-m-d' date_time: 'm-d H:i' duration: '%%h:%%m h' es: - date_time_type: 'dd.MM.yyyy HH:mm' date_type: 'dd.MM.yyyy' date: 'd.m.Y' date_time: 'd.m. H:i' fi: - date_time_type: 'dd.MM.yyyy HH:mm' date_type: 'dd.MM.yyyy' date: 'd.m.Y' date_time: 'd.m. H:i' fr: - date_time_type: 'dd/MM/yyyy HH:mm' date_type: 'dd/MM/yyyy' date: 'd/m/Y' date_time: 'd/m H:i' duration: '%%h h %%m' he: - date_time_type: 'dd/MM/yyyy HH:mm' date_type: 'dd/MM/yyyy' date: 'd/m/Y' date_time: 'd/m H:i' duration: '%%h:%%m' hu: - date_time_type: 'yyyy.MM.dd. HH:mm' date_type: 'yyyy.MM.dd.' date: 'Y.m.d.' date_time: 'm.d. H:i' it: - date_time_type: 'dd.MM.yyyy HH:mm' date_type: 'dd.MM.yyyy' date: 'd.m.Y' date_time: 'd.m. H:i' nl: - date_time_type: 'dd.MM.yyyy HH:mm' date_type: 'dd.MM.yyyy' date: 'd.m.Y' date_time: 'd.m. H:i' duration: '%%hu%%m' pt_BR: - date_time_type: 'dd-MM-yyyy HH:mm' date_type: 'dd-MM-yyyy' date: 'd-m-Y' date_time: 'd-m H:i' ru: - date_time_type: 'dd.MM.yyyy HH:mm' date_type: 'dd.MM.yyyy' date: 'd.m.Y' date_time: 'd.m. H:i' sk: - date_time_type: 'dd. MM. yyyy HH:mm' date_type: 'dd. MM. yyyy' date: 'd. m. Y' date_time: 'd. m. H:i' @@ -306,7 +289,6 @@ kimai: duration: '%%h:%%m tim' date_time: 'd/m H:i' pl: - date_time_type: 'dd. MM. yyyy HH:mm' date_type: 'dd. MM. yyyy' date: 'd. m. Y' date_time: 'd. m. H:i' diff --git a/src/API/ConfigurationController.php b/src/API/ConfigurationController.php index edcd71ee..f24ca22e 100644 --- a/src/API/ConfigurationController.php +++ b/src/API/ConfigurationController.php @@ -64,13 +64,12 @@ final class ConfigurationController extends BaseApiController $model = new I18nConfig(); $model - ->setFormDateTime($formats->getDateTimeTypeFormat($locale)) ->setFormDate($formats->getDateTypeFormat($locale)) ->setDateTime($formats->getDateTimeFormat($locale)) ->setDate($formats->getDateFormat($locale)) ->setDuration($formats->getDurationFormat($locale)) ->setTime($formats->getTimeFormat($locale)) - ->setIs24hours($formats->isTwentyFourHours($locale)) + ->setIs24hours($user->is24Hour()) ->setNow($this->getDateTimeFactory()->createDateTime()) ; diff --git a/src/API/Model/I18nConfig.php b/src/API/Model/I18nConfig.php index 9688eece..054792fe 100644 --- a/src/API/Model/I18nConfig.php +++ b/src/API/Model/I18nConfig.php @@ -18,17 +18,6 @@ use JMS\Serializer\Annotation as Serializer; */ final class I18nConfig { - /** - * Format used for 'begin' and 'end' - * - * @var string - * - * @Serializer\Expose() - * @Serializer\Groups({"Default"}) - * @Serializer\Type(name="string") - * @phpstan-ignore-next-line - */ - private $formDateTime = ''; /** * Format used for toolbar queries * @@ -114,13 +103,6 @@ final class I18nConfig return $this; } - public function setFormDateTime(string $formDateTime): I18nConfig - { - $this->formDateTime = $formDateTime; - - return $this; - } - public function setFormDate(string $formDate): I18nConfig { $this->formDate = $formDate; diff --git a/src/Configuration/LanguageFormattings.php b/src/Configuration/LanguageFormattings.php index 0cec8095..82e35c3b 100644 --- a/src/Configuration/LanguageFormattings.php +++ b/src/Configuration/LanguageFormattings.php @@ -60,28 +60,6 @@ final class LanguageFormattings return $this->momentFormatter->convert($this->getDateTypeFormat($locale)); } - /** - * Returns the format which is used by the form component to handle datetime values. - * - * @param string $locale - * @return string - */ - public function getDateTimeTypeFormat(string $locale): string - { - return $this->getConfig('date_time_type', $locale); - } - - /** - * Returns the format which is used by the Javascript component to handle datetime values. - * - * @param string $locale - * @return string - */ - public function getDateTimePickerFormat(string $locale): string - { - return $this->momentFormatter->convert($this->getDateTimeTypeFormat($locale)); - } - /** * Returns the locale specific date format, which should be used in combination with the twig filter "|date". * @@ -126,17 +104,6 @@ final class LanguageFormattings return $this->getConfig('duration', $locale); } - /** - * Returns whether this locale uses the 24 hour format. - * - * @param string $locale - * @return bool - */ - public function isTwentyFourHours(string $locale): bool - { - return (bool) $this->getConfig('24_hours', $locale); - } - /** * @param string $key * @param string $locale diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 81d3ad3f..f1cd9d2a 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -329,13 +329,19 @@ class Configuration implements ConfigurationInterface ->useAttributeAsKey('name', false) // see https://github.com/symfony/symfony/issues/18988 ->arrayPrototype() ->children() - ->scalarNode('date_time_type')->defaultValue('yyyy-MM-dd HH:mm')->end() // for DateTimeType + ->scalarNode('date_time_type') // for DateTimeType + ->defaultValue('yyyy-MM-dd HH:mm') + ->setDeprecated('date_time_type is deprecated since 1.16 and was replaced by the 24 user configuration') + ->end() ->scalarNode('date_type')->defaultValue('yyyy-MM-dd')->end() // for DateType ->scalarNode('date')->defaultValue('Y-m-d')->end() // for display via twig ->scalarNode('date_time')->defaultValue('m-d H:i')->end() // for display via twig ->scalarNode('duration')->defaultValue('%%h:%%m h')->end() // for display via twig ->scalarNode('time')->defaultValue('H:i')->end() // for display via twig - ->booleanNode('24_hours')->defaultTrue()->end() // for DateTimeType JS component + ->booleanNode('24_hours') // for DateTimeType JS component + ->defaultTrue() + ->setDeprecated('24_hours is deprecated since 1.16 and a user configuration now') + ->end() ->end() ->end() ; diff --git a/src/Entity/User.php b/src/Entity/User.php index 6e0d8873..6f0fedcd 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -430,6 +430,20 @@ class User implements UserInterface, EquatableInterface, \Serializable return null; } + public function getTimeFormat(): string + { + if ($this->is24Hour()) { + return 'H:i'; + } + + return 'h:i A'; + } + + public function is24Hour(): bool + { + return (bool) $this->getPreferenceValue(UserPreference::HOUR_24, true); + } + public function getLocale(): string { return $this->getPreferenceValue(UserPreference::LOCALE, User::DEFAULT_LANGUAGE); diff --git a/src/Entity/UserPreference.php b/src/Entity/UserPreference.php index 636da3cb..95f33892 100644 --- a/src/Entity/UserPreference.php +++ b/src/Entity/UserPreference.php @@ -30,6 +30,7 @@ class UserPreference public const INTERNAL_RATE = 'internal_rate'; public const SKIN = 'skin'; public const LOCALE = 'language'; + public const HOUR_24 = 'hours_24'; public const TIMEZONE = 'timezone'; public const FIRST_WEEKDAY = 'first_weekday'; diff --git a/src/EventSubscriber/UserPreferenceSubscriber.php b/src/EventSubscriber/UserPreferenceSubscriber.php index bafcad7c..34609859 100644 --- a/src/EventSubscriber/UserPreferenceSubscriber.php +++ b/src/EventSubscriber/UserPreferenceSubscriber.php @@ -112,6 +112,13 @@ final class UserPreferenceSubscriber implements EventSubscriberInterface ->setSection('locale') ->setType(FirstWeekDayType::class), + (new UserPreference()) + ->setName(UserPreference::HOUR_24) + ->setValue(true) + ->setOrder(305) + ->setSection('locale') + ->setType(CheckboxType::class), + (new UserPreference()) ->setName(UserPreference::SKIN) ->setValue($this->configuration->getUserDefaultTheme()) diff --git a/src/Form/Type/DateTimePickerType.php b/src/Form/Type/DateTimePickerType.php index 25cb14ff..b37d560f 100644 --- a/src/Form/Type/DateTimePickerType.php +++ b/src/Form/Type/DateTimePickerType.php @@ -10,11 +10,15 @@ namespace App\Form\Type; use App\API\BaseApiController; +use App\Entity\User; +use App\Utils\DateFormatConverter; use App\Utils\LocaleSettings; +use App\Utils\MomentFormatConverter; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\DateTimeType; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; +use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; /** @@ -34,9 +38,6 @@ class DateTimePickerType extends AbstractType */ public function configureOptions(OptionsResolver $resolver) { - $dateTimePicker = $this->localeSettings->getDateTimePickerFormat(); - $dateTimeFormat = $this->localeSettings->getDateTimeTypeFormat(); - $resolver->setDefaults([ 'documentation' => [ 'type' => 'string', @@ -46,8 +47,18 @@ class DateTimePickerType extends AbstractType 'label' => 'label.begin', 'widget' => 'single_text', 'html5' => false, - 'format' => $dateTimeFormat, - 'format_picker' => $dateTimePicker, + 'format' => function (Options $options) { + /** @var User $user */ + $user = $options['user']; + $converter = new DateFormatConverter(); + + return $this->localeSettings->getDateTypeFormat() . ' ' . $converter->convert($user->getTimeFormat()); // PHP + }, + 'format_picker' => function (Options $options) { + $converter = new MomentFormatConverter(); + + return $converter->convert($options['format']); // JS + }, 'with_seconds' => false, 'time_increment' => 1, ]); diff --git a/src/Twig/LocaleFormatExtensions.php b/src/Twig/LocaleFormatExtensions.php index 1c17a47c..2387dbb7 100644 --- a/src/Twig/LocaleFormatExtensions.php +++ b/src/Twig/LocaleFormatExtensions.php @@ -15,6 +15,7 @@ use App\Entity\User; use App\Utils\LocaleFormats; use App\Utils\LocaleFormatter; use DateTime; +use Symfony\Component\Security\Core\Security; use Twig\Extension\AbstractExtension; use Twig\TwigFilter; use Twig\TwigFunction; @@ -22,10 +23,9 @@ use Twig\TwigTest; final class LocaleFormatExtensions extends AbstractExtension { - /** - * @var LanguageFormattings|null - */ private $formats; + private $security; + /** * @var LocaleFormats|null */ @@ -38,10 +38,12 @@ final class LocaleFormatExtensions extends AbstractExtension * @var string */ private $locale; + private $userFormat; - public function __construct(LanguageFormattings $formats) + public function __construct(LanguageFormattings $formats, Security $security) { $this->formats = $formats; + $this->security = $security; } /** @@ -169,7 +171,18 @@ final class LocaleFormatExtensions extends AbstractExtension */ public function dateTimeFull($date, bool $stripMidnight = false) { - return $this->getFormatter()->dateTimeFull($date, $stripMidnight); + return $this->getFormatter()->dateTimeFull($date, $this->getUserTimeFormat(), $stripMidnight); + } + + private function getUserTimeFormat(): string + { + if ($this->userFormat === null) { + /** @var User|null $user */ + $user = $this->security->getUser(); + $this->userFormat = $user !== null ? $user->getTimeFormat() : 'H:i'; + } + + return $this->userFormat; } public function createDate(string $date, ?User $user = null): \DateTime @@ -201,7 +214,7 @@ final class LocaleFormatExtensions extends AbstractExtension */ public function time($date) { - return $this->getFormatter()->time($date); + return $this->getFormatter()->time($date, $this->getUserTimeFormat()); } /** @@ -240,7 +253,16 @@ final class LocaleFormatExtensions extends AbstractExtension */ public function hour24($twentyFour, $twelveHour) { - return $this->getFormatter()->hour24($twentyFour, $twelveHour); + @trigger_error('Twig filter "hour24" is deprecated, use app.user.is24Hour() instead', E_USER_DEPRECATED); + + /** @var User|null $user */ + $user = $this->security->getUser(); + + if (null === $user) { + return true; + } + + return $user->is24Hour(); } public function getDurationFormat(): string diff --git a/src/Utils/DateFormatConverter.php b/src/Utils/DateFormatConverter.php new file mode 100644 index 00000000..378a5107 --- /dev/null +++ b/src/Utils/DateFormatConverter.php @@ -0,0 +1,33 @@ + 'hh', 'H' => 'HH', + // minutes + 'i' => 'mm', + // am/pm to AM/PM + 'A' => 'a' + ]; + + public function convert(string $format): string + { + return strtr($format, self::$formatConvertRules); + } +} diff --git a/src/Utils/LocaleFormats.php b/src/Utils/LocaleFormats.php index cb963789..e689a1c2 100644 --- a/src/Utils/LocaleFormats.php +++ b/src/Utils/LocaleFormats.php @@ -75,21 +75,12 @@ class LocaleFormats /** * Returns the format which is used by the form component to handle datetime values. * + * @deprecated since 1.16 * @return string */ public function getDateTimeTypeFormat(): string { - return $this->formats->getDateTimeTypeFormat($this->getLocale()); - } - - /** - * Returns the format which is used by the Javascript component to handle datetime values. - * - * @return string - */ - public function getDateTimePickerFormat(): string - { - return $this->formats->getDateTimePickerFormat($this->getLocale()); + return $this->formats->getDateTypeFormat($this->getLocale()) . ' HH:mm'; } /** @@ -131,14 +122,4 @@ class LocaleFormats { return $this->formats->getDurationFormat($this->getLocale()); } - - /** - * Returns whether this locale uses the 24 hour format. - * - * @return bool - */ - public function isTwentyFourHours(): bool - { - return $this->formats->isTwentyFourHours($this->getLocale()); - } } diff --git a/src/Utils/LocaleFormatter.php b/src/Utils/LocaleFormatter.php index 756bd3c3..389c88e2 100644 --- a/src/Utils/LocaleFormatter.php +++ b/src/Utils/LocaleFormatter.php @@ -46,6 +46,10 @@ final class LocaleFormatter * @var string */ private $dateTimeFormat = null; + /** + * @var string + */ + private $dateTypeFormat = null; /** * @var string */ @@ -54,10 +58,6 @@ final class LocaleFormatter * @var string */ private $timeFormat = null; - /** - * @var bool - */ - private $isTwentyFourHour = null; public function __construct(LanguageFormattings $formats, string $locale) { @@ -216,6 +216,15 @@ final class LocaleFormatter return $date->format($this->dateFormat); } + private function getDateTypeFormat(): string + { + if (null === $this->dateTypeFormat) { + $this->dateTypeFormat = $this->localeFormats->getDateTypeFormat(); + } + + return $this->dateTypeFormat; + } + /** * @param DateTime|string $date * @return string @@ -239,13 +248,15 @@ final class LocaleFormatter /** * @param DateTime|string $date + * @param string $timeFormat * @param bool $stripMidnight * @return bool|false|string */ - public function dateTimeFull($date, bool $stripMidnight = false) + public function dateTimeFull($date, string $timeFormat, bool $stripMidnight = false) { if (null === $this->dateTimeTypeFormat) { - $this->dateTimeTypeFormat = $this->localeFormats->getDateTimeTypeFormat(); + $converter = new DateFormatConverter(); + $this->dateTimeTypeFormat = $this->getDateTypeFormat() . ' ' . $converter->convert($timeFormat); } if (!$date instanceof DateTime) { @@ -298,7 +309,7 @@ final class LocaleFormatter * @return string * @throws Exception */ - public function time($date) + public function time($date, string $format = null) { if (null === $this->timeFormat) { $this->timeFormat = $this->localeFormats->getTimeFormat(); @@ -308,7 +319,7 @@ final class LocaleFormatter $date = new DateTime($date); } - return $date->format($this->timeFormat); + return $date->format($format ?? $this->timeFormat); } /** @@ -342,22 +353,4 @@ final class LocaleFormatter { return $this->formatIntl($dateTime, ($short ? 'EE' : 'EEEE')); } - - /** - * @param mixed $twentyFour - * @param mixed $twelveHour - * @return mixed - */ - public function hour24($twentyFour, $twelveHour) - { - if (null === $this->isTwentyFourHour) { - $this->isTwentyFourHour = $this->localeFormats->isTwentyFourHours(); - } - - if (true === $this->isTwentyFourHour) { - return $twentyFour; - } - - return $twelveHour; - } } diff --git a/src/Utils/MomentFormatConverter.php b/src/Utils/MomentFormatConverter.php index 9135ba18..36e20eae 100644 --- a/src/Utils/MomentFormatConverter.php +++ b/src/Utils/MomentFormatConverter.php @@ -18,8 +18,8 @@ class MomentFormatConverter { /** * This defines the mapping between PHP ICU date format (key) and moment.js date format (value) - * For ICU formats see http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax - * For Moment formats see http://momentjs.com/docs/#/displaying/format/. + * For ICU formats see https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax + * For Moment formats see http://momentjs.com/docs/#/displaying/format/ * * @var array */ @@ -34,6 +34,8 @@ class MomentFormatConverter 'ZZZZZ' => 'Z', 'ZZZ' => 'ZZ', // letter 'T' '\'T\'' => 'T', + // am/pm to AM/PM + 'a' => 'A', ]; /** diff --git a/templates/base.html.twig b/templates/base.html.twig index d0d1e924..4cf9edef 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -296,7 +296,7 @@ login: '{{ path('fos_user_security_login') }}', locale: '{{ app.request.locale }}', first_dow_iso: {{ iso_day_by_name(app.user.firstDayOfWeek) }}, - twentyFourHours: {{ 'true'|hour24('false') }}, + twentyFourHours: {{ app.user.is24Hour() ? 'true' : 'false' }}, autoComplete: {{ kimai_config.themeAutocompleteCharacters }}, defaultColor: '{{ constant('App\\Constants::DEFAULT_COLOR') }}', updateBrowserTitle: {% if app.user.preferenceValue('theme.update_browser_title') %}true{% else %}false{% endif %} diff --git a/templates/export/renderer/default.html.twig b/templates/export/renderer/default.html.twig index 6828b8da..81d9549c 100644 --- a/templates/export/renderer/default.html.twig +++ b/templates/export/renderer/default.html.twig @@ -309,7 +309,7 @@ |