From 3075b0a70dc337f75366f09baab89ecb9be88e8e Mon Sep 17 00:00:00 2001 From: Arnei Date: Thu, 19 Feb 2026 13:48:36 +0100 Subject: [PATCH] Unify date formatting, base it on locale This patch aims for a consistent date display across the entire ui. That it is not always consistent can be seen for example in the event details metadata, where the start date is formatted differently from the created date. Furthermore, this patch aims to base date formatting more on the chosen locale to create a more intuitive experience for users. No more A.M./P.M. in the german locale for example. To achieve this, date-fns is chosen as the gold standard and momentjs is removed from the project completely. Not only because moment is legacy, but also because our datepickers were using date-fns already and will not use anything else. Additionally, this removes our custom date formatting from the translation files and replaces it with date-fns tokens. In my opinion, we do not need to try and be smarter than our datetime library when it comes to formatting dates. Translators retain the ability to enforce their favourite formatting should they so chose, but will have to be aware that it will not be respect everywhere, e.g. not in the datepickers. This patch contains changes to all translation files. I am aware that everything except en_US will get overwritten, the changes to other languages are merely for ease of reviewing. If this patch is merged, the translations should be adapted asap as per this example. --- package-lock.json | 210 +++++++----------- package.json | 2 - .../EventDetailsSchedulingTab.tsx | 3 +- .../ModalTabsAndPages/NewSourcePage.tsx | 3 +- .../wizards/scheduling/SchedulingTime.tsx | 3 +- src/components/shared/TableFilters.tsx | 7 +- .../shared/TimeSeriesStatistics.tsx | 53 ++--- src/components/shared/wizard/RenderField.tsx | 5 +- .../systems/partials/MeanQueueTimeCell.tsx | 4 +- .../systems/partials/MeanRunTimeCell.tsx | 4 +- src/configs/statisticsConfig.ts | 4 +- src/i18n/i18n.ts | 11 +- .../adminui/languages/lang-am_ET.json | 18 +- .../adminui/languages/lang-cs_CZ.json | 18 +- .../adminui/languages/lang-da_DK.json | 18 +- .../adminui/languages/lang-de_DE.json | 18 +- .../adminui/languages/lang-el_GR.json | 18 +- .../adminui/languages/lang-en_GB.json | 18 +- .../adminui/languages/lang-en_US.json | 18 +- .../adminui/languages/lang-es_ES.json | 18 +- .../adminui/languages/lang-fi_FI.json | 18 +- .../adminui/languages/lang-fil_PH.json | 18 +- .../adminui/languages/lang-fr_FR.json | 18 +- .../adminui/languages/lang-gl_ES.json | 18 +- .../adminui/languages/lang-he_IL.json | 18 +- .../adminui/languages/lang-hi_IN.json | 18 +- .../adminui/languages/lang-id_ID.json | 18 +- .../adminui/languages/lang-it_IT.json | 18 +- .../adminui/languages/lang-ja_JP.json | 18 +- .../adminui/languages/lang-kn_IN.json | 18 +- .../adminui/languages/lang-ml_IN.json | 18 +- .../adminui/languages/lang-nl_NL.json | 18 +- .../adminui/languages/lang-no_NO.json | 18 +- .../adminui/languages/lang-pl_PL.json | 18 +- .../adminui/languages/lang-pt_BR.json | 18 +- .../adminui/languages/lang-pt_PT.json | 18 +- .../adminui/languages/lang-ru_RU.json | 18 +- .../adminui/languages/lang-si_LK.json | 18 +- .../adminui/languages/lang-sl_SI.json | 18 +- .../adminui/languages/lang-sv_SE.json | 18 +- .../adminui/languages/lang-ta_IN.json | 18 +- .../adminui/languages/lang-te_IN.json | 18 +- .../adminui/languages/lang-tl_PH.json | 18 +- .../adminui/languages/lang-tr_TR.json | 18 +- .../adminui/languages/lang-zh_CN.json | 18 +- .../adminui/languages/lang-zh_TW.json | 18 +- src/slices/eventSlice.ts | 5 +- src/slices/statisticsSlice.ts | 19 +- src/utils/dateUtils.ts | 74 ++++-- src/utils/eventDetailsUtils.ts | 18 +- src/utils/statisticsUtils.ts | 46 ++-- src/utils/utils.ts | 6 +- 52 files changed, 552 insertions(+), 537 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3638a2f84e..17a88cbde7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,8 +26,6 @@ "i18next-browser-languagedetector": "^8.2.1", "i18next-http-backend": "^3.0.2", "lodash": "^4.17.23", - "moment": "^2.30.1", - "moment-timezone": "^0.6.0", "react": "^19.2.4", "react-chartjs-2": "^5.3.1", "react-datepicker": "^8.8.0", @@ -79,11 +77,14 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" @@ -101,6 +102,7 @@ "version": "7.24.6", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.6", @@ -242,14 +244,18 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -264,33 +270,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.24.6", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.24.6", - "@babel/types": "^7.24.6" + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.24.7", + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/types": "^7.29.0" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.7", - "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -308,12 +308,14 @@ } }, "node_modules/@babel/template": { - "version": "7.24.7", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -339,12 +341,13 @@ } }, "node_modules/@babel/types": { - "version": "7.24.7", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -413,6 +416,7 @@ "node_modules/@emotion/react": { "version": "11.14.0", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", @@ -455,6 +459,7 @@ "version": "11.14.1", "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", + "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", @@ -1012,7 +1017,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.1", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1022,7 +1029,7 @@ "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", + "js-yaml": "^4.1.1", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, @@ -1247,8 +1254,7 @@ }, "node_modules/@kurkle/color": { "version": "0.3.2", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@mui/core-downloads-tracker": { "version": "7.3.8", @@ -2690,6 +2696,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -2699,6 +2706,7 @@ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -2775,6 +2783,7 @@ "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.56.0", "@typescript-eslint/types": "8.56.0", @@ -3145,6 +3154,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3175,16 +3185,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/argparse": { "version": "2.0.1", "dev": true, @@ -3390,7 +3390,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.11", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -3426,6 +3428,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001629", "electron-to-chromium": "^1.4.796", @@ -3468,12 +3471,14 @@ } }, "node_modules/call-bound": { - "version": "1.0.3", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -3559,18 +3564,6 @@ "node": ">=18" } }, - "node_modules/chalk": { - "version": "2.4.2", - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/chart.js": { "version": "4.3.0", "license": "MIT", @@ -3607,17 +3600,6 @@ "node": ">=6" } }, - "node_modules/color-convert": { - "version": "1.9.3", - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "license": "MIT" - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -4123,19 +4105,13 @@ "node": ">=6" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/eslint": { "version": "9.39.2", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -4191,7 +4167,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.37.4", + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", "dev": true, "license": "MIT", "dependencies": { @@ -4205,7 +4183,7 @@ "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.8", + "object.entries": "^1.1.9", "object.fromentries": "^2.0.8", "object.values": "^1.2.1", "prop-types": "^15.8.1", @@ -4768,13 +4746,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-flag": { - "version": "3.0.0", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/has-property-descriptors": { "version": "1.0.2", "dev": true, @@ -4897,6 +4868,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.28.4" }, @@ -5360,7 +5332,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -5469,7 +5443,9 @@ "license": "MIT" }, "node_modules/lodash-es": { - "version": "4.17.21", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz", + "integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==", "license": "MIT" }, "node_modules/lodash.merge": { @@ -5579,25 +5555,6 @@ "node": "*" } }, - "node_modules/moment": { - "version": "2.30.1", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/moment-timezone": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.6.0.tgz", - "integrity": "sha512-ldA5lRNm3iJCWZcBCab4pnNL3HSZYXVb/3TYr75/1WCTWYuTqYUb5f/S384pncYjJ88lbO8Z4uPDvmoluHJc8Q==", - "license": "MIT", - "dependencies": { - "moment": "^2.29.4" - }, - "engines": { - "node": "*" - } - }, "node_modules/ms": { "version": "2.1.3", "license": "MIT" @@ -5710,13 +5667,16 @@ } }, "node_modules/object.entries": { - "version": "1.1.8", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "es-object-atoms": "^1.1.1" }, "engines": { "node": ">= 0.4" @@ -6032,6 +5992,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -6210,7 +6171,8 @@ }, "node_modules/redux": { "version": "5.0.1", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/redux-persist": { "version": "6.0.0", @@ -6295,6 +6257,7 @@ "integrity": "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -6693,16 +6656,6 @@ "version": "4.2.0", "license": "MIT" }, - "node_modules/supports-color": { - "version": "5.5.0", - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "license": "MIT", @@ -6804,6 +6757,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -6821,13 +6775,6 @@ "node": ">=14.0.0" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "license": "MIT", @@ -6965,6 +6912,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -7125,6 +7073,7 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -7267,6 +7216,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, diff --git a/package.json b/package.json index ad0b798a4f..cec55c2e3e 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,6 @@ "i18next-browser-languagedetector": "^8.2.1", "i18next-http-backend": "^3.0.2", "lodash": "^4.17.23", - "moment": "^2.30.1", - "moment-timezone": "^0.6.0", "react": "^19.2.4", "react-chartjs-2": "^5.3.1", "react-datepicker": "^8.8.0", diff --git a/src/components/events/partials/ModalTabsAndPages/EventDetailsSchedulingTab.tsx b/src/components/events/partials/ModalTabsAndPages/EventDetailsSchedulingTab.tsx index 005301990a..86652f0e29 100644 --- a/src/components/events/partials/ModalTabsAndPages/EventDetailsSchedulingTab.tsx +++ b/src/components/events/partials/ModalTabsAndPages/EventDetailsSchedulingTab.tsx @@ -52,6 +52,7 @@ import SchedulingInputs from "../wizards/scheduling/SchedulingInputs"; import SchedulingConflicts from "../wizards/scheduling/SchedulingConflicts"; import { ParseKeys } from "i18next"; import ModalContentTable from "../../../shared/modals/ModalContentTable"; +import i18n from "../../../../i18n/i18n"; export type InitialValues = { scheduleStartDate: string; @@ -104,7 +105,7 @@ const EventDetailsSchedulingTab = ({ }, []); // Get info about the current language and its date locale - const currentLanguage = getCurrentLanguageInformation(); + const currentLanguage = getCurrentLanguageInformation(i18n.language); // Get timezone offset; Checks should be performed on UTC times const offset = getTimezoneOffset(); diff --git a/src/components/events/partials/ModalTabsAndPages/NewSourcePage.tsx b/src/components/events/partials/ModalTabsAndPages/NewSourcePage.tsx index c588b522b3..0d3998505f 100644 --- a/src/components/events/partials/ModalTabsAndPages/NewSourcePage.tsx +++ b/src/components/events/partials/ModalTabsAndPages/NewSourcePage.tsx @@ -49,6 +49,7 @@ import SchedulingInputs from "../wizards/scheduling/SchedulingInputs"; import SchedulingConflicts from "../wizards/scheduling/SchedulingConflicts"; import { ParseKeys } from "i18next"; import { LuCircleX } from "react-icons/lu"; +import i18n from "../../../../i18n/i18n"; /** * This component renders the source page for new events in the new event wizard. @@ -369,7 +370,7 @@ const Schedule = { const { t } = useTranslation(); - const currentLanguage = getCurrentLanguageInformation(); + const currentLanguage = getCurrentLanguageInformation(i18n.language); const dispatch = useAppDispatch(); // Parse start-Date strings diff --git a/src/components/events/partials/wizards/scheduling/SchedulingTime.tsx b/src/components/events/partials/wizards/scheduling/SchedulingTime.tsx index f7ba97fe48..4e5812400d 100644 --- a/src/components/events/partials/wizards/scheduling/SchedulingTime.tsx +++ b/src/components/events/partials/wizards/scheduling/SchedulingTime.tsx @@ -4,6 +4,7 @@ import { hours, minutes } from "../../../../../configs/modalConfig"; import { formatTimeForDropdown } from "../../../../../utils/dropDownUtils"; import { getCurrentLanguageInformation } from "../../../../../utils/utils"; import { ParseKeys } from "i18next"; +import i18n from "../../../../../i18n/i18n"; const SchedulingTime = ({ hour, @@ -28,7 +29,7 @@ const SchedulingTime = ({ }) => { const { t } = useTranslation(); // Get info about the current language and its date locale - const currentLanguage = getCurrentLanguageInformation(); + const currentLanguage = getCurrentLanguageInformation(i18n.language); return ( diff --git a/src/components/shared/TableFilters.tsx b/src/components/shared/TableFilters.tsx index 575797042a..e035deaee8 100644 --- a/src/components/shared/TableFilters.tsx +++ b/src/components/shared/TableFilters.tsx @@ -23,7 +23,6 @@ import { import TableFilterProfiles from "./TableFilterProfiles"; import { availableHotkeys } from "../../configs/hotkeysConfig"; import { useHotkeys } from "react-hotkeys-hook"; -import moment from "moment"; import { AppThunk, useAppDispatch, useAppSelector } from "../../store"; import { renderValidDate } from "../../utils/dateUtils"; import { getCurrentLanguageInformation } from "../../utils/utils"; @@ -35,6 +34,8 @@ import SearchContainer from "./SearchContainer"; import { Resource } from "../../slices/tableSlice"; import { HiFunnel } from "react-icons/hi2"; import { LuSettings, LuX } from "react-icons/lu"; +import { isValid } from "date-fns"; +import i18n from "../../i18n/i18n"; /** * This component renders the table filters in the upper right corner of the table @@ -202,7 +203,7 @@ const TableFilters = ({ }; const submitDateFilter = async (start: Date | undefined | null, end: Date | undefined | null) => { - if (start && end && moment(start).isValid() && moment(end).isValid()) { + if (start && end && isValid(start) && isValid(end)) { const filter = filterMap.find(({ name }) => name === selectedFilter); if (filter) { dispatch(editFilterValue({ @@ -488,7 +489,7 @@ const FilterSwitch = ({ popperPlacement="bottom" popperClassName="datepicker-custom" className="datepicker-custom-input" - locale={getCurrentLanguageInformation()?.dateLocale} + locale={getCurrentLanguageInformation(i18n.language)?.dateLocale} strictParsing /> diff --git a/src/components/shared/TimeSeriesStatistics.tsx b/src/components/shared/TimeSeriesStatistics.tsx index 1fa79e6135..e5cd729131 100644 --- a/src/components/shared/TimeSeriesStatistics.tsx +++ b/src/components/shared/TimeSeriesStatistics.tsx @@ -1,5 +1,4 @@ import { useState } from "react"; -import moment from "moment"; import { getCurrentLanguageInformation } from "../../utils/utils"; import DatePicker from "react-datepicker"; import { Formik, FormikErrors } from "formik"; @@ -11,7 +10,7 @@ import { statisticDateFormatStrings, statisticTimeModes, } from "../../configs/statisticsConfig"; -import { localizedMoment } from "../../utils/dateUtils"; +import { formatRangeEnd, formatRangeStart } from "../../utils/dateUtils"; import { useTranslation } from "react-i18next"; import type { ChartOptions } from "chart.js"; import { AsyncThunk } from "@reduxjs/toolkit"; @@ -19,6 +18,8 @@ import { useAppDispatch } from "../../store"; import { DataResolution, Statistics, TimeMode } from "../../slices/statisticsSlice"; import { ParseKeys } from "i18next"; import { LuChevronLeft, LuChevronRight, LuDownload } from "react-icons/lu"; +import { add, format, parseISO, sub } from "date-fns"; +import i18n from "../../i18n/i18n"; /** @@ -73,12 +74,17 @@ const TimeSeriesStatistics = ({ const formatStrings = statisticDateFormatStrings; // Get info about the current language and its date locale - const currentLanguage = getCurrentLanguageInformation(); + const currentLanguage = getCurrentLanguageInformation(i18n.language); // Set the date for the react-datepicker const [startDatepicker, setStartDatepicker] = useState(fromDate ? new Date(fromDate) : null); const [endDatepicker, setEndDatepicker] = useState(toDate ? new Date(toDate) : null); + const unitMap = { + year: "years", + month: "months", + } as const; + // change formik values and get new statistic values from API const change = ( setFormikValue: (field: string, value: any) => Promise>, @@ -88,8 +94,8 @@ const TimeSeriesStatistics = ({ dataResolution: DataResolution, ) => { if (timeMode === "year" || timeMode === "month") { - from = moment(from).clone().startOf(timeMode).format("YYYY-MM-DD"); - to = moment(from).clone().endOf(timeMode).format("YYYY-MM-DD"); + from = formatRangeStart(from, timeMode); + to = formatRangeEnd(from, timeMode); setStartDatepicker(new Date(from)); setEndDatepicker(new Date(to)); setFormikValue("fromDate", from); @@ -129,9 +135,8 @@ const TimeSeriesStatistics = ({ from: string, timeMode: keyof typeof formatStrings, ) => { - return localizedMoment(from, currentLanguage ? currentLanguage.dateLocale.code : "en").format( - formatStrings[timeMode], - ); + const locale = currentLanguage?.dateLocale; + return format(parseISO(from), formatStrings[timeMode], { locale }); }; // change to and from dates in formik to previous timeframe and get new values from API @@ -141,10 +146,11 @@ const TimeSeriesStatistics = ({ timeMode: TimeMode, dataResolution: DataResolution, ) => { - const newFrom = moment(from) - // According to the moment.js docs, string is supported as a second argument here - .subtract(1, timeMode + "s" as moment.unitOfTime.DurationConstructor) - .format("YYYY-MM-DD"); + if (timeMode === "custom") { return; } + + const date = parseISO(from); + const newFromDate = sub(date, { [unitMap[timeMode]]: 1 }); + const newFrom = format(newFromDate, "yyyy-MM-dd"); const to = newFrom; change(setFormikValue, timeMode, newFrom, to, dataResolution); }; @@ -156,10 +162,11 @@ const TimeSeriesStatistics = ({ timeMode: TimeMode, dataResolution: DataResolution, ) => { - const newFrom = moment(from) - // According to the moment.js docs, string is supported as a second argument here - .add(1, timeMode + "s" as moment.unitOfTime.DurationConstructor) - .format("YYYY-MM-DD"); + if (timeMode === "custom") { return; } + + const date = parseISO(from); + const newFromDate = add(date, { [unitMap[timeMode]]: 1 }); + const newFrom = format(newFromDate, "yyyy-MM-dd"); const to = newFrom; change(setFormikValue, timeMode, newFrom, to, dataResolution); }; @@ -171,12 +178,8 @@ const TimeSeriesStatistics = ({ initialValues={{ timeMode: timeMode, dataResolution: dataResolution, - // Typescript complains that the method "startOf" cannot take "custom" as a parameter, but in practice - // this does not seem to be a problem - // @ts-expect-error: timeMode should be assignable here - fromDate: moment(fromDate).startOf(timeMode).format("YYYY-MM-DD"), - // @ts-expect-error: timeMode should be assignable here - toDate: moment(toDate).endOf(timeMode).format("YYYY-MM-DD"), + fromDate: formatRangeStart(fromDate, timeMode), + toDate: formatRangeEnd(toDate, timeMode), }} onSubmit={() => {}} > @@ -282,8 +285,8 @@ const TimeSeriesStatistics = ({ const [startDate, endDate] = dates; setStartDatepicker(startDate); setEndDatepicker(endDate); - const newStartDate = startDate ? moment(startDate).format("YYYY-MM-DD") : formik.values.fromDate; - const newEndDate = endDate ? moment(endDate).format("YYYY-MM-DD") : formik.values.toDate; + const newStartDate = startDate ? format(startDate, "yyyy-MM-dd") : formik.values.fromDate; + const newEndDate = endDate ? format(endDate, "yyyy-MM-dd") : formik.values.toDate; change( formik.setFieldValue, formik.values.timeMode, @@ -304,7 +307,7 @@ const TimeSeriesStatistics = ({ popperPlacement="bottom" popperClassName="datepicker-custom" className="datepicker-custom-input" - locale={getCurrentLanguageInformation()?.dateLocale} + locale={getCurrentLanguageInformation(i18n.language)?.dateLocale} strictParsing /> diff --git a/src/components/shared/wizard/RenderField.tsx b/src/components/shared/wizard/RenderField.tsx index 3e031d86af..e9e561395f 100644 --- a/src/components/shared/wizard/RenderField.tsx +++ b/src/components/shared/wizard/RenderField.tsx @@ -12,6 +12,7 @@ import { GroupBase, SelectInstance } from "react-select"; import TextareaAutosize from "react-textarea-autosize"; import { LuCheck, LuSquarePen } from "react-icons/lu"; import axios from "axios"; +import i18n from "../../../i18n/i18n"; /** * This component renders an editable field for single values depending on the type of the corresponding metadata @@ -188,7 +189,7 @@ const EditableDateValue = ({ popperClassName="datepicker-custom" className="datepicker-custom-input" wrapperClassName="datepicker-custom-wrapper" - locale={getCurrentLanguageInformation()?.dateLocale} + locale={getCurrentLanguageInformation(i18n.language)?.dateLocale} strictParsing autoFocus={isFirstField} /> @@ -319,7 +320,7 @@ const EditableSingleValueTime = ({ popperClassName="datepicker-custom" className="datepicker-custom-input" wrapperClassName="datepicker-custom-wrapper" - locale={getCurrentLanguageInformation()?.dateLocale} + locale={getCurrentLanguageInformation(i18n.language)?.dateLocale} strictParsing autoFocus={isFirstField} /> diff --git a/src/components/systems/partials/MeanQueueTimeCell.tsx b/src/components/systems/partials/MeanQueueTimeCell.tsx index d49bfbedd4..2574d8a72f 100644 --- a/src/components/systems/partials/MeanQueueTimeCell.tsx +++ b/src/components/systems/partials/MeanQueueTimeCell.tsx @@ -1,5 +1,5 @@ import { Service } from "../../../slices/serviceSlice"; -import moment from "moment"; +import { formatHMS } from "../../../utils/dateUtils"; /** * This component renders the mean queue time cells of systems in the table view @@ -12,7 +12,7 @@ const MeanQueueTimeCell = ({ return ( - { moment.utc(moment.duration(row.meanQueueTime * 1000).asMilliseconds()).format("HH:mm:ss") } + {formatHMS(row.meanQueueTime)} ); }; diff --git a/src/components/systems/partials/MeanRunTimeCell.tsx b/src/components/systems/partials/MeanRunTimeCell.tsx index 1b1d2c6ede..f7221f1a20 100644 --- a/src/components/systems/partials/MeanRunTimeCell.tsx +++ b/src/components/systems/partials/MeanRunTimeCell.tsx @@ -1,5 +1,5 @@ import { Service } from "../../../slices/serviceSlice"; -import moment from "moment"; +import { formatHMS } from "../../../utils/dateUtils"; /** * This component renders the mean run time cells of systems in the table view @@ -12,7 +12,7 @@ const MeanRunTimeCell = ({ return ( - { moment.utc(moment.duration(row.meanRunTime * 1000).asMilliseconds()).format("HH:mm:ss") } + {formatHMS(row.meanQueueTime)} ); }; diff --git a/src/configs/statisticsConfig.ts b/src/configs/statisticsConfig.ts index daa0918148..a33bda8bcb 100644 --- a/src/configs/statisticsConfig.ts +++ b/src/configs/statisticsConfig.ts @@ -42,6 +42,6 @@ export const availableCustomStatisticDataResolutions = [ // date format strings export const statisticDateFormatStrings = { - month: "MMMM YYYY", - year: "YYYY", + month: "MMMM yyyy", + year: "yyyy", }; diff --git a/src/i18n/i18n.ts b/src/i18n/i18n.ts index 5184fbb1a6..0c6af4e310 100644 --- a/src/i18n/i18n.ts +++ b/src/i18n/i18n.ts @@ -1,6 +1,5 @@ import i18n from "i18next"; import { initReactI18next } from "react-i18next"; -import moment from "moment"; import HttpBackend, { HttpBackendOptions } from "i18next-http-backend"; import LanguageDetector from "i18next-browser-languagedetector"; @@ -23,6 +22,8 @@ import svSETrans from "./org/opencastproject/adminui/languages/lang-sv_SE.json"; import trTRTrans from "./org/opencastproject/adminui/languages/lang-tr_TR.json"; import zhCNTrans from "./org/opencastproject/adminui/languages/lang-zh_CN.json"; import zhTWTrans from "./org/opencastproject/adminui/languages/lang-zh_TW.json"; +import { getCurrentLanguageInformation } from "../utils/utils"; +import { format } from "date-fns/format"; // Assignment of language code to translation file // !!! If translation file of a new language is added, please add assignment here, too !!! @@ -58,9 +59,11 @@ i18n interpolation: { escapeValue: false, - format: function (value, format, _lng) { - if (value instanceof Date) { - return moment(value).format(format); + format: function (value, formatStr, lng) { + if (value instanceof Date && formatStr && lng) { + return format(value, formatStr, { + locale: getCurrentLanguageInformation(lng)?.dateLocale, + }); } // eslint-disable-next-line @typescript-eslint/no-unsafe-return diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-am_ET.json b/src/i18n/org/opencastproject/adminui/languages/lang-am_ET.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-am_ET.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-am_ET.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-cs_CZ.json b/src/i18n/org/opencastproject/adminui/languages/lang-cs_CZ.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-cs_CZ.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-cs_CZ.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-da_DK.json b/src/i18n/org/opencastproject/adminui/languages/lang-da_DK.json index 4c29a101eb..67a13c0935 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-da_DK.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-da_DK.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-de_DE.json b/src/i18n/org/opencastproject/adminui/languages/lang-de_DE.json index fe3c20f371..61e03b4d01 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-de_DE.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-de_DE.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, DD.MM.YY HH:mm}}", - "medium": "{{dateTime, DD.MM.YYYY HH:mm:ss}}", - "full": "{{dateTime, dddd, D. MMMM YYYY HH:mm [Uhr] z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, DD.MM.YY}}", - "medium": "{{date, DD.MM.YYYY}}", - "full": "{{date, dddd, D. MMMM YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, HH:mm}}", - "medium": "{{time, HH:mm:ss}}", - "full": "{{time, HH:mm [Uhr] z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-el_GR.json b/src/i18n/org/opencastproject/adminui/languages/lang-el_GR.json index 2840b902ae..2de922d7c7 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-el_GR.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-el_GR.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, D\/M\/YYYY h:mm a}}", - "medium": "{{dateTime, D MMM YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, D MMMM YYYY h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, D\/M\/YYYY}}", - "medium": "{{date, D MMM YYYY}}", - "full": "{{date, dddd, D MMMM YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-en_GB.json b/src/i18n/org/opencastproject/adminui/languages/lang-en_GB.json index d67f769fc4..9637241136 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-en_GB.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-en_GB.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-en_US.json b/src/i18n/org/opencastproject/adminui/languages/lang-en_US.json index 91ba02dac7..7067ceb80d 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-en_US.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-en_US.json @@ -2150,19 +2150,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M/D/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M/D/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-es_ES.json b/src/i18n/org/opencastproject/adminui/languages/lang-es_ES.json index 23eeb27880..b3bf8c62a3 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-es_ES.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-es_ES.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-fi_FI.json b/src/i18n/org/opencastproject/adminui/languages/lang-fi_FI.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-fi_FI.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-fi_FI.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-fil_PH.json b/src/i18n/org/opencastproject/adminui/languages/lang-fil_PH.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-fil_PH.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-fil_PH.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-fr_FR.json b/src/i18n/org/opencastproject/adminui/languages/lang-fr_FR.json index 46e5e0ad90..644ee93428 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-fr_FR.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-fr_FR.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, DD\/MM\/YY HH:mm}}", - "medium": "{{dateTime, D MMM YYYY HH:mm:ss}}", - "full": "{{dateTime, dddd D MMMM YYYY HH [h] mm z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, DD\/MM\/YY}}", - "medium": "{{date, D MMM YYYY}}", - "full": "{{date, dddd D MMMM YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, HH:mm}}", - "medium": "{{time, HH:mm:ss}}", - "full": "{{time, HH [h] mm z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-gl_ES.json b/src/i18n/org/opencastproject/adminui/languages/lang-gl_ES.json index d2ab5265b2..788f854256 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-gl_ES.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-gl_ES.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, YYYY h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-he_IL.json b/src/i18n/org/opencastproject/adminui/languages/lang-he_IL.json index a78cdb4bb8..fb217e54c1 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-he_IL.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-he_IL.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, HH:mm DD\/MM\/YY}}", - "medium": "{{dateTime, HH:mm:ss DD\/MM\/YYYY}}", - "full": "{{dateTime, HH:mm:ss z dddd D MMMM YYYY}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, DD\/MM\/YY}}", - "medium": "{{date, DD\/MM\/YYYY}}", - "full": "{{date, dddd D MMMM YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, HH:mm}}", - "medium": "{{time, HH:mm:ss}}", - "full": "{{time, HH:mm:ss z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-hi_IN.json b/src/i18n/org/opencastproject/adminui/languages/lang-hi_IN.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-hi_IN.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-hi_IN.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-id_ID.json b/src/i18n/org/opencastproject/adminui/languages/lang-id_ID.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-id_ID.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-id_ID.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-it_IT.json b/src/i18n/org/opencastproject/adminui/languages/lang-it_IT.json index 200b6d81df..70cf820174 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-it_IT.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-it_IT.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, DD\/MM\/YY H.mm}}", - "medium": "{{dateTime, D-MMM-YYYY H.mm.ss}}", - "full": "{{dateTime, dddd D MMMM YYYY H.mm.ss z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, DD\/MM\/YY}}", - "medium": "{{date, D-MMM-YYYY}}", - "full": "{{date, dddd D MMMM YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, H.mm}}", - "medium": "{{time, H.mm.ss}}", - "full": "{{time, H.mm.ss z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-ja_JP.json b/src/i18n/org/opencastproject/adminui/languages/lang-ja_JP.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-ja_JP.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-ja_JP.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-kn_IN.json b/src/i18n/org/opencastproject/adminui/languages/lang-kn_IN.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-kn_IN.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-kn_IN.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-ml_IN.json b/src/i18n/org/opencastproject/adminui/languages/lang-ml_IN.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-ml_IN.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-ml_IN.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-nl_NL.json b/src/i18n/org/opencastproject/adminui/languages/lang-nl_NL.json index 319b4766dc..10893ee718 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-nl_NL.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-nl_NL.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, DD-MM-YY HH:mm}}", - "medium": "{{dateTime, DD-MM-YYYY HH:mm:ss}}", - "full": "{{dateTime, D. MMMM YYYY HH:mm:ss z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, DD-MM-YY}}", - "medium": "{{date, DD-MM-YYYY}}", - "full": "{{date, D. MMMM YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, HH:mm}}", - "medium": "{{time, HH:mm:ss}}", - "full": "{{time, HH:mm:ss z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-no_NO.json b/src/i18n/org/opencastproject/adminui/languages/lang-no_NO.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-no_NO.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-no_NO.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-pl_PL.json b/src/i18n/org/opencastproject/adminui/languages/lang-pl_PL.json index 3325cb2297..ee8de325f3 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-pl_PL.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-pl_PL.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, DD.MM.YY HH:mm}}", - "medium": "{{dateTime, YYYY-MM-DD HH:mm:ss}}", - "full": "{{dateTime, dddd, D MMMM YYYY HH:mm:ss z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, DD.MM.YY}}", - "medium": "{{date, YYYY-MM-DD}}", - "full": "{{date, dddd, D MMMM YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, HH:mm}}", - "medium": "{{time, HH:mm:ss}}", - "full": "{{time, HH:mm:ss z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-pt_BR.json b/src/i18n/org/opencastproject/adminui/languages/lang-pt_BR.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-pt_BR.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-pt_BR.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-pt_PT.json b/src/i18n/org/opencastproject/adminui/languages/lang-pt_PT.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-pt_PT.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-pt_PT.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-ru_RU.json b/src/i18n/org/opencastproject/adminui/languages/lang-ru_RU.json index 7a45f1dbdf..cefe17fdd8 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-ru_RU.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-ru_RU.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-si_LK.json b/src/i18n/org/opencastproject/adminui/languages/lang-si_LK.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-si_LK.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-si_LK.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-sl_SI.json b/src/i18n/org/opencastproject/adminui/languages/lang-sl_SI.json index 946e666214..9a3325fb8c 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-sl_SI.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-sl_SI.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, D.M.Y H:mm}}", - "medium": "{{dateTime, D.M.YYYY H:mm:ss}}", - "full": "{{dateTime, dddd, DD. MMMM Y H:mm:ss z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, D.M.Y}}", - "medium": "{{date, D.M.YYYY}}", - "full": "{{date, dddd, DD. MMMM Y}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, H:mm}}", - "medium": "{{time, H:mm:ss}}", - "full": "{{time, H:mm:ss z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-sv_SE.json b/src/i18n/org/opencastproject/adminui/languages/lang-sv_SE.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-sv_SE.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-sv_SE.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-ta_IN.json b/src/i18n/org/opencastproject/adminui/languages/lang-ta_IN.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-ta_IN.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-ta_IN.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-te_IN.json b/src/i18n/org/opencastproject/adminui/languages/lang-te_IN.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-te_IN.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-te_IN.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-tl_PH.json b/src/i18n/org/opencastproject/adminui/languages/lang-tl_PH.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-tl_PH.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-tl_PH.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-tr_TR.json b/src/i18n/org/opencastproject/adminui/languages/lang-tr_TR.json index 8e1bf17e41..85301452c9 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-tr_TR.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-tr_TR.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, DD.MM.YYYY HH:mm}}", - "medium": "{{dateTime, DD.MMM.YYYY HH:mm:ss}}", - "full": "{{dateTime, DD MMMM YYYY dddd HH:mm:ss z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, DD.MM.YYYY}}", - "medium": "{{date, DD.MMM.YYYY}}", - "full": "{{date, DD MMMM YYYY dddd}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, HH:mm}}", - "medium": "{{time, HH:mm:ss}}", - "full": "{{time, HH:mm:ss z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-zh_CN.json b/src/i18n/org/opencastproject/adminui/languages/lang-zh_CN.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-zh_CN.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-zh_CN.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-zh_TW.json b/src/i18n/org/opencastproject/adminui/languages/lang-zh_TW.json index 51bcd6b3be..585366348b 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-zh_TW.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-zh_TW.json @@ -2147,19 +2147,19 @@ }, "dateFormats": { "dateTime": { - "short": "{{dateTime, M\/D\/YY h:mm a}}", - "medium": "{{dateTime, MMM D, YYYY h:mm:ss a}}", - "full": "{{dateTime, dddd, MMMM D, yyyy h:mm:ss a z}}" + "short": "{{dateTime, Pp}}", + "medium": "{{dateTime, PPp}}", + "full": "{{dateTime, PPPPp}}" }, "date": { - "short": "{{date, M\/D\/YY}}", - "medium": "{{date, MMM D, YYYY}}", - "full": "{{date, dddd, MMMM D, YYYY}}" + "short": "{{date, P}}", + "medium": "{{date, PP}}", + "full": "{{date, PPPPP}}" }, "time": { - "short": "{{time, h:mm a}}", - "medium": "{{time, h:mm:ss a}}", - "full": "{{time, h:mm:ss a z}}" + "short": "{{time, p}}", + "medium": "{{time, pp}}", + "full": "{{time, ppp}}" } }, "ABOUT": { diff --git a/src/slices/eventSlice.ts b/src/slices/eventSlice.ts index 61b87731ce..337d961397 100644 --- a/src/slices/eventSlice.ts +++ b/src/slices/eventSlice.ts @@ -1,7 +1,6 @@ import { PayloadAction, SerializedError, createSlice } from "@reduxjs/toolkit"; import { eventsTableConfig } from "../configs/tableConfigs/eventsTableConfig"; import axios, { AxiosError, AxiosProgressEvent } from "axios"; -import moment from "moment-timezone"; import { getURLParams, prepareAccessPolicyRulesForPost, @@ -809,7 +808,7 @@ export const updateScheduledEventsBulk = (values: { }): AppThunk => dispatch => { const formData = new FormData(); const update = []; - const timezone = moment.tz.guess(); + const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; for (const changedEvent of values.changedEvents) { const eventChanges = values.editedEvents.find( @@ -1076,7 +1075,7 @@ export const checkForConflicts = async ( export const checkForSchedulingConflicts = (events: EditedEvents[]) => (dispatch: AppDispatch) => { const formData = new FormData(); const update = []; - const timezone = moment.tz.guess(); + const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; for (const event of events) { update.push({ events: [event.eventId], diff --git a/src/slices/statisticsSlice.ts b/src/slices/statisticsSlice.ts index 1b4e685ffe..af4217598f 100644 --- a/src/slices/statisticsSlice.ts +++ b/src/slices/statisticsSlice.ts @@ -1,12 +1,12 @@ import { PayloadAction, SerializedError, createSlice } from "@reduxjs/toolkit"; import axios from "axios"; -import moment from "moment"; import { createDownloadUrl, } from "../utils/statisticsUtils"; import { getHttpHeaders } from "../utils/resourceUtils"; import { getStatistics } from "../selectors/statisticsSelectors"; import { createAppAsyncThunk } from "../createAsyncThunkWithTypes"; +import { endOfDay, endOfYear, format, parseISO, startOfYear } from "date-fns"; /** * This file contains redux reducer for actions affecting the state of statistics @@ -107,8 +107,9 @@ export const fetchStatistics = async (resourceId: string, resourceType: string, // default values to use, when statistics are viewed the first time const originalDataResolution = "monthly"; const originalTimeMode = "year"; - const originalFrom = moment().startOf(originalTimeMode); - const originalTo = moment().endOf(originalTimeMode); + const now = new Date(); + const originalFrom = startOfYear(now); + const originalTo = endOfYear(now); // iterate over statistics providers for (let i = 0; i < response.data.length; i++) { @@ -140,8 +141,8 @@ export const fetchStatistics = async (resourceId: string, resourceType: string, timeMode = statistics[i].timeMode; dataResolution = statistics[i].dataResolution; } else { - from = originalFrom.format("YYYY-MM-DD"); - to = originalTo.format("YYYY-MM-DD"); + from = format(originalFrom, "yyyy-MM-dd"); + to = format(originalTo, "yyyy-MM-dd"); timeMode = originalTimeMode; dataResolution = originalDataResolution; } @@ -172,8 +173,8 @@ export const fetchStatistics = async (resourceId: string, resourceType: string, // add settings for this statistic of this resource to value request statisticsValueRequest.push({ dataResolution: dataResolution, - from: moment(from), - to: moment(to).endOf("day"), + from: parseISO(from), + to: endOfDay(parseISO(to)), resourceId: resourceId, providerId: response.data[i].providerId, }); @@ -242,8 +243,8 @@ export const fetchStatisticsValueUpdate = async ( const statisticsValueRequest = [ { dataResolution: dataResolution, - from: moment(from), - to: moment(to).endOf("day"), + from: from instanceof Date ? from : parseISO(from), + to: to instanceof Date ? endOfDay(to) : endOfDay(parseISO(to)), resourceId: resourceId, providerId: providerId, }, diff --git a/src/utils/dateUtils.ts b/src/utils/dateUtils.ts index cdb6adff4b..34d46529f4 100644 --- a/src/utils/dateUtils.ts +++ b/src/utils/dateUtils.ts @@ -1,6 +1,7 @@ -import moment from "moment"; import { makeTwoDigits } from "./utils"; import { FormikErrors } from "formik"; +import { TimeMode } from "../slices/statisticsSlice"; +import { addDays, addMonths, addYears, endOfDay, endOfMonth, endOfYear, format, parseISO, startOfDay, startOfMonth, startOfYear } from "date-fns"; /** * This File contains methods concerning dates @@ -13,18 +14,31 @@ export const renderValidDate = (date: string) => { // transform relative date to an absolute date export const relativeToAbsoluteDate = (relative: string, type: string, from: boolean) => { - const localMoment = moment(); + const now = new Date(); + const amount = Number(relative); + const assumedType = type as "year" | "month" | "day"; + + const startMap = { + year: startOfYear, + month: startOfMonth, + day: startOfDay, + }; - let absolute; - if (from) { - absolute = localMoment.startOf(type as moment.unitOfTime.StartOf); - } else { - absolute = localMoment.endOf(type as moment.unitOfTime.StartOf); - } + const endMap = { + year: endOfYear, + month: endOfMonth, + day: endOfDay, + }; + + const addMap = { + year: addYears, + month: addMonths, + day: addDays, + }; - absolute = absolute.add(relative, type as moment.unitOfTime.Base); + const base = (from ? startMap[assumedType] : endMap[assumedType])(now); - return absolute.toDate(); + return addMap[assumedType](base, amount); }; type RelativeDateSpanValue = { @@ -763,7 +777,41 @@ export const changeDurationMinuteMultiple = ( setFieldValue("scheduleDurationMinutes", value); }; -// get localized time -export const localizedMoment = (m: string, currentLanguageCode: string) => { - return moment(m).locale(currentLanguageCode); +const getRangeDates = (dateStr: string, mode: TimeMode) => { + const base = parseISO(dateStr); + + if (mode === "year") { + return { + from: startOfYear(base), + to: endOfYear(base), + }; + } + + if (mode === "month") { + return { + from: startOfMonth(base), + to: endOfMonth(base), + }; + } + + return { + from: base, + to: base, + }; +}; + +export const formatRangeStart = (d: string, mode: TimeMode) => + format(getRangeDates(d, mode).from, "yyyy-MM-dd"); + +export const formatRangeEnd = (d: string, mode: TimeMode) => + format(getRangeDates(d, mode).to, "yyyy-MM-dd"); + +export const formatHMS = (totalSeconds: number): string => { + const hours = Math.floor(totalSeconds / 3600); + const minutes = Math.floor((totalSeconds % 3600) / 60); + const seconds = Math.floor(totalSeconds % 60); + + return [hours, minutes, seconds] + .map(s => String(s).padStart(2, "0")) + .join(":"); }; diff --git a/src/utils/eventDetailsUtils.ts b/src/utils/eventDetailsUtils.ts index c5df1e9a96..c53b76d6f9 100644 --- a/src/utils/eventDetailsUtils.ts +++ b/src/utils/eventDetailsUtils.ts @@ -1,16 +1,22 @@ -import moment from "moment"; import { Event } from "../slices/eventSlice"; /** * This file contains functions and constants that are needed in the event details modal */ export const formatDuration = (durationInMS: number) => { - const duration = moment.duration(durationInMS); - if (duration.asHours() > 1) { - return moment.utc(duration.asMilliseconds()).format("HH:mm:ss"); - } else { - return moment.utc(duration.asMilliseconds()).format("mm:ss"); + const totalSeconds = Math.floor(durationInMS / 1000); + + const hours = Math.floor(totalSeconds / 3600); + const minutes = Math.floor((totalSeconds % 3600) / 60); + const seconds = totalSeconds % 60; + + const pad = (n: number) => n.toString().padStart(2, "0"); + + if (hours > 0) { + return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`; } + + return `${pad(minutes)}:${pad(seconds)}`; }; export const humanReadableBytesFilter = (bytesValue: string | number) => { diff --git a/src/utils/statisticsUtils.ts b/src/utils/statisticsUtils.ts index 85d5faca4b..195981742a 100644 --- a/src/utils/statisticsUtils.ts +++ b/src/utils/statisticsUtils.ts @@ -1,8 +1,8 @@ -import moment from "moment"; -import "moment/min/locales.min"; import { getCurrentLanguageInformation } from "./utils"; import { DataResolution, TimeMode } from "../slices/statisticsSlice"; import type { ChartOptions, TooltipItem } from "chart.js"; +import i18n from "../i18n/i18n"; +import { endOfDay, format, parseISO } from "date-fns"; /** * This file contains functions that are needed for thunks for statistics @@ -14,31 +14,32 @@ function createXAxisTickCallback( dataResolution: DataResolution, language: string, ) { - let formatString = "L"; + let formatString = "P"; if (timeMode === "year") { formatString = "MMMM"; } else if (timeMode === "month") { - formatString = "dddd, Do"; + formatString = "EEEE, Do"; } else { if (dataResolution === "yearly") { - formatString = "YYYY"; + formatString = "yyyy"; } else if (dataResolution === "monthly") { formatString = "MMMM"; } else if (dataResolution === "daily") { if (language === "en-US" || language === "en-GB") { - formatString = "MMMM Do, YYYY"; + formatString = "MMMM do, yyyy"; } else { - formatString = "Do MMMM YYYY"; + formatString = "do MMMM yyyy"; } } else if (dataResolution === "hourly") { - formatString = "LLL"; + formatString = "PPp"; } } return function (tickValue: number | string) { + const locale = getCurrentLanguageInformation(language)?.dateLocale; // @ts-expect-error: Typescript does not like "this", but the chart.js documentation insists we should do it this way // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access - return moment(this.getLabelForValue(tickValue)).locale(language).format(formatString); + return format(parseISO(this.getLabelForValue(tickValue)), formatString, { locale }); }; }; @@ -50,36 +51,37 @@ const createTooltipCallback = ( ) => { let formatString; if (timeMode === "year") { - formatString = "MMMM YYYY"; + formatString = "MMMM yyyy"; } else if (timeMode === "month") { if (language === "en-US" || language === "en-GB") { - formatString = "dddd, MMMM Do, YYYY"; + formatString = "EEEE, MMMM do, yyyy"; } else { - formatString = "dddd, Do MMMM YYYY"; + formatString = "EEEE, do MMMM yyyy"; } } else { if (dataResolution === "yearly") { - formatString = "YYYY"; + formatString = "yyyy"; } else if (dataResolution === "monthly") { - formatString = "MMMM YYYY"; + formatString = "MMMM yyyy"; } else if (dataResolution === "daily") { if (language === "en-US" || language === "en-GB") { - formatString = "dddd, MMMM Do, YYYY"; + formatString = "EEEE, MMMM do, yyyy"; } else { - formatString = "dddd, Do MMMM YYYY"; + formatString = "EEEE, do MMMM yyyy"; } } else { if (language === "en-US" || language === "en-GB") { - formatString = "dddd, MMMM Do, YYYY HH:mm"; + formatString = "EEEE, MMMM do, yyyy HH:mm"; } else { - formatString = "dddd, Do MMMM YYYY, HH:mm"; + formatString = "EEEE, do MMMM yyyy, HH:mm"; } } } return (tooltipItem: TooltipItem<"bar">) => { const date = tooltipItem.label; - const finalDate = moment(date).locale(language).format(formatString); + const locale = getCurrentLanguageInformation(language)?.dateLocale; + const finalDate = format(parseISO(date), formatString, { locale }); return finalDate + ": " + tooltipItem.formattedValue; }; }; @@ -90,7 +92,7 @@ export const createChartOptions = ( dataResolution: DataResolution, ): ChartOptions<"bar"> => { // Get info about the current language and its date locale - const currentLanguageInfo = getCurrentLanguageInformation(); + const currentLanguageInfo = getCurrentLanguageInformation(i18n.language); let currentLanguage = ""; if (currentLanguageInfo) { currentLanguage = currentLanguageInfo.dateLocale.code; @@ -149,8 +151,8 @@ export const createDownloadUrl = ( providerId: providerId, resourceId: resourceId, resourceType: resourceType, - from: moment(from).toJSON(), - to: moment(to).endOf("day").toJSON(), + from: from instanceof Date ? from.toISOString() : parseISO(from).toISOString(), + to: to instanceof Date ? endOfDay(to).toISOString() : endOfDay(parseISO(to)).toISOString(), }); return "/admin-ng/statistics/export.csv?" + csvUrlSearchParams.toString(); diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 178e6d5847..32b6c1dc16 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -19,12 +19,12 @@ export const getTimezoneString = (offset: number) => { return "UTC" + (offset < 0 ? "-" : "+") + offset; }; -export const getCurrentLanguageInformation = () => { +export const getCurrentLanguageInformation = (languageCode: string) => { // Get code, flag, name and date locale of the current language - let currentLang = languages.find(({ code }) => code === i18n.language); + let currentLang = languages.find(({ code }) => code === languageCode); if (typeof currentLang === "undefined") { // If detected language code, like "de-CH", isn't part of translations try 2-digit language code - currentLang = languages.find(({ code }) => code === i18n.language.split("-")[0]); + currentLang = languages.find(({ code }) => code === languageCode.split("-")[0]); if (typeof currentLang === "undefined") { currentLang = languages.find(({ code }) => code === "en-US"); }