From db51f7f103bbbd6c91c8f47d75b3482ef8939691 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 17 Dec 2023 15:32:20 +0100 Subject: Adding upstream version 3.0.0. Signed-off-by: Daniel Baumann --- .flake8 | 28 - .github/workflows/codspeed.yml | 52 + .github/workflows/release.yml | 98 +- .github/workflows/tests.yml | 31 +- .gitignore | 2 + .pre-commit-config.yaml | 62 +- CHANGELOG.md | 39 +- Makefile | 47 +- README.rst | 22 +- build-wheels.sh | 27 - build.py | 33 - clock | 12 +- codecov.yml | 7 - docs/docs/difference.md | 2 +- docs/docs/index.md | 2 +- docs/docs/installation.md | 20 + docs/docs/interval.md | 168 +++ docs/docs/introduction.md | 2 +- docs/docs/limitations.md | 4 +- docs/docs/period.md | 168 --- docs/docs/testing.md | 94 +- docs/docs/timezones.md | 2 +- meson.build | 20 - pendulum/__init__.py | 363 ----- pendulum/__version__.py | 1 - pendulum/_extensions/__init__.py | 0 pendulum/_extensions/_helpers.c | 931 ------------- pendulum/_extensions/_helpers.pyi | 31 - pendulum/_extensions/helpers.py | 364 ----- pendulum/constants.py | 109 -- pendulum/date.py | 760 ----------- pendulum/datetime.py | 1381 ------------------- pendulum/duration.py | 502 ------- pendulum/exceptions.py | 8 - pendulum/formatting/__init__.py | 5 - pendulum/formatting/difference_formatter.py | 146 -- pendulum/formatting/formatter.py | 683 ---------- pendulum/helpers.py | 223 --- pendulum/interval.py | 448 ------ pendulum/locales/__init__.py | 0 pendulum/locales/cs/__init__.py | 0 pendulum/locales/cs/custom.py | 23 - pendulum/locales/cs/locale.py | 266 ---- pendulum/locales/da/__init__.py | 0 pendulum/locales/da/custom.py | 18 - pendulum/locales/da/locale.py | 147 -- pendulum/locales/de/__init__.py | 0 pendulum/locales/de/custom.py | 36 - pendulum/locales/de/locale.py | 144 -- pendulum/locales/en/__init__.py | 0 pendulum/locales/en/custom.py | 23 - pendulum/locales/en/locale.py | 150 -- pendulum/locales/es/__init__.py | 0 pendulum/locales/es/custom.py | 23 - pendulum/locales/es/locale.py | 141 -- pendulum/locales/fa/__init__.py | 0 pendulum/locales/fa/custom.py | 18 - pendulum/locales/fa/locale.py | 135 -- pendulum/locales/fo/__init__.py | 0 pendulum/locales/fo/custom.py | 20 - pendulum/locales/fo/locale.py | 132 -- pendulum/locales/fr/__init__.py | 0 pendulum/locales/fr/custom.py | 23 - pendulum/locales/fr/locale.py | 133 -- pendulum/locales/he/__init__.py | 0 pendulum/locales/he/custom.py | 23 - pendulum/locales/he/locale.py | 269 ---- pendulum/locales/id/__init__.py | 0 pendulum/locales/id/custom.py | 19 - pendulum/locales/id/locale.py | 141 -- pendulum/locales/it/__init__.py | 0 pendulum/locales/it/custom.py | 24 - pendulum/locales/it/locale.py | 145 -- pendulum/locales/ja/__init__.py | 0 pendulum/locales/ja/custom.py | 21 - pendulum/locales/ja/locale.py | 194 --- pendulum/locales/ko/__init__.py | 0 pendulum/locales/ko/custom.py | 18 - pendulum/locales/ko/locale.py | 105 -- pendulum/locales/locale.py | 102 -- pendulum/locales/lt/__init__.py | 0 pendulum/locales/lt/custom.py | 118 -- pendulum/locales/lt/locale.py | 255 ---- pendulum/locales/nb/__init__.py | 0 pendulum/locales/nb/custom.py | 20 - pendulum/locales/nb/locale.py | 150 -- pendulum/locales/nl/__init__.py | 0 pendulum/locales/nl/custom.py | 23 - pendulum/locales/nl/locale.py | 134 -- pendulum/locales/nn/__init__.py | 0 pendulum/locales/nn/custom.py | 20 - pendulum/locales/nn/locale.py | 141 -- pendulum/locales/pl/__init__.py | 0 pendulum/locales/pl/custom.py | 21 - pendulum/locales/pl/locale.py | 279 ---- pendulum/locales/pt_br/__init__.py | 0 pendulum/locales/pt_br/custom.py | 18 - pendulum/locales/pt_br/locale.py | 143 -- pendulum/locales/ru/__init__.py | 0 pendulum/locales/ru/custom.py | 20 - pendulum/locales/ru/locale.py | 270 ---- pendulum/locales/sk/__init__.py | 0 pendulum/locales/sk/custom.py | 20 - pendulum/locales/sk/locale.py | 266 ---- pendulum/locales/sv/__init__.py | 0 pendulum/locales/sv/custom.py | 20 - pendulum/locales/sv/locale.py | 222 --- pendulum/locales/zh/__init__.py | 0 pendulum/locales/zh/custom.py | 18 - pendulum/locales/zh/locale.py | 113 -- pendulum/mixins/__init__.py | 0 pendulum/mixins/default.py | 36 - pendulum/parser.py | 124 -- pendulum/parsing/__init__.py | 233 ---- pendulum/parsing/_iso8601.c | 1361 ------------------- pendulum/parsing/_iso8601.pyi | 22 - pendulum/parsing/exceptions/__init__.py | 6 - pendulum/parsing/iso8601.py | 454 ------- pendulum/py.typed | 0 pendulum/testing/__init__.py | 0 pendulum/testing/traveller.py | 139 -- pendulum/time.py | 303 ----- pendulum/tz/__init__.py | 80 -- pendulum/tz/data/__init__.py | 0 pendulum/tz/data/windows.py | 139 -- pendulum/tz/exceptions.py | 32 - pendulum/tz/local_timezone.py | 260 ---- pendulum/tz/timezone.py | 217 --- pendulum/utils/__init__.py | 0 pendulum/utils/_compat.py | 13 - poetry.lock | 1662 ++++++++++++----------- pyproject.toml | 176 ++- rust/.cargo/config.toml | 15 + rust/Cargo.lock | 318 +++++ rust/Cargo.toml | 22 + rust/src/constants.rs | 56 + rust/src/helpers.rs | 122 ++ rust/src/lib.rs | 12 + rust/src/parsing.rs | 905 ++++++++++++ rust/src/python/helpers.rs | 388 ++++++ rust/src/python/mod.rs | 27 + rust/src/python/parsing.rs | 117 ++ rust/src/python/types/duration.rs | 59 + rust/src/python/types/interval.rs | 46 + rust/src/python/types/mod.rs | 7 + rust/src/python/types/precise_diff.rs | 53 + rust/src/python/types/timezone.rs | 52 + src/pendulum/__init__.py | 402 ++++++ src/pendulum/__version__.py | 4 + src/pendulum/_helpers.py | 335 +++++ src/pendulum/_pendulum.pyi | 40 + src/pendulum/constants.py | 102 ++ src/pendulum/date.py | 760 +++++++++++ src/pendulum/datetime.py | 1404 +++++++++++++++++++ src/pendulum/day.py | 13 + src/pendulum/duration.py | 533 ++++++++ src/pendulum/exceptions.py | 13 + src/pendulum/formatting/__init__.py | 6 + src/pendulum/formatting/difference_formatter.py | 144 ++ src/pendulum/formatting/formatter.py | 698 ++++++++++ src/pendulum/helpers.py | 221 +++ src/pendulum/interval.py | 455 +++++++ src/pendulum/locales/__init__.py | 0 src/pendulum/locales/cs/__init__.py | 0 src/pendulum/locales/cs/custom.py | 25 + src/pendulum/locales/cs/locale.py | 274 ++++ src/pendulum/locales/da/__init__.py | 0 src/pendulum/locales/da/custom.py | 20 + src/pendulum/locales/da/locale.py | 155 +++ src/pendulum/locales/de/__init__.py | 0 src/pendulum/locales/de/custom.py | 38 + src/pendulum/locales/de/locale.py | 152 +++ src/pendulum/locales/en/__init__.py | 0 src/pendulum/locales/en/custom.py | 25 + src/pendulum/locales/en/locale.py | 158 +++ src/pendulum/locales/en_gb/__init__.py | 0 src/pendulum/locales/en_gb/custom.py | 25 + src/pendulum/locales/en_gb/locale.py | 240 ++++ src/pendulum/locales/en_us/__init__.py | 0 src/pendulum/locales/en_us/custom.py | 25 + src/pendulum/locales/en_us/locale.py | 240 ++++ src/pendulum/locales/es/__init__.py | 0 src/pendulum/locales/es/custom.py | 25 + src/pendulum/locales/es/locale.py | 149 ++ src/pendulum/locales/fa/__init__.py | 0 src/pendulum/locales/fa/custom.py | 20 + src/pendulum/locales/fa/locale.py | 143 ++ src/pendulum/locales/fo/__init__.py | 0 src/pendulum/locales/fo/custom.py | 22 + src/pendulum/locales/fo/locale.py | 140 ++ src/pendulum/locales/fr/__init__.py | 0 src/pendulum/locales/fr/custom.py | 25 + src/pendulum/locales/fr/locale.py | 141 ++ src/pendulum/locales/he/__init__.py | 0 src/pendulum/locales/he/custom.py | 25 + src/pendulum/locales/he/locale.py | 277 ++++ src/pendulum/locales/id/__init__.py | 0 src/pendulum/locales/id/custom.py | 21 + src/pendulum/locales/id/locale.py | 149 ++ src/pendulum/locales/it/__init__.py | 0 src/pendulum/locales/it/custom.py | 25 + src/pendulum/locales/it/locale.py | 153 +++ src/pendulum/locales/ja/__init__.py | 0 src/pendulum/locales/ja/custom.py | 23 + src/pendulum/locales/ja/locale.py | 202 +++ src/pendulum/locales/ko/__init__.py | 0 src/pendulum/locales/ko/custom.py | 20 + src/pendulum/locales/ko/locale.py | 113 ++ src/pendulum/locales/locale.py | 100 ++ src/pendulum/locales/lt/__init__.py | 0 src/pendulum/locales/lt/custom.py | 120 ++ src/pendulum/locales/lt/locale.py | 263 ++++ src/pendulum/locales/nb/__init__.py | 0 src/pendulum/locales/nb/custom.py | 22 + src/pendulum/locales/nb/locale.py | 158 +++ src/pendulum/locales/nl/__init__.py | 0 src/pendulum/locales/nl/custom.py | 25 + src/pendulum/locales/nl/locale.py | 142 ++ src/pendulum/locales/nn/__init__.py | 0 src/pendulum/locales/nn/custom.py | 22 + src/pendulum/locales/nn/locale.py | 149 ++ src/pendulum/locales/pl/__init__.py | 0 src/pendulum/locales/pl/custom.py | 23 + src/pendulum/locales/pl/locale.py | 287 ++++ src/pendulum/locales/pt_br/__init__.py | 0 src/pendulum/locales/pt_br/custom.py | 20 + src/pendulum/locales/pt_br/locale.py | 151 ++ src/pendulum/locales/ru/__init__.py | 0 src/pendulum/locales/ru/custom.py | 22 + src/pendulum/locales/ru/locale.py | 278 ++++ src/pendulum/locales/sk/__init__.py | 0 src/pendulum/locales/sk/custom.py | 22 + src/pendulum/locales/sk/locale.py | 274 ++++ src/pendulum/locales/sv/__init__.py | 0 src/pendulum/locales/sv/custom.py | 22 + src/pendulum/locales/sv/locale.py | 230 ++++ src/pendulum/locales/tr/__init__.py | 0 src/pendulum/locales/tr/custom.py | 24 + src/pendulum/locales/tr/locale.py | 225 +++ src/pendulum/locales/zh/__init__.py | 0 src/pendulum/locales/zh/custom.py | 20 + src/pendulum/locales/zh/locale.py | 121 ++ src/pendulum/mixins/__init__.py | 0 src/pendulum/mixins/default.py | 37 + src/pendulum/parser.py | 128 ++ src/pendulum/parsing/__init__.py | 235 ++++ src/pendulum/parsing/exceptions/__init__.py | 5 + src/pendulum/parsing/iso8601.py | 453 ++++++ src/pendulum/py.typed | 0 src/pendulum/testing/__init__.py | 0 src/pendulum/testing/traveller.py | 172 +++ src/pendulum/time.py | 321 +++++ src/pendulum/tz/__init__.py | 64 + src/pendulum/tz/data/__init__.py | 0 src/pendulum/tz/data/windows.py | 140 ++ src/pendulum/tz/exceptions.py | 33 + src/pendulum/tz/local_timezone.py | 264 ++++ src/pendulum/tz/timezone.py | 239 ++++ src/pendulum/utils/__init__.py | 0 src/pendulum/utils/_compat.py | 15 + src/pendulum/utils/_zoneinfo.py | 80 ++ tests/benchmarks/__init__.py | 0 tests/benchmarks/test_parse_8601.py | 51 + tests/conftest.py | 51 +- tests/date/test_comparison.py | 2 +- tests/date/test_day_of_week_modifiers.py | 18 +- tests/date/test_diff.py | 2 +- tests/datetime/test_add.py | 20 +- tests/datetime/test_behavior.py | 8 + tests/datetime/test_comparison.py | 2 +- tests/datetime/test_construct.py | 27 +- tests/datetime/test_day_of_week_modifiers.py | 18 +- tests/datetime/test_from_format.py | 35 +- tests/datetime/test_getters.py | 51 +- tests/datetime/test_start_end_of.py | 40 + tests/datetime/test_strings.py | 10 +- tests/duration/test_behavior.py | 15 +- tests/formatting/test_formatter.py | 14 + tests/interval/test_add_subtract.py | 20 +- tests/interval/test_behavior.py | 21 +- tests/interval/test_construct.py | 28 +- tests/interval/test_hashing.py | 20 +- tests/interval/test_in_words.py | 38 +- tests/interval/test_range.py | 2 +- tests/localization/test_cs.py | 1 + tests/localization/test_da.py | 1 + tests/localization/test_de.py | 1 + tests/localization/test_es.py | 1 + tests/localization/test_fa.py | 1 + tests/localization/test_fo.py | 1 + tests/localization/test_fr.py | 1 + tests/localization/test_he.py | 1 + tests/localization/test_id.py | 1 + tests/localization/test_it.py | 1 + tests/localization/test_ja.py | 1 + tests/localization/test_ko.py | 1 + tests/localization/test_lt.py | 1 + tests/localization/test_nb.py | 1 + tests/localization/test_nl.py | 1 + tests/localization/test_nn.py | 1 + tests/localization/test_pl.py | 1 + tests/localization/test_ru.py | 1 + tests/localization/test_sk.py | 1 + tests/localization/test_sv.py | 1 + tests/localization/test_tr.py | 66 + tests/parsing/test_parse_iso8601.py | 485 ++----- tests/parsing/test_parsing.py | 15 +- tests/test_helpers.py | 57 +- tests/test_main.py | 52 +- tests/test_parsing.py | 53 +- tests/testing/test_time_travel.py | 1 + tests/time/test_comparison.py | 2 +- tests/tz/test_helpers.py | 2 +- tests/tz/test_timezone.py | 10 +- 314 files changed, 17438 insertions(+), 16021 deletions(-) delete mode 100644 .flake8 create mode 100644 .github/workflows/codspeed.yml delete mode 100755 build-wheels.sh delete mode 100644 build.py delete mode 100644 codecov.yml create mode 100644 docs/docs/interval.md delete mode 100644 docs/docs/period.md delete mode 100644 meson.build delete mode 100644 pendulum/__init__.py delete mode 100644 pendulum/__version__.py delete mode 100644 pendulum/_extensions/__init__.py delete mode 100644 pendulum/_extensions/_helpers.c delete mode 100644 pendulum/_extensions/_helpers.pyi delete mode 100644 pendulum/_extensions/helpers.py delete mode 100644 pendulum/constants.py delete mode 100644 pendulum/date.py delete mode 100644 pendulum/datetime.py delete mode 100644 pendulum/duration.py delete mode 100644 pendulum/exceptions.py delete mode 100644 pendulum/formatting/__init__.py delete mode 100644 pendulum/formatting/difference_formatter.py delete mode 100644 pendulum/formatting/formatter.py delete mode 100644 pendulum/helpers.py delete mode 100644 pendulum/interval.py delete mode 100644 pendulum/locales/__init__.py delete mode 100644 pendulum/locales/cs/__init__.py delete mode 100644 pendulum/locales/cs/custom.py delete mode 100644 pendulum/locales/cs/locale.py delete mode 100644 pendulum/locales/da/__init__.py delete mode 100644 pendulum/locales/da/custom.py delete mode 100644 pendulum/locales/da/locale.py delete mode 100644 pendulum/locales/de/__init__.py delete mode 100644 pendulum/locales/de/custom.py delete mode 100644 pendulum/locales/de/locale.py delete mode 100644 pendulum/locales/en/__init__.py delete mode 100644 pendulum/locales/en/custom.py delete mode 100644 pendulum/locales/en/locale.py delete mode 100644 pendulum/locales/es/__init__.py delete mode 100644 pendulum/locales/es/custom.py delete mode 100644 pendulum/locales/es/locale.py delete mode 100644 pendulum/locales/fa/__init__.py delete mode 100644 pendulum/locales/fa/custom.py delete mode 100644 pendulum/locales/fa/locale.py delete mode 100644 pendulum/locales/fo/__init__.py delete mode 100644 pendulum/locales/fo/custom.py delete mode 100644 pendulum/locales/fo/locale.py delete mode 100644 pendulum/locales/fr/__init__.py delete mode 100644 pendulum/locales/fr/custom.py delete mode 100644 pendulum/locales/fr/locale.py delete mode 100644 pendulum/locales/he/__init__.py delete mode 100644 pendulum/locales/he/custom.py delete mode 100644 pendulum/locales/he/locale.py delete mode 100644 pendulum/locales/id/__init__.py delete mode 100644 pendulum/locales/id/custom.py delete mode 100644 pendulum/locales/id/locale.py delete mode 100644 pendulum/locales/it/__init__.py delete mode 100644 pendulum/locales/it/custom.py delete mode 100644 pendulum/locales/it/locale.py delete mode 100644 pendulum/locales/ja/__init__.py delete mode 100644 pendulum/locales/ja/custom.py delete mode 100644 pendulum/locales/ja/locale.py delete mode 100644 pendulum/locales/ko/__init__.py delete mode 100644 pendulum/locales/ko/custom.py delete mode 100644 pendulum/locales/ko/locale.py delete mode 100644 pendulum/locales/locale.py delete mode 100644 pendulum/locales/lt/__init__.py delete mode 100644 pendulum/locales/lt/custom.py delete mode 100644 pendulum/locales/lt/locale.py delete mode 100644 pendulum/locales/nb/__init__.py delete mode 100644 pendulum/locales/nb/custom.py delete mode 100644 pendulum/locales/nb/locale.py delete mode 100644 pendulum/locales/nl/__init__.py delete mode 100644 pendulum/locales/nl/custom.py delete mode 100644 pendulum/locales/nl/locale.py delete mode 100644 pendulum/locales/nn/__init__.py delete mode 100644 pendulum/locales/nn/custom.py delete mode 100644 pendulum/locales/nn/locale.py delete mode 100644 pendulum/locales/pl/__init__.py delete mode 100644 pendulum/locales/pl/custom.py delete mode 100644 pendulum/locales/pl/locale.py delete mode 100644 pendulum/locales/pt_br/__init__.py delete mode 100644 pendulum/locales/pt_br/custom.py delete mode 100644 pendulum/locales/pt_br/locale.py delete mode 100644 pendulum/locales/ru/__init__.py delete mode 100644 pendulum/locales/ru/custom.py delete mode 100644 pendulum/locales/ru/locale.py delete mode 100644 pendulum/locales/sk/__init__.py delete mode 100644 pendulum/locales/sk/custom.py delete mode 100644 pendulum/locales/sk/locale.py delete mode 100644 pendulum/locales/sv/__init__.py delete mode 100644 pendulum/locales/sv/custom.py delete mode 100644 pendulum/locales/sv/locale.py delete mode 100644 pendulum/locales/zh/__init__.py delete mode 100644 pendulum/locales/zh/custom.py delete mode 100644 pendulum/locales/zh/locale.py delete mode 100644 pendulum/mixins/__init__.py delete mode 100644 pendulum/mixins/default.py delete mode 100644 pendulum/parser.py delete mode 100644 pendulum/parsing/__init__.py delete mode 100644 pendulum/parsing/_iso8601.c delete mode 100644 pendulum/parsing/_iso8601.pyi delete mode 100644 pendulum/parsing/exceptions/__init__.py delete mode 100644 pendulum/parsing/iso8601.py delete mode 100644 pendulum/py.typed delete mode 100644 pendulum/testing/__init__.py delete mode 100644 pendulum/testing/traveller.py delete mode 100644 pendulum/time.py delete mode 100644 pendulum/tz/__init__.py delete mode 100644 pendulum/tz/data/__init__.py delete mode 100644 pendulum/tz/data/windows.py delete mode 100644 pendulum/tz/exceptions.py delete mode 100644 pendulum/tz/local_timezone.py delete mode 100644 pendulum/tz/timezone.py delete mode 100644 pendulum/utils/__init__.py delete mode 100644 pendulum/utils/_compat.py create mode 100644 rust/.cargo/config.toml create mode 100644 rust/Cargo.lock create mode 100644 rust/Cargo.toml create mode 100644 rust/src/constants.rs create mode 100644 rust/src/helpers.rs create mode 100644 rust/src/lib.rs create mode 100644 rust/src/parsing.rs create mode 100644 rust/src/python/helpers.rs create mode 100644 rust/src/python/mod.rs create mode 100644 rust/src/python/parsing.rs create mode 100644 rust/src/python/types/duration.rs create mode 100644 rust/src/python/types/interval.rs create mode 100644 rust/src/python/types/mod.rs create mode 100644 rust/src/python/types/precise_diff.rs create mode 100644 rust/src/python/types/timezone.rs create mode 100644 src/pendulum/__init__.py create mode 100644 src/pendulum/__version__.py create mode 100644 src/pendulum/_helpers.py create mode 100644 src/pendulum/_pendulum.pyi create mode 100644 src/pendulum/constants.py create mode 100644 src/pendulum/date.py create mode 100644 src/pendulum/datetime.py create mode 100644 src/pendulum/day.py create mode 100644 src/pendulum/duration.py create mode 100644 src/pendulum/exceptions.py create mode 100644 src/pendulum/formatting/__init__.py create mode 100644 src/pendulum/formatting/difference_formatter.py create mode 100644 src/pendulum/formatting/formatter.py create mode 100644 src/pendulum/helpers.py create mode 100644 src/pendulum/interval.py create mode 100644 src/pendulum/locales/__init__.py create mode 100644 src/pendulum/locales/cs/__init__.py create mode 100644 src/pendulum/locales/cs/custom.py create mode 100644 src/pendulum/locales/cs/locale.py create mode 100644 src/pendulum/locales/da/__init__.py create mode 100644 src/pendulum/locales/da/custom.py create mode 100644 src/pendulum/locales/da/locale.py create mode 100644 src/pendulum/locales/de/__init__.py create mode 100644 src/pendulum/locales/de/custom.py create mode 100644 src/pendulum/locales/de/locale.py create mode 100644 src/pendulum/locales/en/__init__.py create mode 100644 src/pendulum/locales/en/custom.py create mode 100644 src/pendulum/locales/en/locale.py create mode 100644 src/pendulum/locales/en_gb/__init__.py create mode 100644 src/pendulum/locales/en_gb/custom.py create mode 100644 src/pendulum/locales/en_gb/locale.py create mode 100644 src/pendulum/locales/en_us/__init__.py create mode 100644 src/pendulum/locales/en_us/custom.py create mode 100644 src/pendulum/locales/en_us/locale.py create mode 100644 src/pendulum/locales/es/__init__.py create mode 100644 src/pendulum/locales/es/custom.py create mode 100644 src/pendulum/locales/es/locale.py create mode 100644 src/pendulum/locales/fa/__init__.py create mode 100644 src/pendulum/locales/fa/custom.py create mode 100644 src/pendulum/locales/fa/locale.py create mode 100644 src/pendulum/locales/fo/__init__.py create mode 100644 src/pendulum/locales/fo/custom.py create mode 100644 src/pendulum/locales/fo/locale.py create mode 100644 src/pendulum/locales/fr/__init__.py create mode 100644 src/pendulum/locales/fr/custom.py create mode 100644 src/pendulum/locales/fr/locale.py create mode 100644 src/pendulum/locales/he/__init__.py create mode 100644 src/pendulum/locales/he/custom.py create mode 100644 src/pendulum/locales/he/locale.py create mode 100644 src/pendulum/locales/id/__init__.py create mode 100644 src/pendulum/locales/id/custom.py create mode 100644 src/pendulum/locales/id/locale.py create mode 100644 src/pendulum/locales/it/__init__.py create mode 100644 src/pendulum/locales/it/custom.py create mode 100644 src/pendulum/locales/it/locale.py create mode 100644 src/pendulum/locales/ja/__init__.py create mode 100644 src/pendulum/locales/ja/custom.py create mode 100644 src/pendulum/locales/ja/locale.py create mode 100644 src/pendulum/locales/ko/__init__.py create mode 100644 src/pendulum/locales/ko/custom.py create mode 100644 src/pendulum/locales/ko/locale.py create mode 100644 src/pendulum/locales/locale.py create mode 100644 src/pendulum/locales/lt/__init__.py create mode 100644 src/pendulum/locales/lt/custom.py create mode 100644 src/pendulum/locales/lt/locale.py create mode 100644 src/pendulum/locales/nb/__init__.py create mode 100644 src/pendulum/locales/nb/custom.py create mode 100644 src/pendulum/locales/nb/locale.py create mode 100644 src/pendulum/locales/nl/__init__.py create mode 100644 src/pendulum/locales/nl/custom.py create mode 100644 src/pendulum/locales/nl/locale.py create mode 100644 src/pendulum/locales/nn/__init__.py create mode 100644 src/pendulum/locales/nn/custom.py create mode 100644 src/pendulum/locales/nn/locale.py create mode 100644 src/pendulum/locales/pl/__init__.py create mode 100644 src/pendulum/locales/pl/custom.py create mode 100644 src/pendulum/locales/pl/locale.py create mode 100644 src/pendulum/locales/pt_br/__init__.py create mode 100644 src/pendulum/locales/pt_br/custom.py create mode 100644 src/pendulum/locales/pt_br/locale.py create mode 100644 src/pendulum/locales/ru/__init__.py create mode 100644 src/pendulum/locales/ru/custom.py create mode 100644 src/pendulum/locales/ru/locale.py create mode 100644 src/pendulum/locales/sk/__init__.py create mode 100644 src/pendulum/locales/sk/custom.py create mode 100644 src/pendulum/locales/sk/locale.py create mode 100644 src/pendulum/locales/sv/__init__.py create mode 100644 src/pendulum/locales/sv/custom.py create mode 100644 src/pendulum/locales/sv/locale.py create mode 100644 src/pendulum/locales/tr/__init__.py create mode 100644 src/pendulum/locales/tr/custom.py create mode 100644 src/pendulum/locales/tr/locale.py create mode 100644 src/pendulum/locales/zh/__init__.py create mode 100644 src/pendulum/locales/zh/custom.py create mode 100644 src/pendulum/locales/zh/locale.py create mode 100644 src/pendulum/mixins/__init__.py create mode 100644 src/pendulum/mixins/default.py create mode 100644 src/pendulum/parser.py create mode 100644 src/pendulum/parsing/__init__.py create mode 100644 src/pendulum/parsing/exceptions/__init__.py create mode 100644 src/pendulum/parsing/iso8601.py create mode 100644 src/pendulum/py.typed create mode 100644 src/pendulum/testing/__init__.py create mode 100644 src/pendulum/testing/traveller.py create mode 100644 src/pendulum/time.py create mode 100644 src/pendulum/tz/__init__.py create mode 100644 src/pendulum/tz/data/__init__.py create mode 100644 src/pendulum/tz/data/windows.py create mode 100644 src/pendulum/tz/exceptions.py create mode 100644 src/pendulum/tz/local_timezone.py create mode 100644 src/pendulum/tz/timezone.py create mode 100644 src/pendulum/utils/__init__.py create mode 100644 src/pendulum/utils/_compat.py create mode 100644 src/pendulum/utils/_zoneinfo.py create mode 100644 tests/benchmarks/__init__.py create mode 100644 tests/benchmarks/test_parse_8601.py create mode 100644 tests/localization/test_tr.py diff --git a/.flake8 b/.flake8 deleted file mode 100644 index d571285..0000000 --- a/.flake8 +++ /dev/null @@ -1,28 +0,0 @@ -[flake8] -max-line-length = 88 -per-file-ignores = - # F401: Module imported but unused - # TC001: Move import into type checking block - __init__.py:F401, TC001 - # F811: Redefinition of unused name from line n - pendulum/tz/timezone.py:F811 -min_python_version = 3.7.0 -ban-relative-imports = true -# flake8-use-fstring: https://github.com/MichaelKim0407/flake8-use-fstring#--percent-greedy-and---format-greedy -format-greedy = 1 -inline-quotes = double -enable-extensions = TC, TC1 -type-checking-exempt-modules = typing, typing-extensions -eradicate-whitelist-extend = ^-.*; -extend-ignore = - # E501: Line too long - E501, - # E203: Whitespace before ':' - E203, - # SIM106: Handle error-cases first - SIM106, -extend-exclude = - # External to the project's coding standards: - docs/*, - # Machine-generated, too many false-positives - pendulum/locales/*, diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml new file mode 100644 index 0000000..fcc7ed3 --- /dev/null +++ b/.github/workflows/codspeed.yml @@ -0,0 +1,52 @@ +name: codspeed + +on: + push: + branches: + - "master" + pull_request: + # `workflow_dispatch` allows CodSpeed to trigger backtest + # performance analysis in order to generate initial data. + workflow_dispatch: + +jobs: + benchmarks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + with: + python-version: "3.9" + + - name: Get full Python version + id: full-python-version + run: | + echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") + + - name: Install poetry + run: | + curl -fsS https://install.python-poetry.org | python - -y + + - name: Update PATH + if: ${{ matrix.os != 'Windows' }} + run: echo "$HOME/.local/bin" >> $GITHUB_PATH + + - name: Configure poetry + run: poetry config virtualenvs.create false + + - name: Install dependencies + run: poetry install --only test --only benchmark --only build -vvv --no-root + + - name: Install project + run: poetry install --only test --only benchmark --only build -vvv --no-root + + - name: Install pendulum and check extensions + run: | + poetry run pip install -e . -vvv + python -c 'import pendulum._pendulum' + + - name: Run benchmarks + uses: CodSpeedHQ/action@v1 + with: + token: ${{ secrets.CODSPEED_TOKEN }} + run: pytest tests/ --codspeed diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 59062ae..5821407 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,34 +4,103 @@ on: push: tags: - '*.*.*' + workflow_dispatch: jobs: - build: - name: Build wheels on ${{ matrix.os }} - runs-on: ${{ matrix.os }}-latest + name: Build on ${{ matrix.platform || matrix.os }} (${{ matrix.target }} - ${{ matrix.manylinux || 'auto' }}) strategy: + fail-fast: false matrix: - os: [ ubuntu, windows, macos ] + os: [ubuntu, macos, windows] + target: [x86_64, aarch64] + manylinux: [auto] + include: + - os: ubuntu + platform: linux + - os: windows + ls: dir + interpreter: 3.7 3.8 3.9 3.10 3.11 3.12 pypy3.8 pypy3.9 pypy3.10 + - os: windows + ls: dir + target: aarch64 + interpreter: 3.11 3.12 + - os: macos + target: aarch64 + interpreter: 3.7 3.8 3.9 3.10 3.11 3.12 pypy3.8 pypy3.9 pypy3.10 + - os: ubuntu + platform: linux + target: aarch64 + # mimalloc not supported on manylinux2014 cross-compile container + extra-build-args: --no-default-features + # musllinux + - os: ubuntu + platform: linux + target: x86_64 + manylinux: musllinux_1_1 + - os: ubuntu + platform: linux + target: aarch64 + manylinux: musllinux_1_1 + - os: ubuntu + platform: linux + target: ppc64le + interpreter: 3.7 3.8 3.9 3.10 3.11 3.12 + # mimalloc not supported on manylinux2014 cross-compile container + extra-build-args: --no-default-features + - os: ubuntu + platform: linux + target: s390x + interpreter: 3.7 3.8 3.9 3.10 3.11 3.12 + # mimalloc not supported on manylinux2014 cross-compile container + extra-build-args: --no-default-features + runs-on: ${{ matrix.os }}-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - name: Build wheels - uses: pypa/cibuildwheel@v2.10.1 - env: - CIBW_PROJECT_REQUIRES_PYTHON: ">=3.7" + - name: set up python + uses: actions/setup-python@v4 with: - package-dir: . - output-dir: dist + python-version: '3.11' + architecture: ${{ matrix.python-architecture || 'x64' }} + + - name: build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.target }} + manylinux: ${{ matrix.manylinux || 'auto' }} + container: ${{ matrix.container }} + args: --release --out dist --interpreter ${{ matrix.interpreter || '3.7 3.8 3.9 3.10 3.11 3.12 pypy3.7 pypy3.8 pypy3.9 pypy3.10' }} ${{ matrix.extra-build-args }} + rust-toolchain: stable + docker-options: -e CI + + - run: ${{ matrix.ls || 'ls -lh' }} dist/ - uses: actions/upload-artifact@v3 with: name: dist - path: ./dist/* + path: dist + + build_sdist: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Build sdist + uses: PyO3/maturin-action@v1 + with: + command: sdist + args: --out dist + - name: Upload sdist + uses: actions/upload-artifact@v3 + with: + name: dist + path: dist + Release: - needs: [ build ] + needs: [ build, build_sdist ] + if: success() && startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: @@ -51,9 +120,6 @@ jobs: - name: Update PATH run: echo "$HOME/.local/bin" >> $GITHUB_PATH - - name: Build sdist - run: poetry build --format sdist - - name: Check distributions run: | ls -la dist diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 341859e..077a9c7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,13 +13,27 @@ on: - '**' jobs: + Linting: + name: Linting + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.11" + - name: "Install pre-commit" + run: pip install pre-commit + - name: "Install Rust toolchain" + run: rustup component add rustfmt clippy + - run: pre-commit run --all-files + Tests: name: ${{ matrix.os }} / ${{ matrix.python-version }} runs-on: ${{ matrix.os }}-latest strategy: matrix: os: [Ubuntu, MacOS, Windows] - python-version: [3.7, 3.8, 3.9, "3.10"] + python-version: [3.8, 3.9, "3.10", "3.11", "3.12"] defaults: run: shell: bash @@ -31,6 +45,7 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Get full Python version id: full-python-version @@ -64,8 +79,18 @@ jobs: if: steps.cache.outputs.cache-hit == 'true' && matrix.os != 'MacOS' run: timeout 10s poetry run pip --version || rm -rf .venv - - name: Install dependencies - run: poetry install --only main --only test -vvv + - name: Install runtime, testing, and typing dependencies + run: poetry install --only main --only test --only typing --only build --no-root -vvv + + - name: Install project + run: poetry run maturin develop + + - name: Run type checking + run: poetry run mypy + + - name: Uninstall typing dependencies + # This ensures pendulum runs without typing_extensions installed + run: poetry install --only main --only test --only build --sync --no-root -vvv - name: Test Pure Python run: | diff --git a/.gitignore b/.gitignore index bb25f8b..dd3696f 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,5 @@ setup.py # editor .vscode +/target +/rust/target diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0e8d094..3ec3be2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ ci: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v4.4.0 hooks: - id: trailing-whitespace exclude: ^tests/.*/fixtures/.* @@ -11,61 +11,21 @@ repos: exclude: ^tests/.*/fixtures/.* - id: debug-statements - - repo: https://github.com/hadialqattan/pycln - rev: v2.1.1 - hooks: - - id: pycln - args: [ --all ] - - repo: https://github.com/psf/black - rev: 22.10.0 + rev: 23.7.0 hooks: - id: black - - repo: https://github.com/pycqa/isort - rev: 5.10.1 - hooks: - - id: isort - args: [ --add-import, from __future__ import annotations, --lines-after-imports, "-1" ] - - - repo: https://github.com/pycqa/flake8 - rev: 5.0.4 - hooks: - - id: flake8 - additional_dependencies: &flake8_deps - - flake8-broken-line==0.5.0 - - flake8-bugbear==22.7.1 - - flake8-comprehensions==3.10.0 - - flake8-eradicate==1.3.0 - - flake8-quotes==3.3.1 - - flake8-simplify==0.19.2 - - flake8-tidy-imports==4.8.0 - - flake8-type-checking==2.1.2 - - flake8-typing-imports==1.12.0 - - flake8-use-fstring==1.3 - - pep8-naming==0.13.1 - - - repo: https://github.com/asottile/yesqa - rev: v1.4.0 - hooks: - - id: yesqa - additional_dependencies: *flake8_deps - - - repo: https://github.com/asottile/pyupgrade - rev: v3.2.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.0.291 hooks: - - id: pyupgrade - exclude: ^build\.py$ - args: - - --py37-plus + - id: ruff - - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.982 + - repo: local hooks: - - id: mypy + - id: lint-rust + name: Lint Rust + entry: make lint-rust + types: [rust] + language: rust pass_filenames: false - exclude: ^build\.py$ - additional_dependencies: - - pytest>=7.1.2 - - types-backports - - types-python-dateutil diff --git a/CHANGELOG.md b/CHANGELOG.md index ae71991..4c90eff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,40 @@ # Change Log +## [3.0.0] - 2023-12-16 + +### Changed + +- Relaxed dependency constraints. [#760](https://github.com/sdispater/pendulum/pull/760) +- The testing helpers are now optional and must be opted-in via the `test` extra. [#778](https://github.com/sdispater/pendulum/pull/778) + +### Fixed + +- Removed remaining mentions of periods instead of intervals. [#757](https://github.com/sdispater/pendulum/pull/757) +- Fixed the behavior of the `week_of_month` property for edge cases in January and December. [#774](https://github.com/sdispater/pendulum/pull/774) +- Fixed the handling of the `fold` attribute when deep-copying a `DateTime` instance. [#776](https://github.com/sdispater/pendulum/pull/776) +- Fixed errors where hours and days were not handled properly when adding durations. [#775](https://github.com/sdispater/pendulum/pull/775) +- Fixed errors where hours and days were not handled properly when adding durations. [#775](https://github.com/sdispater/pendulum/pull/775) + + +## [3.0.0b1] - 2023-10-01 + +### Added + +- Made `instance()` support all native types (date, time, datetime). [#732](https://github.com/sdispater/pendulum/pull/732) + +### Changed + +- Dropped support for Python 3.7. [#734](https://github.com/sdispater/pendulum/pull/734) +- Rewrote extensions in Rust. [#721](https://github.com/sdispater/pendulum/pull/721) +- Made day of week convention more consistent across the codebase. [#731](https://github.com/sdispater/pendulum/pull/731) + +### Fixed + +- Fixed datetime string representation to match the native library. [#733](https://github.com/sdispater/pendulum/pull/733) +- Fixed issues on some system when retrieving the local timezone. [#733](https://github.com/sdispater/pendulum/pull/733) +- Fixed DST handling in `start_of()/end_of()` methods. [#713](https://github.com/sdispater/pendulum/pull/713) + + ## [3.0.0a1] - 2022-11-23 ### Added @@ -165,7 +200,9 @@ -[Unreleased]: https://github.com/sdispater/pendulum/compare/3.0.0a1...master +[Unreleased]: https://github.com/sdispater/pendulum/compare/3.0.0...master +[3.0.0]: https://github.com/sdispater/pendulum/releases/tag/3.0.0 +[3.0.0b1]: https://github.com/sdispater/pendulum/releases/tag/3.0.0b1 [3.0.0a1]: https://github.com/sdispater/pendulum/releases/tag/3.0.0a1 [2.1.1]: https://github.com/sdispater/pendulum/releases/tag/2.1.1 [2.1.0]: https://github.com/sdispater/pendulum/releases/tag/2.1.0 diff --git a/Makefile b/Makefile index e68b94c..d6626b5 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,3 @@ -# This file is part of orator -# https://github.com/sdispater/orator - -# Licensed under the MIT license: -# http://www.opensource.org/licenses/MIT-license -# Copyright (c) 2015 Sébastien Eustace - -PENDULUM_RELEASE := $$(sed -n -E "s/VERSION = \"(.+)\"/\1/p" pendulum/version.py) # lists all available targets list: @@ -16,38 +8,11 @@ list: # required for list no_targets__: -# install all dependencies -setup: setup-python - -# test your application (tests in the tests/ directory) -test: - @py.test --cov=pendulum --cov-config .coveragerc tests/ -sq - -linux_release: wheels_x64 wheels_i686 - -release: wheels_x64 wheels_i686 wheel - -publish: - @poetry publish --no-build - -tar: - python setup.py sdist --formats=gztar - -wheel: - @poetry build -v - -wheels_x64: build_wheels_x64 - -wheels_i686: build_wheels_i686 - -build_wheels_x64: - docker pull quay.io/pypa/manylinux1_x86_64 - docker run --rm -v `pwd`:/io quay.io/pypa/manylinux1_x86_64 /io/build-wheels.sh +lint-rust: + cd rust && cargo fmt --all -- --check + cd rust && cargo clippy --tests -- -D warnings -build_wheels_i686: - docker pull quay.io/pypa/manylinux1_i686 - docker run --rm -v `pwd`:/io quay.io/pypa/manylinux1_i686 /io/build-wheels.sh -# run tests against all supported python versions -tox: - @tox +format-rust: + cd rust && cargo fmt --all + cd rust && cargo clippy --tests --fix --allow-dirty -- -D warnings diff --git a/README.rst b/README.rst index 78437e2..65a0ad6 100644 --- a/README.rst +++ b/README.rst @@ -7,9 +7,6 @@ Pendulum .. image:: https://img.shields.io/pypi/l/pendulum.svg :target: https://pypi.python.org/pypi/pendulum -.. image:: https://img.shields.io/codecov/c/github/sdispater/pendulum/master.svg - :target: https://codecov.io/gh/sdispater/pendulum/branch/master - .. image:: https://github.com/sdispater/pendulum/actions/workflows/tests.yml/badge.svg :alt: Pendulum Build status :target: https://github.com/sdispater/pendulum/actions @@ -17,7 +14,7 @@ Pendulum Python datetimes made easy. -Supports Python **2.7** and **3.4+**. +Supports Python **3.8 and newer**. .. code-block:: python @@ -56,6 +53,13 @@ Supports Python **2.7** and **3.4+**. '2013-03-31T03:00:00+02:00' +Resources +========= + +* `Official Website `_ +* `Documentation `_ +* `Issue Tracker `_ + Why Pendulum? ============= @@ -66,7 +70,7 @@ So it's still ``datetime`` but better. Unlike other datetime libraries for Python, Pendulum is a drop-in replacement for the standard ``datetime`` class (it inherits from it), so, basically, you can replace all your ``datetime`` -instances by ``DateTime`` instances in you code (exceptions exist for libraries that check +instances by ``DateTime`` instances in your code (exceptions exist for libraries that check the type of the objects by using the ``type`` function like ``sqlite3`` or ``PyMySQL`` for instance). It also removes the notion of naive datetimes: each ``Pendulum`` instance is timezone-aware @@ -121,14 +125,6 @@ a possible solution, if any: return '' if val is None else val.isoformat() -Resources -========= - -* `Official Website `_ -* `Documentation `_ -* `Issue Tracker `_ - - Contributing ============ diff --git a/build-wheels.sh b/build-wheels.sh deleted file mode 100755 index 1c8f1cb..0000000 --- a/build-wheels.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -set -e -x - -cd $(dirname $0) - -export PATH=/opt/python/cp38-cp38/bin/:$PATH - -curl -fsS -o get-poetry.py https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py -/opt/python/cp38-cp38/bin/python get-poetry.py --preview -y -rm get-poetry.py - -for PYBIN in /opt/python/cp3*/bin; do - if [ "$PYBIN" == "/opt/python/cp34-cp34m/bin" ]; then - continue - fi - if [ "$PYBIN" == "/opt/python/cp35-cp35m/bin" ]; then - continue - fi - rm -rf build - "${PYBIN}/python" $HOME/.poetry/bin/poetry build -vvv -done - -cd dist -for whl in *.whl; do - auditwheel repair "$whl" - rm "$whl" -done diff --git a/build.py b/build.py deleted file mode 100644 index 95e63e1..0000000 --- a/build.py +++ /dev/null @@ -1,33 +0,0 @@ -import subprocess - -from pathlib import Path - - -def meson(*args): - subprocess.call(["meson"] + list(args)) - - -def _build(): - build_dir = Path(__file__).parent.joinpath("build") - build_dir.mkdir(parents=True, exist_ok=True) - - meson("setup", build_dir.as_posix()) - meson("compile", "-C", build_dir.as_posix()) - meson("install", "-C", build_dir.as_posix()) - - -def build(setup_kwargs): - """ - This function is mandatory in order to build the extensions. - """ - try: - _build() - except Exception: - print( - " Unable to build C extensions, " - "Pendulum will use the pure python version of the extensions." - ) - - -if __name__ == "__main__": - build({}) diff --git a/clock b/clock index 17f35a3..acd8c55 100755 --- a/clock +++ b/clock @@ -47,7 +47,6 @@ class _LambdaCompiler(_GettextCompiler): class LocaleCreate(Command): - name = "locale create" description = "Creates locale translations." @@ -113,8 +112,8 @@ translations = {{}} data["days"] = {} for fmt, names in days.items(): data["days"][fmt] = {} - for value, name in names.items(): - data["days"][fmt][(value + 1) % 7] = name + for value, name in sorted(names.items()): + data["days"][fmt][value] = name # Getting months names months = content["months"]["format"] @@ -159,6 +158,9 @@ translations = {{}} # Day periods data["day_periods"] = content["day_periods"]["format"]["wide"] + # Week data + data["week_data"] = content["week_data"] + result = self.TEMPLATE.format( locale=locale, plural=plural, @@ -229,7 +231,6 @@ translations = {{}} class LocaleRecreate(Command): - name = "locale recreate" description = "Recreate existing locales." @@ -240,11 +241,10 @@ class LocaleRecreate(Command): locales = glob.glob(os.path.join(locales_dir, "*", "locale.py")) locales = [os.path.basename(os.path.dirname(locale)) for locale in locales] - self.call("locale:create", [("locales", locales)]) + self.call("locale create", "locales " + " ".join(locales)) class WindowsTzDump(Command): - name = "windows dump-timezones" description = "Dumps the mapping of Windows timezones to IANA timezones." diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index 3cbba28..0000000 --- a/codecov.yml +++ /dev/null @@ -1,7 +0,0 @@ -comment: false - -coverage: - status: - patch: - default: - enabled: false diff --git a/docs/docs/difference.md b/docs/docs/difference.md index 3a7f063..2653f01 100644 --- a/docs/docs/difference.md +++ b/docs/docs/difference.md @@ -1,6 +1,6 @@ # Difference -The `diff()` method returns a [Period](#period) instance that represents the total duration +The `diff()` method returns an [Interval](#interval) instance that represents the total duration between two `DateTime` instances. This interval can be then expressed in various units. These interval methods always return *the total difference expressed* in the specified time requested. All values are truncated and not rounded. diff --git a/docs/docs/index.md b/docs/docs/index.md index daca205..107e043 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -12,6 +12,6 @@ {!docs/modifiers.md!} {!docs/timezones.md!} {!docs/duration.md!} -{!docs/period.md!} +{!docs/interval.md!} {!docs/testing.md!} {!docs/limitations.md!} diff --git a/docs/docs/installation.md b/docs/docs/installation.md index bfa9641..9f80e87 100644 --- a/docs/docs/installation.md +++ b/docs/docs/installation.md @@ -11,3 +11,23 @@ or, if you are using [poetry](https://python-poetry.org): ```bash $ poetry add pendulum ``` + +## Optional features + +Pendulum provides optional features that you must explicitly require in order to use them. + +These optional features are: + +- `test`: Provides a set of helpers to make testing easier by allowing you to control the flow of time. + +You can install them by specifying them when installing Pendulum + +```bash +$ pip install pendulum[test] +``` + +or, if you are using [poetry](https://python-poetry.org): + +```bash +$ poetry add pendulum[test] +``` diff --git a/docs/docs/interval.md b/docs/docs/interval.md new file mode 100644 index 0000000..fc70fb3 --- /dev/null +++ b/docs/docs/interval.md @@ -0,0 +1,168 @@ +# Interval + +When you subtract a `DateTime` instance from another, or use the `diff()` method, it will return an `Interval` instance. +It inherits from the [Duration](#duration) class with the added benefit that it is aware of the +instances that generated it, so that it can give access to more methods and properties: + +```python +>>> import pendulum + +>>> start = pendulum.datetime(2000, 11, 20) +>>> end = pendulum.datetime(2016, 11, 5) + +>>> interval = end - start + +>>> interval.years +15 +>>> interval.months +11 +>>> interval.in_years() +15 +>>> interval.in_months() +191 + +# Note that the weeks property +# will change compared to the Duration class +>>> interval.weeks +2 # 832 for the duration + +# However the days property will still remain the same +# to keep the compatibility with the timedelta class +>>> interval.days +5829 +``` + +Be aware that an interval, just like an duration, is compatible with the `timedelta` class regarding +its attributes. However, its custom attributes (like `remaining_days`) will be aware of any DST +transitions that might have occurred and adjust accordingly. Let's take an example: + +```python +>>> import pendulum + +>>> start = pendulum.datetime(2017, 3, 7, tz='America/Toronto') +>>> end = start.add(days=6) + +>>> interval = end - start + +# timedelta properties +>>> interval.days +5 +>>> interval.seconds +82800 + +# interval properties +>>> interval.remaining_days +6 +>>> interval.hours +0 +>>> interval.remaining_seconds +0 +``` + +!!!warning + + Due to their nature (fixed duration between two datetimes), most arithmetic operations will + return a `Duration` instead of an `Interval`. + + ```python + >>> import pendulum + + >>> dt1 = pendulum.datetime(2016, 8, 7, 12, 34, 56) + >>> dt2 = dt1.add(days=6, seconds=34) + >>> interval = pendulum.interval(dt1, dt2) + >>> interval * 2 + Duration(weeks=1, days=5, minutes=1, seconds=8) + ``` + + +## Instantiation + +You can create an instance by using the `interval()` helper: + +```python + +>>> import pendulum + +>>> start = pendulum.datetime(2000, 1, 1) +>>> end = pendulum.datetime(2000, 1, 31) + +>>> interval = pendulum.interval(start, end) +``` + +You can also make an inverted interval: + +```python +>>> interval = pendulum.interval(end, start) +>>> interval.remaining_days +-2 +``` + +If you have inverted dates but want to make sure that the interval is positive, +you should set the `absolute` keyword argument to `True`: + +```python +>>> interval = pendulum.interval(end, start, absolute=True) +>>> interval.remaining_days +2 +``` + +## Range + +If you want to iterate over a interval, you can use the `range()` method: + +```python +>>> import pendulum + +>>> start = pendulum.datetime(2000, 1, 1) +>>> end = pendulum.datetime(2000, 1, 10) + +>>> interval = pendulum.interval(start, end) + +>>> for dt in interval.range('days'): +>>> print(dt) + +'2000-01-01T00:00:00+00:00' +'2000-01-02T00:00:00+00:00' +'2000-01-03T00:00:00+00:00' +'2000-01-04T00:00:00+00:00' +'2000-01-05T00:00:00+00:00' +'2000-01-06T00:00:00+00:00' +'2000-01-07T00:00:00+00:00' +'2000-01-08T00:00:00+00:00' +'2000-01-09T00:00:00+00:00' +'2000-01-10T00:00:00+00:00' +``` + +!!!note + + Supported units for `range()` are: `years`, `months`, `weeks`, + `days`, `hours`, `minutes`, `seconds` and `microseconds` + +You can pass an amount for the passed unit to control the length of the gap: + +```python +>>> for dt in interval.range('days', 2): +>>> print(dt) + +'2000-01-01T00:00:00+00:00' +'2000-01-03T00:00:00+00:00' +'2000-01-05T00:00:00+00:00' +'2000-01-07T00:00:00+00:00' +'2000-01-09T00:00:00+00:00' +``` + +You can also directly iterate over the `Interval` instance, +the unit will be `days` in this case: + +```python +>>> for dt in interval: +>>> print(dt) +``` + +You can check if a `DateTime` instance is inside a interval using the `in` keyword: + +```python +>>> dt = pendulum.datetime(2000, 1, 4) +>>> dt in interval +True +``` diff --git a/docs/docs/introduction.md b/docs/docs/introduction.md index fbbab97..0078b48 100644 --- a/docs/docs/introduction.md +++ b/docs/docs/introduction.md @@ -18,4 +18,4 @@ For example, all comparisons are done in `UTC` or in the timezone of the datetim 3 ``` -The default timezone, except when using the `now()`, method will always be `UTC`. +The default timezone, except when using the `now()` method, will always be `UTC`. diff --git a/docs/docs/limitations.md b/docs/docs/limitations.md index 7deff23..913aca1 100644 --- a/docs/docs/limitations.md +++ b/docs/docs/limitations.md @@ -4,7 +4,7 @@ Even though the `DateTime` class is a subclass of `datetime`, there are some rare cases where it can't replace the native class directly. Here is a list (non-exhaustive) of the reported cases with a possible solution, if any: -* `sqlite3` will use the the `type()` function to determine the type of the object by default. To work around it you can register a new adapter: +* `sqlite3` will use the `type()` function to determine the type of the object by default. To work around it you can register a new adapter: ```python import pendulum @@ -13,7 +13,7 @@ Here is a list (non-exhaustive) of the reported cases with a possible solution, register_adapter(pendulum.DateTime, lambda val: val.isoformat(' ')) ``` -* `mysqlclient` (former `MySQLdb`) and `PyMySQL` will use the the `type()` function to determine the type of the object by default. To work around it you can register a new adapter: +* `mysqlclient` (former `MySQLdb`) and `PyMySQL` will use the `type()` function to determine the type of the object by default. To work around it you can register a new adapter: ```python import pendulum diff --git a/docs/docs/period.md b/docs/docs/period.md deleted file mode 100644 index a4dde16..0000000 --- a/docs/docs/period.md +++ /dev/null @@ -1,168 +0,0 @@ -# Period - -When you subtract a `DateTime` instance from another, or use the `diff()` method, it will return a `Period` instance. -It inherits from the [Duration](#duration) class with the added benefit that it is aware of the -instances that generated it, so that it can give access to more methods and properties: - -```python ->>> import pendulum - ->>> start = pendulum.datetime(2000, 11, 20) ->>> end = pendulum.datetime(2016, 11, 5) - ->>> period = end - start - ->>> period.years -15 ->>> period.months -11 ->>> period.in_years() -15 ->>> period.in_months() -191 - -# Note that the weeks property -# will change compared to the Duration class ->>> period.weeks -2 # 832 for the duration - -# However the days property will still remain the same -# to keep the compatibility with the timedelta class ->>> period.days -5829 -``` - -Be aware that a period, just like an interval, is compatible with the `timedelta` class regarding -its attributes. However, its custom attributes (like `remaining_days`) will be aware of any DST -transitions that might have occurred and adjust accordingly. Let's take an example: - -```python ->>> import pendulum - ->>> start = pendulum.datetime(2017, 3, 7, tz='America/Toronto') ->>> end = start.add(days=6) - ->>> period = end - start - -# timedelta properties ->>> period.days -5 ->>> period.seconds -82800 - -# period properties ->>> period.remaining_days -6 ->>> period.hours -0 ->>> period.remaining_seconds -0 -``` - -!!!warning - - Due to their nature (fixed duration between two datetimes), most arithmetic operations will - return a `Duration` instead of a `Period`. - - ```python - >>> import pendulum - - >>> dt1 = pendulum.datetime(2016, 8, 7, 12, 34, 56) - >>> dt2 = dt1.add(days=6, seconds=34) - >>> period = pendulum.period(dt1, dt2) - >>> period * 2 - Duration(weeks=1, days=5, minutes=1, seconds=8) - ``` - - -## Instantiation - -You can create an instance by using the `period()` helper: - -```python - ->>> import pendulum - ->>> start = pendulum.datetime(2000, 1, 1) ->>> end = pendulum.datetime(2000, 1, 31) - ->>> period = pendulum.period(start, end) -``` - -You can also make an inverted period: - -```python ->>> period = pendulum.period(end, start) ->>> period.remaining_days --2 -``` - -If you have inverted dates but want to make sure that the period is positive, -you should set the `absolute` keyword argument to `True`: - -```python ->>> period = pendulum.period(end, start, absolute=True) ->>> period.remaining_days -2 -``` - -## Range - -If you want to iterate over a period, you can use the `range()` method: - -```python ->>> import pendulum - ->>> start = pendulum.datetime(2000, 1, 1) ->>> end = pendulum.datetime(2000, 1, 10) - ->>> period = pendulum.period(start, end) - ->>> for dt in period.range('days'): ->>> print(dt) - -'2000-01-01T00:00:00+00:00' -'2000-01-02T00:00:00+00:00' -'2000-01-03T00:00:00+00:00' -'2000-01-04T00:00:00+00:00' -'2000-01-05T00:00:00+00:00' -'2000-01-06T00:00:00+00:00' -'2000-01-07T00:00:00+00:00' -'2000-01-08T00:00:00+00:00' -'2000-01-09T00:00:00+00:00' -'2000-01-10T00:00:00+00:00' -``` - -!!!note - - Supported units for `range()` are: `years`, `months`, `weeks`, - `days`, `hours`, `minutes`, `seconds` and `microseconds` - -You can pass an amount for the passed unit to control the length of the gap: - -```python ->>> for dt in period.range('days', 2): ->>> print(dt) - -'2000-01-01T00:00:00+00:00' -'2000-01-03T00:00:00+00:00' -'2000-01-05T00:00:00+00:00' -'2000-01-07T00:00:00+00:00' -'2000-01-09T00:00:00+00:00' -``` - -You can also directly iterate over the `Period` instance, -the unit will be `days` in this case: - -```python ->>> for dt in period: ->>> print(dt) -``` - -You can check if a `DateTime` instance is inside a period using the `in` keyword: - -```python ->>> dt = pendulum.datetime(2000, 1, 4) ->>> dt in period -True -``` diff --git a/docs/docs/testing.md b/docs/docs/testing.md index dfca054..25aad8d 100644 --- a/docs/docs/testing.md +++ b/docs/docs/testing.md @@ -1,59 +1,87 @@ # Testing -The testing methods allow you to set a `DateTime` instance (real or mock) to be returned -when a "now" instance is created. -The provided instance will be returned specifically under the following conditions: +Pendulum provides a few helpers to help you control the flow of time in your tests. Note that +these helpers are only available if you opted in the `test` extra during [installation](#installation). -* A call to the `now()` method, ex. `pendulum.now()`. -* When the string "now" is passed to the `parse()` method, ex. `pendulum.parse('now')` +!!!warning + If you are migrating from Pendulum 2, note that the `set_test_now()` and `test()` + helpers have been removed. + + +## Relative time travel + +You can travel in time relatively to the current time ```python >>> import pendulum -# Create testing datetime ->>> known = pendulum.datetime(2001, 5, 21, 12) +>>> now = pendulum.now() +>>> pendulum.travel(minutes=5) +>>> pendulum.now().diff_for_humans(now) +"5 minutes after" +``` -# Set the mock ->>> pendulum.set_test_now(known) +Note that once you've travelled in time the clock **keeps ticking**. If you prefer to stop the time completely +you can use the `freeze` parameter: ->>> print(pendulum.now()) -'2001-05-21T12:00:00+00:00' +```python +>>> import pendulum ->>> print(pendulum.parse('now')) -'2001-05-21T12:00:00+00:00' +>>> now = pendulum.now() +>>> pendulum.travel(minutes=5, freeze=True) +>>> pendulum.now().diff_for_humans(now) +"5 minutes after" # This will stay like this indefinitely +``` -# Clear the mock ->>> pendulum.set_test_now() ->>> print(pendulum.now()) -'2016-07-10T22:10:33.954851-05:00' -``` +## Absolute time travel -Related methods will also return values mocked according to the **now** instance. +Sometimes, you may want to place yourself at a specific point in time. +This is possible by using the `travel_to()` helper. This helper accepts a `DateTime` instance +that represents the point in time where you want to travel to. ```python ->>> print(pendulum.today()) -'2001-05-21T00:00:00+00:00' +>>> import pendulum ->>> print(pendulum.tomorrow()) -'2001-05-22T00:00:00+00:00' +>>> pendulum.travel_to(pendulum.yesterday()) +``` ->>> print(pendulum.yesterday()) -'2001-05-20T00:00:00+00:00' +Similarly to `travel`, it's important to remember that, by default, the time keeps ticking so, if you prefer +stopping the time, use the `freeze` parameter: + +```python +>>> import pendulum + +>>> pendulum.travel_to(pendulum.yesterday(), freeze=True) ``` -If you don't want to manually clear the mock (or you are afraid of forgetting), -you can use the provided `test()` contextmanager. +## Travelling back to the present + +Using any of the travel helpers will keep you in the past, or future, until you decide +to travel back to the present time. To do so, you may use the `travel_back()` helper. ```python >>> import pendulum ->>> known = pendulum.datetime(2001, 5, 21, 12) +>>> now = pendulum.now() +>>> pendulum.travel(minutes=5, freeze=True) +>>> pendulum.now().diff_for_humans(now) +"5 minutes after" +>>> pendulum.travel_back() +>>> pendulum.now().diff_for_humans(now) +"a few seconds after" +``` + +However, it might be cumbersome to remember to travel back so, instead, you can use any of the helpers as a context +manager: ->>> with pendulum.test(known): ->>> print(pendulum.now()) -'2001-05-21T12:00:00+00:00' +```python +>>> import pendulum ->>> print(pendulum.now()) -'2016-07-10T22:10:33.954851-05:00' +>>> now = pendulum.now() +>>> with pendulum.travel(minutes=5, freeze=True): +>>> pendulum.now().diff_for_humans(now) +"5 minutes after" +>>> pendulum.now().diff_for_humans(now) +"a few seconds after" ``` diff --git a/docs/docs/timezones.md b/docs/docs/timezones.md index 85ff147..e70034e 100644 --- a/docs/docs/timezones.md +++ b/docs/docs/timezones.md @@ -67,7 +67,7 @@ adopt the proper behavior and apply the transition accordingly. >>> dt = dt.add(microseconds=1) '2013-03-31T03:00:00+02:00' >>> dt.subtract(microseconds=1) -'2013-03-31T01:59:59.999998+01:00' +'2013-03-31T01:59:59.999999+01:00' >>> dt = pendulum.datetime(2013, 10, 27, 2, 59, 59, 999999, tz='Europe/Paris', diff --git a/meson.build b/meson.build deleted file mode 100644 index 666c281..0000000 --- a/meson.build +++ /dev/null @@ -1,20 +0,0 @@ -project('pendulum C extensions', 'c') - -py_mod = import('python') -py = py_mod.find_installation() -py_dep = py.dependency() - -extensions = [ - ['_helpers', 'pendulum/_extensions/_helpers.c', meson.source_root() / 'pendulum/_extensions/'], - ['_iso8601', 'pendulum/parsing/_iso8601.c', meson.source_root() / 'pendulum/parsing/'], -] - -foreach extension : extensions - py.extension_module( - extension[0], - extension[1], - dependencies : py_dep, - install : true, - install_dir: extension[2] - ) -endforeach diff --git a/pendulum/__init__.py b/pendulum/__init__.py deleted file mode 100644 index 4491244..0000000 --- a/pendulum/__init__.py +++ /dev/null @@ -1,363 +0,0 @@ -from __future__ import annotations - -import datetime as _datetime - -from typing import Union -from typing import cast - -from pendulum.__version__ import __version__ -from pendulum.constants import DAYS_PER_WEEK -from pendulum.constants import FRIDAY -from pendulum.constants import HOURS_PER_DAY -from pendulum.constants import MINUTES_PER_HOUR -from pendulum.constants import MONDAY -from pendulum.constants import MONTHS_PER_YEAR -from pendulum.constants import SATURDAY -from pendulum.constants import SECONDS_PER_DAY -from pendulum.constants import SECONDS_PER_HOUR -from pendulum.constants import SECONDS_PER_MINUTE -from pendulum.constants import SUNDAY -from pendulum.constants import THURSDAY -from pendulum.constants import TUESDAY -from pendulum.constants import WEDNESDAY -from pendulum.constants import WEEKS_PER_YEAR -from pendulum.constants import YEARS_PER_CENTURY -from pendulum.constants import YEARS_PER_DECADE -from pendulum.date import Date -from pendulum.datetime import DateTime -from pendulum.duration import Duration -from pendulum.formatting import Formatter -from pendulum.helpers import format_diff -from pendulum.helpers import get_locale -from pendulum.helpers import locale -from pendulum.helpers import set_locale -from pendulum.helpers import week_ends_at -from pendulum.helpers import week_starts_at -from pendulum.interval import Interval -from pendulum.parser import parse -from pendulum.testing.traveller import Traveller -from pendulum.time import Time -from pendulum.tz import UTC -from pendulum.tz import local_timezone -from pendulum.tz import set_local_timezone -from pendulum.tz import test_local_timezone -from pendulum.tz import timezone -from pendulum.tz import timezones -from pendulum.tz.timezone import FixedTimezone -from pendulum.tz.timezone import Timezone - -_TEST_NOW: DateTime | None = None -_LOCALE = "en" -_WEEK_STARTS_AT = MONDAY -_WEEK_ENDS_AT = SUNDAY - -_formatter = Formatter() - - -def _safe_timezone( - obj: str | float | _datetime.tzinfo | Timezone | FixedTimezone | None, - dt: _datetime.datetime | None = None, -) -> Timezone | FixedTimezone: - """ - Creates a timezone instance - from a string, Timezone, TimezoneInfo or integer offset. - """ - if isinstance(obj, (Timezone, FixedTimezone)): - return obj - - if obj is None or obj == "local": - return local_timezone() - - if isinstance(obj, (int, float)): - obj = int(obj * 60 * 60) - elif isinstance(obj, _datetime.tzinfo): - # zoneinfo - if hasattr(obj, "key"): - obj = obj.key # type: ignore - # pytz - elif hasattr(obj, "localize"): - obj = obj.zone # type: ignore - elif obj.tzname(None) == "UTC": - return UTC - else: - offset = obj.utcoffset(dt) - - if offset is None: - offset = _datetime.timedelta(0) - - obj = int(offset.total_seconds()) - - obj = cast(Union[str, int], obj) - - return timezone(obj) - - -# Public API -def datetime( - year: int, - month: int, - day: int, - hour: int = 0, - minute: int = 0, - second: int = 0, - microsecond: int = 0, - tz: str | float | Timezone | FixedTimezone | _datetime.tzinfo | None = UTC, - fold: int = 1, - raise_on_unknown_times: bool = False, -) -> DateTime: - """ - Creates a new DateTime instance from a specific date and time. - """ - return DateTime.create( - year, - month, - day, - hour=hour, - minute=minute, - second=second, - microsecond=microsecond, - tz=tz, - fold=fold, - raise_on_unknown_times=raise_on_unknown_times, - ) - - -def local( - year: int, - month: int, - day: int, - hour: int = 0, - minute: int = 0, - second: int = 0, - microsecond: int = 0, -) -> DateTime: - """ - Return a DateTime in the local timezone. - """ - return datetime( - year, month, day, hour, minute, second, microsecond, tz=local_timezone() - ) - - -def naive( - year: int, - month: int, - day: int, - hour: int = 0, - minute: int = 0, - second: int = 0, - microsecond: int = 0, - fold: int = 1, -) -> DateTime: - """ - Return a naive DateTime. - """ - return DateTime(year, month, day, hour, minute, second, microsecond, fold=fold) - - -def date(year: int, month: int, day: int) -> Date: - """ - Create a new Date instance. - """ - return Date(year, month, day) - - -def time(hour: int, minute: int = 0, second: int = 0, microsecond: int = 0) -> Time: - """ - Create a new Time instance. - """ - return Time(hour, minute, second, microsecond) - - -def instance( - dt: _datetime.datetime, - tz: str | Timezone | FixedTimezone | _datetime.tzinfo | None = UTC, -) -> DateTime: - """ - Create a DateTime instance from a datetime one. - """ - if not isinstance(dt, _datetime.datetime): - raise ValueError("instance() only accepts datetime objects.") - - if isinstance(dt, DateTime): - return dt - - tz = dt.tzinfo or tz - - if tz is not None: - tz = _safe_timezone(tz, dt=dt) - - return datetime( - dt.year, - dt.month, - dt.day, - dt.hour, - dt.minute, - dt.second, - dt.microsecond, - tz=cast(Union[str, int, Timezone, FixedTimezone, None], tz), - ) - - -def now(tz: str | Timezone | None = None) -> DateTime: - """ - Get a DateTime instance for the current date and time. - """ - return DateTime.now(tz) - - -def today(tz: str | Timezone = "local") -> DateTime: - """ - Create a DateTime instance for today. - """ - return now(tz).start_of("day") - - -def tomorrow(tz: str | Timezone = "local") -> DateTime: - """ - Create a DateTime instance for today. - """ - return today(tz).add(days=1) - - -def yesterday(tz: str | Timezone = "local") -> DateTime: - """ - Create a DateTime instance for today. - """ - return today(tz).subtract(days=1) - - -def from_format( - string: str, - fmt: str, - tz: str | Timezone = UTC, - locale: str | None = None, -) -> DateTime: - """ - Creates a DateTime instance from a specific format. - """ - parts = _formatter.parse(string, fmt, now(tz=tz), locale=locale) - if parts["tz"] is None: - parts["tz"] = tz - - return datetime(**parts) - - -def from_timestamp(timestamp: int | float, tz: str | Timezone = UTC) -> DateTime: - """ - Create a DateTime instance from a timestamp. - """ - dt = _datetime.datetime.utcfromtimestamp(timestamp) - - dt = datetime( - dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond - ) - - if tz is not UTC or tz != "UTC": - dt = dt.in_timezone(tz) - - return dt - - -def duration( - days: float = 0, - seconds: float = 0, - microseconds: float = 0, - milliseconds: float = 0, - minutes: float = 0, - hours: float = 0, - weeks: float = 0, - years: float = 0, - months: float = 0, -) -> Duration: - """ - Create a Duration instance. - """ - return Duration( - days=days, - seconds=seconds, - microseconds=microseconds, - milliseconds=milliseconds, - minutes=minutes, - hours=hours, - weeks=weeks, - years=years, - months=months, - ) - - -def interval(start: DateTime, end: DateTime, absolute: bool = False) -> Interval: - """ - Create an Interval instance. - """ - return Interval(start, end, absolute=absolute) - - -# Testing - -_traveller = Traveller(DateTime) - -freeze = _traveller.freeze -travel = _traveller.travel -travel_to = _traveller.travel_to -travel_back = _traveller.travel_back - -__all__ = [ - "__version__", - "DAYS_PER_WEEK", - "FRIDAY", - "HOURS_PER_DAY", - "MINUTES_PER_HOUR", - "MONDAY", - "MONTHS_PER_YEAR", - "SATURDAY", - "SECONDS_PER_DAY", - "SECONDS_PER_HOUR", - "SECONDS_PER_MINUTE", - "SUNDAY", - "THURSDAY", - "TUESDAY", - "WEDNESDAY", - "WEEKS_PER_YEAR", - "YEARS_PER_CENTURY", - "YEARS_PER_DECADE", - "Date", - "DateTime", - "Duration", - "Formatter", - "date", - "datetime", - "duration", - "format_diff", - "freeze", - "from_format", - "from_timestamp", - "get_locale", - "instance", - "interval", - "local", - "locale", - "naive", - "now", - "set_locale", - "week_ends_at", - "week_starts_at", - "parse", - "Interval", - "Time", - "UTC", - "local_timezone", - "set_local_timezone", - "test_local_timezone", - "time", - "timezone", - "timezones", - "today", - "tomorrow", - "travel", - "travel_back", - "travel_to", - "FixedTimezone", - "Timezone", - "yesterday", -] diff --git a/pendulum/__version__.py b/pendulum/__version__.py deleted file mode 100644 index 29e86a8..0000000 --- a/pendulum/__version__.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "3.0.0a" diff --git a/pendulum/_extensions/__init__.py b/pendulum/_extensions/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/_extensions/_helpers.c b/pendulum/_extensions/_helpers.c deleted file mode 100644 index a3114d9..0000000 --- a/pendulum/_extensions/_helpers.c +++ /dev/null @@ -1,931 +0,0 @@ -/* ------------------------------------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* ------------------------------------------------------------------------- */ - -#define EPOCH_YEAR 1970 - -#define DAYS_PER_N_YEAR 365 -#define DAYS_PER_L_YEAR 366 - -#define USECS_PER_SEC 1000000 - -#define SECS_PER_MIN 60 -#define SECS_PER_HOUR (60 * SECS_PER_MIN) -#define SECS_PER_DAY (SECS_PER_HOUR * 24) - -// 400-year chunks always have 146097 days (20871 weeks). -#define DAYS_PER_400_YEARS 146097L -#define SECS_PER_400_YEARS ((int64_t)DAYS_PER_400_YEARS * (int64_t)SECS_PER_DAY) - -// The number of seconds in an aligned 100-year chunk, for those that -// do not begin with a leap year and those that do respectively. -const int64_t SECS_PER_100_YEARS[2] = { - (uint64_t)(76L * DAYS_PER_N_YEAR + 24L * DAYS_PER_L_YEAR) * SECS_PER_DAY, - (uint64_t)(75L * DAYS_PER_N_YEAR + 25L * DAYS_PER_L_YEAR) * SECS_PER_DAY}; - -// The number of seconds in an aligned 4-year chunk, for those that -// do not begin with a leap year and those that do respectively. -const int32_t SECS_PER_4_YEARS[2] = { - (4 * DAYS_PER_N_YEAR + 0 * DAYS_PER_L_YEAR) * SECS_PER_DAY, - (3 * DAYS_PER_N_YEAR + 1 * DAYS_PER_L_YEAR) * SECS_PER_DAY}; - -// The number of seconds in non-leap and leap years respectively. -const int32_t SECS_PER_YEAR[2] = { - DAYS_PER_N_YEAR * SECS_PER_DAY, - DAYS_PER_L_YEAR *SECS_PER_DAY}; - -#define MONTHS_PER_YEAR 12 - -// The month lengths in non-leap and leap years respectively. -const int32_t DAYS_PER_MONTHS[2][13] = { - {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {-1, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; - -// The day offsets of the beginning of each (1-based) month in non-leap -// and leap years respectively. -// For example, in a leap year there are 335 days before December. -const int32_t MONTHS_OFFSETS[2][14] = { - {-1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, - {-1, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}}; - -const int DAY_OF_WEEK_TABLE[12] = { - 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; - -#define TM_SUNDAY 0 -#define TM_MONDAY 1 -#define TM_TUESDAY 2 -#define TM_WEDNESDAY 3 -#define TM_THURSDAY 4 -#define TM_FRIDAY 5 -#define TM_SATURDAY 6 - -#define TM_JANUARY 0 -#define TM_FEBRUARY 1 -#define TM_MARCH 2 -#define TM_APRIL 3 -#define TM_MAY 4 -#define TM_JUNE 5 -#define TM_JULY 6 -#define TM_AUGUST 7 -#define TM_SEPTEMBER 8 -#define TM_OCTOBER 9 -#define TM_NOVEMBER 10 -#define TM_DECEMBER 11 - -/* ------------------------------------------------------------------------- */ - -int _p(int y) -{ - return y + y / 4 - y / 100 + y / 400; -} - -int _is_leap(int year) -{ - return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); -} - -int _is_long_year(int year) -{ - return (_p(year) % 7 == 4) || (_p(year - 1) % 7 == 3); -} - -int _week_day(int year, int month, int day) -{ - int y; - int w; - - y = year - (month < 3); - - w = (_p(y) + DAY_OF_WEEK_TABLE[month - 1] + day) % 7; - - if (!w) - { - w = 7; - } - - return w; -} - -int _days_in_year(int year) -{ - if (_is_leap(year)) - { - return DAYS_PER_L_YEAR; - } - - return DAYS_PER_N_YEAR; -} - -int _day_number(int year, int month, int day) -{ - month = (month + 9) % 12; - year = year - month / 10; - - return ( - 365 * year + year / 4 - year / 100 + year / 400 + (month * 306 + 5) / 10 + (day - 1)); -} - -int _get_offset(PyObject *dt) -{ - PyObject *tzinfo; - PyObject *offset; - - tzinfo = ((PyDateTime_DateTime *)(dt))->tzinfo; - - if (tzinfo != Py_None) - { - offset = PyObject_CallMethod(tzinfo, "utcoffset", "O", dt); - - return PyDateTime_DELTA_GET_DAYS(offset) * SECS_PER_DAY + PyDateTime_DELTA_GET_SECONDS(offset); - } - - return 0; -} - -int _has_tzinfo(PyObject *dt) -{ - return ((_PyDateTime_BaseTZInfo *)(dt))->hastzinfo; -} - -char *_get_tz_name(PyObject *dt) -{ - PyObject *tzinfo; - char *tz = ""; - - tzinfo = ((PyDateTime_DateTime *)(dt))->tzinfo; - - if (tzinfo != Py_None) - { - if (PyObject_HasAttrString(tzinfo, "key")) - { - // zoneinfo timezone - tz = (char *)PyUnicode_AsUTF8( - PyObject_GetAttrString(tzinfo, "name")); - } - else if (PyObject_HasAttrString(tzinfo, "name")) - { - // Pendulum timezone - tz = (char *)PyUnicode_AsUTF8( - PyObject_GetAttrString(tzinfo, "name")); - } - else if (PyObject_HasAttrString(tzinfo, "zone")) - { - // pytz timezone - tz = (char *)PyUnicode_AsUTF8( - PyObject_GetAttrString(tzinfo, "zone")); - } - } - - return tz; -} - -/* ------------------------ Custom Types ------------------------------- */ - -/* - * class Diff(): - */ -typedef struct -{ - PyObject_HEAD int years; - int months; - int days; - int hours; - int minutes; - int seconds; - int microseconds; - int total_days; -} Diff; - -/* - * def __init__(self, years, months, days, hours, minutes, seconds, microseconds, total_days): - * self.years = years - * # ... -*/ -static int Diff_init(Diff *self, PyObject *args, PyObject *kwargs) -{ - int years; - int months; - int days; - int hours; - int minutes; - int seconds; - int microseconds; - int total_days; - - if (!PyArg_ParseTuple(args, "iiiiiii", &years, &months, &days, &hours, &minutes, &seconds, µseconds, &total_days)) - return -1; - - self->years = years; - self->months = months; - self->days = days; - self->hours = hours; - self->minutes = minutes; - self->seconds = seconds; - self->microseconds = microseconds; - self->total_days = total_days; - - return 0; -} - -/* - * def __repr__(self): - * return '{} years {} months {} days {} hours {} minutes {} seconds {} microseconds'.format( - * self.years, self.months, self.days, self.minutes, self.hours, self.seconds, self.microseconds - * ) - */ -static PyObject *Diff_repr(Diff *self) -{ - return PyUnicode_FromFormat( - "%d years %d months %d days %d hours %d minutes %d seconds %d microseconds", - self->years, - self->months, - self->days, - self->hours, - self->minutes, - self->seconds, - self->microseconds); -} - -/* - * Instantiate new Diff_type object - * Skip overhead of calling PyObject_New and PyObject_Init. - * Directly allocate object. - */ -static PyObject *new_diff_ex(int years, int months, int days, int hours, int minutes, int seconds, int microseconds, int total_days, PyTypeObject *type) -{ - Diff *self = (Diff *)(type->tp_alloc(type, 0)); - - if (self != NULL) - { - self->years = years; - self->months = months; - self->days = days; - self->hours = hours; - self->minutes = minutes; - self->seconds = seconds; - self->microseconds = microseconds; - self->total_days = total_days; - } - - return (PyObject *)self; -} - -/* - * Class member / class attributes - */ -static PyMemberDef Diff_members[] = { - {"years", T_INT, offsetof(Diff, years), 0, "years in diff"}, - {"months", T_INT, offsetof(Diff, months), 0, "months in diff"}, - {"days", T_INT, offsetof(Diff, days), 0, "days in diff"}, - {"hours", T_INT, offsetof(Diff, hours), 0, "hours in diff"}, - {"minutes", T_INT, offsetof(Diff, minutes), 0, "minutes in diff"}, - {"seconds", T_INT, offsetof(Diff, seconds), 0, "seconds in diff"}, - {"microseconds", T_INT, offsetof(Diff, microseconds), 0, "microseconds in diff"}, - {"total_days", T_INT, offsetof(Diff, total_days), 0, "total days in diff"}, - {NULL}}; - -static PyTypeObject Diff_type = { - PyVarObject_HEAD_INIT(NULL, 0) "PreciseDiff", /* tp_name */ - sizeof(Diff), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)Diff_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - (reprfunc)Diff_repr, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "Precise difference between two datetime objects", /* tp_doc */ -}; - -#define new_diff(years, months, days, hours, minutes, seconds, microseconds, total_days) new_diff_ex(years, months, days, hours, minutes, seconds, microseconds, total_days, &Diff_type) - -/* -------------------------- Functions --------------------------*/ - -PyObject *is_leap(PyObject *self, PyObject *args) -{ - PyObject *leap; - int year; - - if (!PyArg_ParseTuple(args, "i", &year)) - { - PyErr_SetString( - PyExc_ValueError, "Invalid parameters"); - return NULL; - } - - leap = PyBool_FromLong(_is_leap(year)); - - return leap; -} - -PyObject *is_long_year(PyObject *self, PyObject *args) -{ - PyObject *is_long; - int year; - - if (!PyArg_ParseTuple(args, "i", &year)) - { - PyErr_SetString( - PyExc_ValueError, "Invalid parameters"); - return NULL; - } - - is_long = PyBool_FromLong(_is_long_year(year)); - - return is_long; -} - -PyObject *week_day(PyObject *self, PyObject *args) -{ - PyObject *wd; - int year; - int month; - int day; - - if (!PyArg_ParseTuple(args, "iii", &year, &month, &day)) - { - PyErr_SetString( - PyExc_ValueError, "Invalid parameters"); - return NULL; - } - - wd = PyLong_FromLong(_week_day(year, month, day)); - - return wd; -} - -PyObject *days_in_year(PyObject *self, PyObject *args) -{ - PyObject *ndays; - int year; - - if (!PyArg_ParseTuple(args, "i", &year)) - { - PyErr_SetString( - PyExc_ValueError, "Invalid parameters"); - return NULL; - } - - ndays = PyLong_FromLong(_days_in_year(year)); - - return ndays; -} - -PyObject *timestamp(PyObject *self, PyObject *args) -{ - int64_t result; - PyObject *dt; - - if (!PyArg_ParseTuple(args, "O", &dt)) - { - PyErr_SetString( - PyExc_ValueError, "Invalid parameters"); - return NULL; - } - - int year = (double)PyDateTime_GET_YEAR(dt); - int month = PyDateTime_GET_MONTH(dt); - int day = PyDateTime_GET_DAY(dt); - int hour = PyDateTime_DATE_GET_HOUR(dt); - int minute = PyDateTime_DATE_GET_MINUTE(dt); - int second = PyDateTime_DATE_GET_SECOND(dt); - - result = (year - 1970) * 365 + MONTHS_OFFSETS[0][month]; - result += (int)floor((double)(year - 1968) / 4); - result -= (year - 1900) / 100; - result += (year - 1600) / 400; - - if (_is_leap(year) && month < 3) - { - result -= 1; - } - - result += day - 1; - result *= 24; - result += hour; - result *= 60; - result += minute; - result *= 60; - result += second; - - return PyLong_FromSsize_t(result); -} - -PyObject *local_time(PyObject *self, PyObject *args) -{ - double unix_time; - int32_t utc_offset; - int32_t year; - int32_t microsecond; - int64_t seconds; - int32_t leap_year; - int64_t sec_per_100years; - int64_t sec_per_4years; - int32_t sec_per_year; - int32_t month; - int32_t day; - int32_t month_offset; - int32_t hour; - int32_t minute; - int32_t second; - - if (!PyArg_ParseTuple(args, "dii", &unix_time, &utc_offset, µsecond)) - { - PyErr_SetString( - PyExc_ValueError, "Invalid parameters"); - return NULL; - } - - year = EPOCH_YEAR; - seconds = (int64_t)floor(unix_time); - - // Shift to a base year that is 400-year aligned. - if (seconds >= 0) - { - seconds -= 10957L * SECS_PER_DAY; - year += 30; // == 2000; - } - else - { - seconds += (int64_t)(146097L - 10957L) * SECS_PER_DAY; - year -= 370; // == 1600; - } - - seconds += utc_offset; - - // Handle years in chunks of 400/100/4/1 - year += 400 * (seconds / SECS_PER_400_YEARS); - seconds %= SECS_PER_400_YEARS; - if (seconds < 0) - { - seconds += SECS_PER_400_YEARS; - year -= 400; - } - - leap_year = 1; // 4-century aligned - - sec_per_100years = SECS_PER_100_YEARS[leap_year]; - - while (seconds >= sec_per_100years) - { - seconds -= sec_per_100years; - year += 100; - leap_year = 0; // 1-century, non 4-century aligned - sec_per_100years = SECS_PER_100_YEARS[leap_year]; - } - - sec_per_4years = SECS_PER_4_YEARS[leap_year]; - while (seconds >= sec_per_4years) - { - seconds -= sec_per_4years; - year += 4; - leap_year = 1; // 4-year, non century aligned - sec_per_4years = SECS_PER_4_YEARS[leap_year]; - } - - sec_per_year = SECS_PER_YEAR[leap_year]; - while (seconds >= sec_per_year) - { - seconds -= sec_per_year; - year += 1; - leap_year = 0; // non 4-year aligned - sec_per_year = SECS_PER_YEAR[leap_year]; - } - - // Handle months and days - month = TM_DECEMBER + 1; - day = seconds / SECS_PER_DAY + 1; - seconds %= SECS_PER_DAY; - while (month != TM_JANUARY + 1) - { - month_offset = MONTHS_OFFSETS[leap_year][month]; - if (day > month_offset) - { - day -= month_offset; - break; - } - - month -= 1; - } - - // Handle hours, minutes and seconds - hour = seconds / SECS_PER_HOUR; - seconds %= SECS_PER_HOUR; - minute = seconds / SECS_PER_MIN; - second = seconds % SECS_PER_MIN; - - return Py_BuildValue("NNNNNNN", - PyLong_FromLong(year), - PyLong_FromLong(month), - PyLong_FromLong(day), - PyLong_FromLong(hour), - PyLong_FromLong(minute), - PyLong_FromLong(second), - PyLong_FromLong(microsecond)); -} - -// Calculate a precise difference between two datetimes. -PyObject *precise_diff(PyObject *self, PyObject *args) -{ - PyObject *dt1; - PyObject *dt2; - - if (!PyArg_ParseTuple(args, "OO", &dt1, &dt2)) - { - PyErr_SetString( - PyExc_ValueError, "Invalid parameters"); - return NULL; - } - - int year_diff = 0; - int month_diff = 0; - int day_diff = 0; - int hour_diff = 0; - int minute_diff = 0; - int second_diff = 0; - int microsecond_diff = 0; - int sign = 1; - int year; - int month; - int leap; - int days_in_last_month; - int days_in_month; - int dt1_year = PyDateTime_GET_YEAR(dt1); - int dt2_year = PyDateTime_GET_YEAR(dt2); - int dt1_month = PyDateTime_GET_MONTH(dt1); - int dt2_month = PyDateTime_GET_MONTH(dt2); - int dt1_day = PyDateTime_GET_DAY(dt1); - int dt2_day = PyDateTime_GET_DAY(dt2); - int dt1_hour = 0; - int dt2_hour = 0; - int dt1_minute = 0; - int dt2_minute = 0; - int dt1_second = 0; - int dt2_second = 0; - int dt1_microsecond = 0; - int dt2_microsecond = 0; - int dt1_total_seconds = 0; - int dt2_total_seconds = 0; - int dt1_offset = 0; - int dt2_offset = 0; - int dt1_is_datetime = PyDateTime_Check(dt1); - int dt2_is_datetime = PyDateTime_Check(dt2); - char *tz1 = ""; - char *tz2 = ""; - int in_same_tz = 0; - int total_days = (_day_number(dt2_year, dt2_month, dt2_day) - _day_number(dt1_year, dt1_month, dt1_day)); - - // If both dates are datetimes, we check - // If we are in the same timezone - if (dt1_is_datetime && dt2_is_datetime) - { - if (_has_tzinfo(dt1)) - { - tz1 = _get_tz_name(dt1); - dt1_offset = _get_offset(dt1); - } - - if (_has_tzinfo(dt2)) - { - tz2 = _get_tz_name(dt2); - dt2_offset = _get_offset(dt2); - } - - in_same_tz = tz1 == tz2 && strncmp(tz1, "", 1); - } - - // If we have datetimes (and not only dates) - // we get the information we need - if (dt1_is_datetime) - { - dt1_hour = PyDateTime_DATE_GET_HOUR(dt1); - dt1_minute = PyDateTime_DATE_GET_MINUTE(dt1); - dt1_second = PyDateTime_DATE_GET_SECOND(dt1); - dt1_microsecond = PyDateTime_DATE_GET_MICROSECOND(dt1); - - if ((!in_same_tz && dt1_offset != 0) || total_days == 0) - { - dt1_hour -= dt1_offset / SECS_PER_HOUR; - dt1_offset %= SECS_PER_HOUR; - dt1_minute -= dt1_offset / SECS_PER_MIN; - dt1_offset %= SECS_PER_MIN; - dt1_second -= dt1_offset; - - if (dt1_second < 0) - { - dt1_second += 60; - dt1_minute -= 1; - } - else if (dt1_second > 60) - { - dt1_second -= 60; - dt1_minute += 1; - } - - if (dt1_minute < 0) - { - dt1_minute += 60; - dt1_hour -= 1; - } - else if (dt1_minute > 60) - { - dt1_minute -= 60; - dt1_hour += 1; - } - - if (dt1_hour < 0) - { - dt1_hour += 24; - dt1_day -= 1; - } - else if (dt1_hour > 24) - { - dt1_hour -= 24; - dt1_day += 1; - } - } - - dt1_total_seconds = (dt1_hour * SECS_PER_HOUR + dt1_minute * SECS_PER_MIN + dt1_second); - } - - if (dt2_is_datetime) - { - dt2_hour = PyDateTime_DATE_GET_HOUR(dt2); - dt2_minute = PyDateTime_DATE_GET_MINUTE(dt2); - dt2_second = PyDateTime_DATE_GET_SECOND(dt2); - dt2_microsecond = PyDateTime_DATE_GET_MICROSECOND(dt2); - - if ((!in_same_tz && dt2_offset != 0) || total_days == 0) - { - dt2_hour -= dt2_offset / SECS_PER_HOUR; - dt2_offset %= SECS_PER_HOUR; - dt2_minute -= dt2_offset / SECS_PER_MIN; - dt2_offset %= SECS_PER_MIN; - dt2_second -= dt2_offset; - - if (dt2_second < 0) - { - dt2_second += 60; - dt2_minute -= 1; - } - else if (dt2_second > 60) - { - dt2_second -= 60; - dt2_minute += 1; - } - - if (dt2_minute < 0) - { - dt2_minute += 60; - dt2_hour -= 1; - } - else if (dt2_minute > 60) - { - dt2_minute -= 60; - dt2_hour += 1; - } - - if (dt2_hour < 0) - { - dt2_hour += 24; - dt2_day -= 1; - } - else if (dt2_hour > 24) - { - dt2_hour -= 24; - dt2_day += 1; - } - } - - dt2_total_seconds = (dt2_hour * SECS_PER_HOUR + dt2_minute * SECS_PER_MIN + dt2_second); - } - - // Direct comparison between two datetimes does not work - // so we need to check by properties - int dt1_gt_dt2 = (dt1_year > dt2_year || (dt1_year == dt2_year && dt1_month > dt2_month) || (dt1_year == dt2_year && dt1_month == dt2_month && dt1_day > dt2_day) || (dt1_year == dt2_year && dt1_month == dt2_month && dt1_day == dt2_day && dt1_total_seconds > dt2_total_seconds) || (dt1_year == dt2_year && dt1_month == dt2_month && dt1_day == dt2_day && dt1_total_seconds == dt2_total_seconds && dt1_microsecond > dt2_microsecond)); - - if (dt1_gt_dt2) - { - PyObject *temp; - temp = dt1; - dt1 = dt2; - dt2 = temp; - sign = -1; - - // Retrieving properties - dt1_year = PyDateTime_GET_YEAR(dt1); - dt2_year = PyDateTime_GET_YEAR(dt2); - dt1_month = PyDateTime_GET_MONTH(dt1); - dt2_month = PyDateTime_GET_MONTH(dt2); - dt1_day = PyDateTime_GET_DAY(dt1); - dt2_day = PyDateTime_GET_DAY(dt2); - - if (dt2_is_datetime) - { - dt1_hour = PyDateTime_DATE_GET_HOUR(dt1); - dt1_minute = PyDateTime_DATE_GET_MINUTE(dt1); - dt1_second = PyDateTime_DATE_GET_SECOND(dt1); - dt1_microsecond = PyDateTime_DATE_GET_MICROSECOND(dt1); - } - - if (dt1_is_datetime) - { - dt2_hour = PyDateTime_DATE_GET_HOUR(dt2); - dt2_minute = PyDateTime_DATE_GET_MINUTE(dt2); - dt2_second = PyDateTime_DATE_GET_SECOND(dt2); - dt2_microsecond = PyDateTime_DATE_GET_MICROSECOND(dt2); - } - - total_days = (_day_number(dt2_year, dt2_month, dt2_day) - _day_number(dt1_year, dt1_month, dt1_day)); - } - - year_diff = dt2_year - dt1_year; - month_diff = dt2_month - dt1_month; - day_diff = dt2_day - dt1_day; - hour_diff = dt2_hour - dt1_hour; - minute_diff = dt2_minute - dt1_minute; - second_diff = dt2_second - dt1_second; - microsecond_diff = dt2_microsecond - dt1_microsecond; - - if (microsecond_diff < 0) - { - microsecond_diff += 1e6; - second_diff -= 1; - } - - if (second_diff < 0) - { - second_diff += 60; - minute_diff -= 1; - } - - if (minute_diff < 0) - { - minute_diff += 60; - hour_diff -= 1; - } - - if (hour_diff < 0) - { - hour_diff += 24; - day_diff -= 1; - } - - if (day_diff < 0) - { - // If we have a difference in days, - // we have to check if they represent months - year = dt2_year; - month = dt2_month; - - if (month == 1) - { - month = 12; - year -= 1; - } - else - { - month -= 1; - } - - leap = _is_leap(year); - - days_in_last_month = DAYS_PER_MONTHS[leap][month]; - days_in_month = DAYS_PER_MONTHS[_is_leap(dt2_year)][dt2_month]; - - if (day_diff < days_in_month - days_in_last_month) - { - // We don't have a full month, we calculate days - if (days_in_last_month < dt1_day) - { - day_diff += dt1_day; - } - else - { - day_diff += days_in_last_month; - } - } - else if (day_diff == days_in_month - days_in_last_month) - { - // We have exactly a full month - // We remove the days difference - // and add one to the months difference - day_diff = 0; - month_diff += 1; - } - else - { - // We have a full month - day_diff += days_in_last_month; - } - - month_diff -= 1; - } - - if (month_diff < 0) - { - month_diff += 12; - year_diff -= 1; - } - - return new_diff( - year_diff * sign, - month_diff * sign, - day_diff * sign, - hour_diff * sign, - minute_diff * sign, - second_diff * sign, - microsecond_diff * sign, - total_days * sign); -} - -/* ------------------------------------------------------------------------- */ - -static PyMethodDef helpers_methods[] = { - {"is_leap", - (PyCFunction)is_leap, - METH_VARARGS, - PyDoc_STR("Checks if a year is a leap year.")}, - {"is_long_year", - (PyCFunction)is_long_year, - METH_VARARGS, - PyDoc_STR("Checks if a year is a long year.")}, - {"week_day", - (PyCFunction)week_day, - METH_VARARGS, - PyDoc_STR("Returns the weekday number.")}, - {"days_in_year", - (PyCFunction)days_in_year, - METH_VARARGS, - PyDoc_STR("Returns the number of days in the given year.")}, - {"timestamp", - (PyCFunction)timestamp, - METH_VARARGS, - PyDoc_STR("Returns the timestamp of the given datetime.")}, - {"local_time", - (PyCFunction)local_time, - METH_VARARGS, - PyDoc_STR("Returns a UNIX time as a broken down time for a particular transition type.")}, - {"precise_diff", - (PyCFunction)precise_diff, - METH_VARARGS, - PyDoc_STR("Calculate a precise difference between two datetimes.")}, - {NULL}}; - -/* ------------------------------------------------------------------------- */ - -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "_helpers", - NULL, - -1, - helpers_methods, - NULL, - NULL, - NULL, - NULL, -}; - -PyMODINIT_FUNC -PyInit__helpers(void) -{ - PyObject *module; - - PyDateTime_IMPORT; - - module = PyModule_Create(&moduledef); - - if (module == NULL) - return NULL; - - // Diff declaration - Diff_type.tp_new = PyType_GenericNew; - Diff_type.tp_members = Diff_members; - Diff_type.tp_init = (initproc)Diff_init; - - if (PyType_Ready(&Diff_type) < 0) - return NULL; - - PyModule_AddObject(module, "PreciseDiff", (PyObject *)&Diff_type); - - return module; -} diff --git a/pendulum/_extensions/_helpers.pyi b/pendulum/_extensions/_helpers.pyi deleted file mode 100644 index 99a5397..0000000 --- a/pendulum/_extensions/_helpers.pyi +++ /dev/null @@ -1,31 +0,0 @@ -from __future__ import annotations - -from collections import namedtuple -from datetime import date -from datetime import datetime - -def days_in_year(year: int) -> int: ... -def is_leap(year: int) -> bool: ... -def is_long_year(year: int) -> bool: ... -def local_time( - unix_time: int, utc_offset: int, microseconds: int -) -> tuple[int, int, int, int, int, int, int]: ... - -class PreciseDiff( - namedtuple( - "PreciseDiff", - "years months days " "hours minutes seconds microseconds " "total_days", - ) -): - years: int - months: int - days: int - hours: int - minutes: int - seconds: int - microseconds: int - total_days: int - -def precise_diff(d1: datetime | date, d2: datetime | date) -> PreciseDiff: ... -def timestamp(dt: datetime) -> int: ... -def week_day(year: int, month: int, day: int) -> int: ... diff --git a/pendulum/_extensions/helpers.py b/pendulum/_extensions/helpers.py deleted file mode 100644 index 01066a3..0000000 --- a/pendulum/_extensions/helpers.py +++ /dev/null @@ -1,364 +0,0 @@ -from __future__ import annotations - -import datetime -import math - -from collections import namedtuple -from typing import cast - -from pendulum.constants import DAY_OF_WEEK_TABLE -from pendulum.constants import DAYS_PER_L_YEAR -from pendulum.constants import DAYS_PER_MONTHS -from pendulum.constants import DAYS_PER_N_YEAR -from pendulum.constants import EPOCH_YEAR -from pendulum.constants import MONTHS_OFFSETS -from pendulum.constants import SECS_PER_4_YEARS -from pendulum.constants import SECS_PER_100_YEARS -from pendulum.constants import SECS_PER_400_YEARS -from pendulum.constants import SECS_PER_DAY -from pendulum.constants import SECS_PER_HOUR -from pendulum.constants import SECS_PER_MIN -from pendulum.constants import SECS_PER_YEAR -from pendulum.constants import TM_DECEMBER -from pendulum.constants import TM_JANUARY -from pendulum.tz.timezone import Timezone -from pendulum.utils._compat import zoneinfo - - -class PreciseDiff( - namedtuple( - "PreciseDiff", - "years months days " "hours minutes seconds microseconds " "total_days", - ) -): - years: int - months: int - days: int - hours: int - minutes: int - seconds: int - microseconds: int - total_days: int - - def __repr__(self) -> str: - return ( - f"{self.years} years " - f"{self.months} months " - f"{self.days} days " - f"{self.hours} hours " - f"{self.minutes} minutes " - f"{self.seconds} seconds " - f"{self.microseconds} microseconds" - ) - - -def is_leap(year: int) -> bool: - return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) - - -def is_long_year(year: int) -> bool: - def p(y: int) -> int: - return y + y // 4 - y // 100 + y // 400 - - return p(year) % 7 == 4 or p(year - 1) % 7 == 3 - - -def week_day(year: int, month: int, day: int) -> int: - if month < 3: - year -= 1 - - w = ( - year - + year // 4 - - year // 100 - + year // 400 - + DAY_OF_WEEK_TABLE[month - 1] - + day - ) % 7 - - if not w: - w = 7 - - return w - - -def days_in_year(year: int) -> int: - if is_leap(year): - return DAYS_PER_L_YEAR - - return DAYS_PER_N_YEAR - - -def timestamp(dt: datetime.datetime) -> int: - year = dt.year - - result = (year - 1970) * 365 + MONTHS_OFFSETS[0][dt.month] - result += (year - 1968) // 4 - result -= (year - 1900) // 100 - result += (year - 1600) // 400 - - if is_leap(year) and dt.month < 3: - result -= 1 - - result += dt.day - 1 - result *= 24 - result += dt.hour - result *= 60 - result += dt.minute - result *= 60 - result += dt.second - - return result - - -def local_time( - unix_time: int, utc_offset: int, microseconds: int -) -> tuple[int, int, int, int, int, int, int]: - """ - Returns a UNIX time as a broken-down time - for a particular transition type. - """ - year = EPOCH_YEAR - seconds = int(math.floor(unix_time)) - - # Shift to a base year that is 400-year aligned. - if seconds >= 0: - seconds -= 10957 * SECS_PER_DAY - year += 30 # == 2000 - else: - seconds += (146097 - 10957) * SECS_PER_DAY - year -= 370 # == 1600 - - seconds += utc_offset - - # Handle years in chunks of 400/100/4/1 - year += 400 * (seconds // SECS_PER_400_YEARS) - seconds %= SECS_PER_400_YEARS - if seconds < 0: - seconds += SECS_PER_400_YEARS - year -= 400 - - leap_year = 1 # 4-century aligned - - sec_per_100years = SECS_PER_100_YEARS[leap_year] - while seconds >= sec_per_100years: - seconds -= sec_per_100years - year += 100 - leap_year = 0 # 1-century, non 4-century aligned - sec_per_100years = SECS_PER_100_YEARS[leap_year] - - sec_per_4years = SECS_PER_4_YEARS[leap_year] - while seconds >= sec_per_4years: - seconds -= sec_per_4years - year += 4 - leap_year = 1 # 4-year, non century aligned - sec_per_4years = SECS_PER_4_YEARS[leap_year] - - sec_per_year = SECS_PER_YEAR[leap_year] - while seconds >= sec_per_year: - seconds -= sec_per_year - year += 1 - leap_year = 0 # non 4-year aligned - sec_per_year = SECS_PER_YEAR[leap_year] - - # Handle months and days - month = TM_DECEMBER + 1 - day = seconds // SECS_PER_DAY + 1 - seconds %= SECS_PER_DAY - while month != TM_JANUARY + 1: - month_offset = MONTHS_OFFSETS[leap_year][month] - if day > month_offset: - day -= month_offset - break - - month -= 1 - - # Handle hours, minutes, seconds and microseconds - hour = seconds // SECS_PER_HOUR - seconds %= SECS_PER_HOUR - minute = seconds // SECS_PER_MIN - second = seconds % SECS_PER_MIN - - return year, month, day, hour, minute, second, microseconds - - -def precise_diff( - d1: datetime.datetime | datetime.date, d2: datetime.datetime | datetime.date -) -> PreciseDiff: - """ - Calculate a precise difference between two datetimes. - - :param d1: The first datetime - :param d2: The second datetime - """ - sign = 1 - - if d1 == d2: - return PreciseDiff(0, 0, 0, 0, 0, 0, 0, 0) - - tzinfo1: datetime.tzinfo | None = ( - d1.tzinfo if isinstance(d1, datetime.datetime) else None - ) - tzinfo2: datetime.tzinfo | None = ( - d2.tzinfo if isinstance(d2, datetime.datetime) else None - ) - - if ( - tzinfo1 is None - and tzinfo2 is not None - or tzinfo2 is None - and tzinfo1 is not None - ): - raise ValueError( - "Comparison between naive and aware datetimes is not supported" - ) - - if d1 > d2: - d1, d2 = d2, d1 - sign = -1 - - d_diff = 0 - hour_diff = 0 - min_diff = 0 - sec_diff = 0 - mic_diff = 0 - total_days = _day_number(d2.year, d2.month, d2.day) - _day_number( - d1.year, d1.month, d1.day - ) - in_same_tz = False - tz1 = None - tz2 = None - - # Trying to figure out the timezone names - # If we can't find them, we assume different timezones - if tzinfo1 and tzinfo2: - tz1 = _get_tzinfo_name(tzinfo1) - tz2 = _get_tzinfo_name(tzinfo2) - - in_same_tz = tz1 == tz2 and tz1 is not None - - if isinstance(d2, datetime.datetime): - if isinstance(d1, datetime.datetime): - # If we are not in the same timezone - # we need to adjust - # - # We also need to adjust if we do not - # have variable-length units - if not in_same_tz or total_days == 0: - offset1 = d1.utcoffset() - offset2 = d2.utcoffset() - - if offset1: - d1 = d1 - offset1 - - if offset2: - d2 = d2 - offset2 - - hour_diff = d2.hour - d1.hour - min_diff = d2.minute - d1.minute - sec_diff = d2.second - d1.second - mic_diff = d2.microsecond - d1.microsecond - else: - hour_diff = d2.hour - min_diff = d2.minute - sec_diff = d2.second - mic_diff = d2.microsecond - - if mic_diff < 0: - mic_diff += 1000000 - sec_diff -= 1 - - if sec_diff < 0: - sec_diff += 60 - min_diff -= 1 - - if min_diff < 0: - min_diff += 60 - hour_diff -= 1 - - if hour_diff < 0: - hour_diff += 24 - d_diff -= 1 - - y_diff = d2.year - d1.year - m_diff = d2.month - d1.month - d_diff += d2.day - d1.day - - if d_diff < 0: - year = d2.year - month = d2.month - - if month == 1: - month = 12 - year -= 1 - else: - month -= 1 - - leap = int(is_leap(year)) - - days_in_last_month = DAYS_PER_MONTHS[leap][month] - days_in_month = DAYS_PER_MONTHS[int(is_leap(d2.year))][d2.month] - - if d_diff < days_in_month - days_in_last_month: - # We don't have a full month, we calculate days - if days_in_last_month < d1.day: - d_diff += d1.day - else: - d_diff += days_in_last_month - elif d_diff == days_in_month - days_in_last_month: - # We have exactly a full month - # We remove the days difference - # and add one to the months difference - d_diff = 0 - m_diff += 1 - else: - # We have a full month - d_diff += days_in_last_month - - m_diff -= 1 - - if m_diff < 0: - m_diff += 12 - y_diff -= 1 - - return PreciseDiff( - sign * y_diff, - sign * m_diff, - sign * d_diff, - sign * hour_diff, - sign * min_diff, - sign * sec_diff, - sign * mic_diff, - sign * total_days, - ) - - -def _day_number(year: int, month: int, day: int) -> int: - month = (month + 9) % 12 - year = year - month // 10 - - return ( - 365 * year - + year // 4 - - year // 100 - + year // 400 - + (month * 306 + 5) // 10 - + (day - 1) - ) - - -def _get_tzinfo_name(tzinfo: datetime.tzinfo | None) -> str | None: - if tzinfo is None: - return None - - if hasattr(tzinfo, "key"): - # zoneinfo timezone - return cast(str, cast(zoneinfo.ZoneInfo, tzinfo).key) - elif hasattr(tzinfo, "name"): - # Pendulum timezone - return cast(Timezone, tzinfo).name - elif hasattr(tzinfo, "zone"): - # pytz timezone - return tzinfo.zone # type: ignore - - return None diff --git a/pendulum/constants.py b/pendulum/constants.py deleted file mode 100644 index a3d2a18..0000000 --- a/pendulum/constants.py +++ /dev/null @@ -1,109 +0,0 @@ -# The day constants -from __future__ import annotations - -SUNDAY = 0 -MONDAY = 1 -TUESDAY = 2 -WEDNESDAY = 3 -THURSDAY = 4 -FRIDAY = 5 -SATURDAY = 6 - -# Number of X in Y. -YEARS_PER_CENTURY = 100 -YEARS_PER_DECADE = 10 -MONTHS_PER_YEAR = 12 -WEEKS_PER_YEAR = 52 -DAYS_PER_WEEK = 7 -HOURS_PER_DAY = 24 -MINUTES_PER_HOUR = 60 -SECONDS_PER_MINUTE = 60 -SECONDS_PER_HOUR = MINUTES_PER_HOUR * SECONDS_PER_MINUTE -SECONDS_PER_DAY = HOURS_PER_DAY * SECONDS_PER_HOUR -US_PER_SECOND = 1000000 - -# Formats -ATOM = "YYYY-MM-DDTHH:mm:ssZ" -COOKIE = "dddd, DD-MMM-YYYY HH:mm:ss zz" -ISO8601 = "YYYY-MM-DDTHH:mm:ssZ" -ISO8601_EXTENDED = "YYYY-MM-DDTHH:mm:ss.SSSSSSZ" -RFC822 = "ddd, DD MMM YY HH:mm:ss ZZ" -RFC850 = "dddd, DD-MMM-YY HH:mm:ss zz" -RFC1036 = "ddd, DD MMM YY HH:mm:ss ZZ" -RFC1123 = "ddd, DD MMM YYYY HH:mm:ss ZZ" -RFC2822 = "ddd, DD MMM YYYY HH:mm:ss ZZ" -RFC3339 = ISO8601 -RFC3339_EXTENDED = ISO8601_EXTENDED -RSS = "ddd, DD MMM YYYY HH:mm:ss ZZ" -W3C = ISO8601 - - -EPOCH_YEAR = 1970 - -DAYS_PER_N_YEAR = 365 -DAYS_PER_L_YEAR = 366 - -USECS_PER_SEC = 1000000 - -SECS_PER_MIN = 60 -SECS_PER_HOUR = 60 * SECS_PER_MIN -SECS_PER_DAY = SECS_PER_HOUR * 24 - -# 400-year chunks always have 146097 days (20871 weeks). -SECS_PER_400_YEARS = 146097 * SECS_PER_DAY - -# The number of seconds in an aligned 100-year chunk, for those that -# do not begin with a leap year and those that do respectively. -SECS_PER_100_YEARS = ( - (76 * DAYS_PER_N_YEAR + 24 * DAYS_PER_L_YEAR) * SECS_PER_DAY, - (75 * DAYS_PER_N_YEAR + 25 * DAYS_PER_L_YEAR) * SECS_PER_DAY, -) - -# The number of seconds in an aligned 4-year chunk, for those that -# do not begin with a leap year and those that do respectively. -SECS_PER_4_YEARS = ( - (4 * DAYS_PER_N_YEAR + 0 * DAYS_PER_L_YEAR) * SECS_PER_DAY, - (3 * DAYS_PER_N_YEAR + 1 * DAYS_PER_L_YEAR) * SECS_PER_DAY, -) - -# The number of seconds in non-leap and leap years respectively. -SECS_PER_YEAR = (DAYS_PER_N_YEAR * SECS_PER_DAY, DAYS_PER_L_YEAR * SECS_PER_DAY) - -DAYS_PER_YEAR = (DAYS_PER_N_YEAR, DAYS_PER_L_YEAR) - -# The month lengths in non-leap and leap years respectively. -DAYS_PER_MONTHS = ( - (-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31), - (-1, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31), -) - -# The day offsets of the beginning of each (1-based) month in non-leap -# and leap years respectively. -# For example, in a leap year there are 335 days before December. -MONTHS_OFFSETS = ( - (-1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365), - (-1, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366), -) - -DAY_OF_WEEK_TABLE = (0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4) - -TM_SUNDAY = 0 -TM_MONDAY = 1 -TM_TUESDAY = 2 -TM_WEDNESDAY = 3 -TM_THURSDAY = 4 -TM_FRIDAY = 5 -TM_SATURDAY = 6 - -TM_JANUARY = 0 -TM_FEBRUARY = 1 -TM_MARCH = 2 -TM_APRIL = 3 -TM_MAY = 4 -TM_JUNE = 5 -TM_JULY = 6 -TM_AUGUST = 7 -TM_SEPTEMBER = 8 -TM_OCTOBER = 9 -TM_NOVEMBER = 10 -TM_DECEMBER = 11 diff --git a/pendulum/date.py b/pendulum/date.py deleted file mode 100644 index 4e2655b..0000000 --- a/pendulum/date.py +++ /dev/null @@ -1,760 +0,0 @@ -from __future__ import annotations - -import calendar -import math - -from datetime import date -from datetime import datetime -from datetime import timedelta -from typing import NoReturn -from typing import cast -from typing import overload - -import pendulum - -from pendulum.constants import FRIDAY -from pendulum.constants import MONDAY -from pendulum.constants import MONTHS_PER_YEAR -from pendulum.constants import SATURDAY -from pendulum.constants import SUNDAY -from pendulum.constants import THURSDAY -from pendulum.constants import TUESDAY -from pendulum.constants import WEDNESDAY -from pendulum.constants import YEARS_PER_CENTURY -from pendulum.constants import YEARS_PER_DECADE -from pendulum.exceptions import PendulumException -from pendulum.helpers import add_duration -from pendulum.interval import Interval -from pendulum.mixins.default import FormattableMixin - - -class Date(FormattableMixin, date): - # Names of days of the week - _days = { - SUNDAY: "Sunday", - MONDAY: "Monday", - TUESDAY: "Tuesday", - WEDNESDAY: "Wednesday", - THURSDAY: "Thursday", - FRIDAY: "Friday", - SATURDAY: "Saturday", - } - - _MODIFIERS_VALID_UNITS = ["day", "week", "month", "year", "decade", "century"] - - # Getters/Setters - - def set( - self, year: int | None = None, month: int | None = None, day: int | None = None - ) -> Date: - return self.replace(year=year, month=month, day=day) - - @property - def day_of_week(self) -> int: - """ - Returns the day of the week (0-6). - """ - return self.isoweekday() % 7 - - @property - def day_of_year(self) -> int: - """ - Returns the day of the year (1-366). - """ - k = 1 if self.is_leap_year() else 2 - - return (275 * self.month) // 9 - k * ((self.month + 9) // 12) + self.day - 30 - - @property - def week_of_year(self) -> int: - return self.isocalendar()[1] - - @property - def days_in_month(self) -> int: - return calendar.monthrange(self.year, self.month)[1] - - @property - def week_of_month(self) -> int: - first_day_of_month = self.replace(day=1) - - return self.week_of_year - first_day_of_month.week_of_year + 1 - - @property - def age(self) -> int: - return self.diff(abs=False).in_years() - - @property - def quarter(self) -> int: - return int(math.ceil(self.month / 3)) - - # String Formatting - - def to_date_string(self) -> str: - """ - Format the instance as date. - - :rtype: str - """ - return self.strftime("%Y-%m-%d") - - def to_formatted_date_string(self) -> str: - """ - Format the instance as a readable date. - - :rtype: str - """ - return self.strftime("%b %d, %Y") - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self.year}, {self.month}, {self.day})" - - # COMPARISONS - - def closest(self, dt1: date, dt2: date) -> Date: - """ - Get the closest date from the instance. - """ - dt1 = self.__class__(dt1.year, dt1.month, dt1.day) - dt2 = self.__class__(dt2.year, dt2.month, dt2.day) - - if self.diff(dt1).in_seconds() < self.diff(dt2).in_seconds(): - return dt1 - - return dt2 - - def farthest(self, dt1: date, dt2: date) -> Date: - """ - Get the farthest date from the instance. - """ - dt1 = self.__class__(dt1.year, dt1.month, dt1.day) - dt2 = self.__class__(dt2.year, dt2.month, dt2.day) - - if self.diff(dt1).in_seconds() > self.diff(dt2).in_seconds(): - return dt1 - - return dt2 - - def is_future(self) -> bool: - """ - Determines if the instance is in the future, ie. greater than now. - """ - return self > self.today() - - def is_past(self) -> bool: - """ - Determines if the instance is in the past, ie. less than now. - """ - return self < self.today() - - def is_leap_year(self) -> bool: - """ - Determines if the instance is a leap year. - """ - return calendar.isleap(self.year) - - def is_long_year(self) -> bool: - """ - Determines if the instance is a long year - - See link ``_ - """ - return Date(self.year, 12, 28).isocalendar()[1] == 53 - - def is_same_day(self, dt: date) -> bool: - """ - Checks if the passed in date is the same day as the instance current day. - """ - return self == dt - - def is_anniversary(self, dt: date | None = None) -> bool: - """ - Check if it's the anniversary. - - Compares the date/month values of the two dates. - """ - if dt is None: - dt = Date.today() - - instance = self.__class__(dt.year, dt.month, dt.day) - - return (self.month, self.day) == (instance.month, instance.day) - - # the additional method for checking if today is the anniversary day - # the alias is provided to start using a new name and keep the backward compatibility - # the old name can be completely replaced with the new in one of the future versions - is_birthday = is_anniversary - - # ADDITIONS AND SUBTRACTIONS - - def add( - self, years: int = 0, months: int = 0, weeks: int = 0, days: int = 0 - ) -> Date: - """ - Add duration to the instance. - - :param years: The number of years - :param months: The number of months - :param weeks: The number of weeks - :param days: The number of days - """ - dt = add_duration( - date(self.year, self.month, self.day), - years=years, - months=months, - weeks=weeks, - days=days, - ) - - return self.__class__(dt.year, dt.month, dt.day) - - def subtract( - self, years: int = 0, months: int = 0, weeks: int = 0, days: int = 0 - ) -> Date: - """ - Remove duration from the instance. - - :param years: The number of years - :param months: The number of months - :param weeks: The number of weeks - :param days: The number of days - """ - return self.add(years=-years, months=-months, weeks=-weeks, days=-days) - - def _add_timedelta(self, delta: timedelta) -> Date: - """ - Add timedelta duration to the instance. - - :param delta: The timedelta instance - """ - if isinstance(delta, pendulum.Duration): - return self.add( - years=delta.years, - months=delta.months, - weeks=delta.weeks, - days=delta.remaining_days, - ) - - return self.add(days=delta.days) - - def _subtract_timedelta(self, delta: timedelta) -> Date: - """ - Remove timedelta duration from the instance. - - :param delta: The timedelta instance - """ - if isinstance(delta, pendulum.Duration): - return self.subtract( - years=delta.years, - months=delta.months, - weeks=delta.weeks, - days=delta.remaining_days, - ) - - return self.subtract(days=delta.days) - - def __add__(self, other: timedelta) -> Date: - if not isinstance(other, timedelta): - return NotImplemented - - return self._add_timedelta(other) - - @overload - def __sub__(self, delta: timedelta) -> Date: - ... - - @overload - def __sub__(self, dt: datetime) -> NoReturn: - ... - - @overload - def __sub__(self, dt: Date) -> Interval: - ... - - def __sub__(self, other: timedelta | date) -> Date | Interval: - if isinstance(other, timedelta): - return self._subtract_timedelta(other) - - if not isinstance(other, date): - return NotImplemented - - dt = self.__class__(other.year, other.month, other.day) - - return dt.diff(self, False) - - # DIFFERENCES - - def diff(self, dt: date | None = None, abs: bool = True) -> Interval: - """ - Returns the difference between two Date objects as an Interval. - - :param dt: The date to compare to (defaults to today) - :param abs: Whether to return an absolute interval or not - """ - if dt is None: - dt = self.today() - - return Interval(self, Date(dt.year, dt.month, dt.day), absolute=abs) - - def diff_for_humans( - self, - other: date | None = None, - absolute: bool = False, - locale: str | None = None, - ) -> str: - """ - Get the difference in a human readable format in the current locale. - - When comparing a value in the past to default now: - 1 day ago - 5 months ago - - When comparing a value in the future to default now: - 1 day from now - 5 months from now - - When comparing a value in the past to another value: - 1 day before - 5 months before - - When comparing a value in the future to another value: - 1 day after - 5 months after - - :param other: The date to compare to (defaults to today) - :param absolute: removes time difference modifiers ago, after, etc - :param locale: The locale to use for localization - """ - is_now = other is None - - if is_now: - other = self.today() - - diff = self.diff(other) - - return pendulum.format_diff(diff, is_now, absolute, locale) - - # MODIFIERS - - def start_of(self, unit: str) -> Date: - """ - Returns a copy of the instance with the time reset - with the following rules: - - * day: time to 00:00:00 - * week: date to first day of the week and time to 00:00:00 - * month: date to first day of the month and time to 00:00:00 - * year: date to first day of the year and time to 00:00:00 - * decade: date to first day of the decade and time to 00:00:00 - * century: date to first day of century and time to 00:00:00 - - :param unit: The unit to reset to - """ - if unit not in self._MODIFIERS_VALID_UNITS: - raise ValueError(f'Invalid unit "{unit}" for start_of()') - - return cast(Date, getattr(self, f"_start_of_{unit}")()) - - def end_of(self, unit: str) -> Date: - """ - Returns a copy of the instance with the time reset - with the following rules: - - * week: date to last day of the week - * month: date to last day of the month - * year: date to last day of the year - * decade: date to last day of the decade - * century: date to last day of century - - :param unit: The unit to reset to - """ - if unit not in self._MODIFIERS_VALID_UNITS: - raise ValueError(f'Invalid unit "{unit}" for end_of()') - - return cast(Date, getattr(self, f"_end_of_{unit}")()) - - def _start_of_day(self) -> Date: - """ - Compatibility method. - """ - return self - - def _end_of_day(self) -> Date: - """ - Compatibility method - """ - return self - - def _start_of_month(self) -> Date: - """ - Reset the date to the first day of the month. - """ - return self.set(self.year, self.month, 1) - - def _end_of_month(self) -> Date: - """ - Reset the date to the last day of the month. - """ - return self.set(self.year, self.month, self.days_in_month) - - def _start_of_year(self) -> Date: - """ - Reset the date to the first day of the year. - """ - return self.set(self.year, 1, 1) - - def _end_of_year(self) -> Date: - """ - Reset the date to the last day of the year. - """ - return self.set(self.year, 12, 31) - - def _start_of_decade(self) -> Date: - """ - Reset the date to the first day of the decade. - """ - year = self.year - self.year % YEARS_PER_DECADE - - return self.set(year, 1, 1) - - def _end_of_decade(self) -> Date: - """ - Reset the date to the last day of the decade. - """ - year = self.year - self.year % YEARS_PER_DECADE + YEARS_PER_DECADE - 1 - - return self.set(year, 12, 31) - - def _start_of_century(self) -> Date: - """ - Reset the date to the first day of the century. - """ - year = self.year - 1 - (self.year - 1) % YEARS_PER_CENTURY + 1 - - return self.set(year, 1, 1) - - def _end_of_century(self) -> Date: - """ - Reset the date to the last day of the century. - """ - year = self.year - 1 - (self.year - 1) % YEARS_PER_CENTURY + YEARS_PER_CENTURY - - return self.set(year, 12, 31) - - def _start_of_week(self) -> Date: - """ - Reset the date to the first day of the week. - """ - dt = self - - if self.day_of_week != pendulum._WEEK_STARTS_AT: - dt = self.previous(pendulum._WEEK_STARTS_AT) - - return dt.start_of("day") - - def _end_of_week(self) -> Date: - """ - Reset the date to the last day of the week. - """ - dt = self - - if self.day_of_week != pendulum._WEEK_ENDS_AT: - dt = self.next(pendulum._WEEK_ENDS_AT) - - return dt.end_of("day") - - def next(self, day_of_week: int | None = None) -> Date: - """ - Modify to the next occurrence of a given day of the week. - If no day_of_week is provided, modify to the next occurrence - of the current day of the week. Use the supplied consts - to indicate the desired day_of_week, ex. pendulum.MONDAY. - - :param day_of_week: The next day of week to reset to. - """ - if day_of_week is None: - day_of_week = self.day_of_week - - if day_of_week < SUNDAY or day_of_week > SATURDAY: - raise ValueError("Invalid day of week") - - dt = self.add(days=1) - while dt.day_of_week != day_of_week: - dt = dt.add(days=1) - - return dt - - def previous(self, day_of_week: int | None = None) -> Date: - """ - Modify to the previous occurrence of a given day of the week. - If no day_of_week is provided, modify to the previous occurrence - of the current day of the week. Use the supplied consts - to indicate the desired day_of_week, ex. pendulum.MONDAY. - - :param day_of_week: The previous day of week to reset to. - """ - if day_of_week is None: - day_of_week = self.day_of_week - - if day_of_week < SUNDAY or day_of_week > SATURDAY: - raise ValueError("Invalid day of week") - - dt = self.subtract(days=1) - while dt.day_of_week != day_of_week: - dt = dt.subtract(days=1) - - return dt - - def first_of(self, unit: str, day_of_week: int | None = None) -> Date: - """ - Returns an instance set to the first occurrence - of a given day of the week in the current unit. - If no day_of_week is provided, modify to the first day of the unit. - Use the supplied consts to indicate the desired day_of_week, ex. pendulum.MONDAY. - - Supported units are month, quarter and year. - - :param unit: The unit to use - :param day_of_week: The day of week to reset to. - """ - if unit not in ["month", "quarter", "year"]: - raise ValueError(f'Invalid unit "{unit}" for first_of()') - - return cast(Date, getattr(self, f"_first_of_{unit}")(day_of_week)) - - def last_of(self, unit: str, day_of_week: int | None = None) -> Date: - """ - Returns an instance set to the last occurrence - of a given day of the week in the current unit. - If no day_of_week is provided, modify to the last day of the unit. - Use the supplied consts to indicate the desired day_of_week, ex. pendulum.MONDAY. - - Supported units are month, quarter and year. - - :param unit: The unit to use - :param day_of_week: The day of week to reset to. - """ - if unit not in ["month", "quarter", "year"]: - raise ValueError(f'Invalid unit "{unit}" for first_of()') - - return cast(Date, getattr(self, f"_last_of_{unit}")(day_of_week)) - - def nth_of(self, unit: str, nth: int, day_of_week: int) -> Date: - """ - Returns a new instance set to the given occurrence - of a given day of the week in the current unit. - If the calculated occurrence is outside the scope of the current unit, - then raise an error. Use the supplied consts - to indicate the desired day_of_week, ex. pendulum.MONDAY. - - Supported units are month, quarter and year. - - :param unit: The unit to use - :param nth: The occurrence to use - :param day_of_week: The day of week to set to. - """ - if unit not in ["month", "quarter", "year"]: - raise ValueError(f'Invalid unit "{unit}" for first_of()') - - dt = cast(Date, getattr(self, f"_nth_of_{unit}")(nth, day_of_week)) - if not dt: - raise PendulumException( - f"Unable to find occurence {nth}" - f" of {self._days[day_of_week]} in {unit}" - ) - - return dt - - def _first_of_month(self, day_of_week: int) -> Date: - """ - Modify to the first occurrence of a given day of the week - in the current month. If no day_of_week is provided, - modify to the first day of the month. Use the supplied consts - to indicate the desired day_of_week, ex. pendulum.MONDAY. - - :param day_of_week: The day of week to set to. - """ - dt = self - - if day_of_week is None: - return dt.set(day=1) - - month = calendar.monthcalendar(dt.year, dt.month) - - calendar_day = (day_of_week - 1) % 7 - - if month[0][calendar_day] > 0: - day_of_month = month[0][calendar_day] - else: - day_of_month = month[1][calendar_day] - - return dt.set(day=day_of_month) - - def _last_of_month(self, day_of_week: int | None = None) -> Date: - """ - Modify to the last occurrence of a given day of the week - in the current month. If no day_of_week is provided, - modify to the last day of the month. Use the supplied consts - to indicate the desired day_of_week, ex. pendulum.MONDAY. - - :param day_of_week: The day of week to set to. - """ - dt = self - - if day_of_week is None: - return dt.set(day=self.days_in_month) - - month = calendar.monthcalendar(dt.year, dt.month) - - calendar_day = (day_of_week - 1) % 7 - - if month[-1][calendar_day] > 0: - day_of_month = month[-1][calendar_day] - else: - day_of_month = month[-2][calendar_day] - - return dt.set(day=day_of_month) - - def _nth_of_month(self, nth: int, day_of_week: int) -> Date | None: - """ - Modify to the given occurrence of a given day of the week - in the current month. If the calculated occurrence is outside, - the scope of the current month, then return False and no - modifications are made. Use the supplied consts - to indicate the desired day_of_week, ex. pendulum.MONDAY. - """ - if nth == 1: - return self.first_of("month", day_of_week) - - dt = self.first_of("month") - check = dt.format("YYYY-MM") - for _ in range(nth - (1 if dt.day_of_week == day_of_week else 0)): - dt = dt.next(day_of_week) - - if dt.format("YYYY-MM") == check: - return self.set(day=dt.day) - - return None - - def _first_of_quarter(self, day_of_week: int | None = None) -> Date: - """ - Modify to the first occurrence of a given day of the week - in the current quarter. If no day_of_week is provided, - modify to the first day of the quarter. Use the supplied consts - to indicate the desired day_of_week, ex. pendulum.MONDAY. - """ - return self.set(self.year, self.quarter * 3 - 2, 1).first_of( - "month", day_of_week - ) - - def _last_of_quarter(self, day_of_week: int | None = None) -> Date: - """ - Modify to the last occurrence of a given day of the week - in the current quarter. If no day_of_week is provided, - modify to the last day of the quarter. Use the supplied consts - to indicate the desired day_of_week, ex. pendulum.MONDAY. - """ - return self.set(self.year, self.quarter * 3, 1).last_of("month", day_of_week) - - def _nth_of_quarter(self, nth: int, day_of_week: int) -> Date | None: - """ - Modify to the given occurrence of a given day of the week - in the current quarter. If the calculated occurrence is outside, - the scope of the current quarter, then return False and no - modifications are made. Use the supplied consts - to indicate the desired day_of_week, ex. pendulum.MONDAY. - """ - if nth == 1: - return self.first_of("quarter", day_of_week) - - dt = self.replace(self.year, self.quarter * 3, 1) - last_month = dt.month - year = dt.year - dt = dt.first_of("quarter") - for _ in range(nth - (1 if dt.day_of_week == day_of_week else 0)): - dt = dt.next(day_of_week) - - if last_month < dt.month or year != dt.year: - return None - - return self.set(self.year, dt.month, dt.day) - - def _first_of_year(self, day_of_week: int | None = None) -> Date: - """ - Modify to the first occurrence of a given day of the week - in the current year. If no day_of_week is provided, - modify to the first day of the year. Use the supplied consts - to indicate the desired day_of_week, ex. pendulum.MONDAY. - """ - return self.set(month=1).first_of("month", day_of_week) - - def _last_of_year(self, day_of_week: int | None = None) -> Date: - """ - Modify to the last occurrence of a given day of the week - in the current year. If no day_of_week is provided, - modify to the last day of the year. Use the supplied consts - to indicate the desired day_of_week, ex. pendulum.MONDAY. - """ - return self.set(month=MONTHS_PER_YEAR).last_of("month", day_of_week) - - def _nth_of_year(self, nth: int, day_of_week: int) -> Date | None: - """ - Modify to the given occurrence of a given day of the week - in the current year. If the calculated occurrence is outside, - the scope of the current year, then return False and no - modifications are made. Use the supplied consts - to indicate the desired day_of_week, ex. pendulum.MONDAY. - """ - if nth == 1: - return self.first_of("year", day_of_week) - - dt = self.first_of("year") - year = dt.year - for _ in range(nth - (1 if dt.day_of_week == day_of_week else 0)): - dt = dt.next(day_of_week) - - if year != dt.year: - return None - - return self.set(self.year, dt.month, dt.day) - - def average(self, dt: date | None = None) -> Date: - """ - Modify the current instance to the average - of a given instance (default now) and the current instance. - """ - if dt is None: - dt = Date.today() - - return self.add(days=int(self.diff(dt, False).in_days() / 2)) - - # Native methods override - - @classmethod - def today(cls) -> Date: - dt = date.today() - - return cls(dt.year, dt.month, dt.day) - - @classmethod - def fromtimestamp(cls, t: float) -> Date: - dt = super().fromtimestamp(t) - - return cls(dt.year, dt.month, dt.day) - - @classmethod - def fromordinal(cls, n: int) -> Date: - dt = super().fromordinal(n) - - return cls(dt.year, dt.month, dt.day) - - def replace( - self, - year: int | None = None, - month: int | None = None, - day: int | None = None, - ) -> Date: - year = year if year is not None else self.year - month = month if month is not None else self.month - day = day if day is not None else self.day - - return self.__class__(year, month, day) diff --git a/pendulum/datetime.py b/pendulum/datetime.py deleted file mode 100644 index 52ad3cc..0000000 --- a/pendulum/datetime.py +++ /dev/null @@ -1,1381 +0,0 @@ -from __future__ import annotations - -import calendar -import datetime - -from typing import TYPE_CHECKING -from typing import Any -from typing import Callable -from typing import Optional -from typing import cast -from typing import overload - -import pendulum - -from pendulum.constants import ATOM -from pendulum.constants import COOKIE -from pendulum.constants import MINUTES_PER_HOUR -from pendulum.constants import MONTHS_PER_YEAR -from pendulum.constants import RFC822 -from pendulum.constants import RFC850 -from pendulum.constants import RFC1036 -from pendulum.constants import RFC1123 -from pendulum.constants import RFC2822 -from pendulum.constants import RSS -from pendulum.constants import SATURDAY -from pendulum.constants import SECONDS_PER_DAY -from pendulum.constants import SECONDS_PER_MINUTE -from pendulum.constants import SUNDAY -from pendulum.constants import W3C -from pendulum.constants import YEARS_PER_CENTURY -from pendulum.constants import YEARS_PER_DECADE -from pendulum.date import Date -from pendulum.exceptions import PendulumException -from pendulum.helpers import add_duration -from pendulum.interval import Interval -from pendulum.time import Time -from pendulum.tz import UTC -from pendulum.tz import local_timezone -from pendulum.tz.timezone import FixedTimezone -from pendulum.tz.timezone import Timezone -from pendulum.utils._compat import PY38 - -if TYPE_CHECKING: - from typing import Literal - - -class DateTime(datetime.datetime, Date): - EPOCH: DateTime - - # Formats - - _FORMATS: dict[str, str | Callable[[datetime.datetime], str]] = { - "atom": ATOM, - "cookie": COOKIE, - "iso8601": lambda dt: dt.isoformat(), - "rfc822": RFC822, - "rfc850": RFC850, - "rfc1036": RFC1036, - "rfc1123": RFC1123, - "rfc2822": RFC2822, - "rfc3339": lambda dt: dt.isoformat(), - "rss": RSS, - "w3c": W3C, - } - - _MODIFIERS_VALID_UNITS: list[str] = [ - "second", - "minute", - "hour", - "day", - "week", - "month", - "year", - "decade", - "century", - ] - - _EPOCH: datetime.datetime = datetime.datetime(1970, 1, 1, tzinfo=UTC) - - @classmethod - def create( - cls, - year: int, - month: int, - day: int, - hour: int = 0, - minute: int = 0, - second: int = 0, - microsecond: int = 0, - tz: str | float | Timezone | FixedTimezone | None | datetime.tzinfo = UTC, - fold: int = 1, - raise_on_unknown_times: bool = False, - ) -> DateTime: - """ - Creates a new DateTime instance from a specific date and time. - """ - if tz is not None: - tz = pendulum._safe_timezone(tz) - - dt = datetime.datetime( - year, month, day, hour, minute, second, microsecond, fold=fold - ) - - if tz is not None: - dt = tz.convert(dt, raise_on_unknown_times=raise_on_unknown_times) - - return cls( - dt.year, - dt.month, - dt.day, - dt.hour, - dt.minute, - dt.second, - dt.microsecond, - tzinfo=dt.tzinfo, - fold=dt.fold, - ) - - @overload - @classmethod - def now(cls, tz: datetime.tzinfo | None = None) -> DateTime: - ... - - @overload - @classmethod - def now(cls, tz: str | Timezone | FixedTimezone | None = None) -> DateTime: - ... - - @classmethod - def now( - cls, tz: str | Timezone | FixedTimezone | datetime.tzinfo | None = None - ) -> DateTime: - """ - Get a DateTime instance for the current date and time. - """ - if tz is None or tz == "local": - dt = datetime.datetime.now(local_timezone()) - elif tz is UTC or tz == "UTC": - dt = datetime.datetime.now(UTC) - else: - dt = datetime.datetime.now(UTC) - tz = pendulum._safe_timezone(tz) - dt = dt.astimezone(tz) - - return cls( - dt.year, - dt.month, - dt.day, - dt.hour, - dt.minute, - dt.second, - dt.microsecond, - tzinfo=dt.tzinfo, - fold=dt.fold, - ) - - @classmethod - def utcnow(cls) -> DateTime: - """ - Get a DateTime instance for the current date and time in UTC. - """ - return cls.now(UTC) - - @classmethod - def today(cls) -> DateTime: - return cls.now() - - @classmethod - def strptime(cls, time: str, fmt: str) -> DateTime: - return pendulum.instance(datetime.datetime.strptime(time, fmt)) - - # Getters/Setters - - def set( - self, - year: int | None = None, - month: int | None = None, - day: int | None = None, - hour: int | None = None, - minute: int | None = None, - second: int | None = None, - microsecond: int | None = None, - tz: str | float | Timezone | FixedTimezone | datetime.tzinfo | None = None, - ) -> DateTime: - if year is None: - year = self.year - if month is None: - month = self.month - if day is None: - day = self.day - if hour is None: - hour = self.hour - if minute is None: - minute = self.minute - if second is None: - second = self.second - if microsecond is None: - microsecond = self.microsecond - if tz is None: - tz = self.tz - - return DateTime.create( - year, month, day, hour, minute, second, microsecond, tz=tz - ) - - @property - def float_timestamp(self) -> float: - return self.timestamp() - - @property - def int_timestamp(self) -> int: - # Workaround needed to avoid inaccuracy - # for far into the future datetimes - dt = datetime.datetime( - self.year, - self.month, - self.day, - self.hour, - self.minute, - self.second, - self.microsecond, - tzinfo=self.tzinfo, - fold=self.fold, - ) - - delta = dt - self._EPOCH - - return delta.days * SECONDS_PER_DAY + delta.seconds - - @property - def offset(self) -> int | None: - return self.get_offset() - - @property - def offset_hours(self) -> float | None: - offset = self.get_offset() - - if offset is None: - return None - - return offset / SECONDS_PER_MINUTE / MINUTES_PER_HOUR - - @property - def timezone(self) -> Timezone | FixedTimezone | None: - if not isinstance(self.tzinfo, (Timezone, FixedTimezone)): - return None - - return self.tzinfo - - @property - def tz(self) -> Timezone | FixedTimezone | None: - return self.timezone - - @property - def timezone_name(self) -> str | None: - tz = self.timezone - - if tz is None: - return None - - return tz.name - - @property - def age(self) -> int: - return self.date().diff(self.now(self.tz).date(), abs=False).in_years() - - def is_local(self) -> bool: - return self.offset == self.in_timezone(pendulum.local_timezone()).offset - - def is_utc(self) -> bool: - return self.offset == 0 - - def is_dst(self) -> bool: - return self.dst() != datetime.timedelta() - - def get_offset(self) -> int | None: - utcoffset = self.utcoffset() - if utcoffset is None: - return None - - return int(utcoffset.total_seconds()) - - def date(self) -> Date: - return Date(self.year, self.month, self.day) - - def time(self) -> Time: - return Time(self.hour, self.minute, self.second, self.microsecond) - - def naive(self) -> DateTime: - """ - Return the DateTime without timezone information. - """ - return self.__class__( - self.year, - self.month, - self.day, - self.hour, - self.minute, - self.second, - self.microsecond, - ) - - def on(self, year: int, month: int, day: int) -> DateTime: - """ - Returns a new instance with the current date set to a different date. - """ - return self.set(year=int(year), month=int(month), day=int(day)) - - def at( - self, hour: int, minute: int = 0, second: int = 0, microsecond: int = 0 - ) -> DateTime: - """ - Returns a new instance with the current time to a different time. - """ - return self.set( - hour=hour, minute=minute, second=second, microsecond=microsecond - ) - - def in_timezone(self, tz: str | Timezone | FixedTimezone) -> DateTime: - """ - Set the instance's timezone from a string or object. - """ - tz = pendulum._safe_timezone(tz) - - dt = self - if not self.timezone: - dt = dt.replace(fold=1) - - return cast(DateTime, tz.convert(dt)) - - def in_tz(self, tz: str | Timezone | FixedTimezone) -> DateTime: - """ - Set the instance's timezone from a string or object. - """ - return self.in_timezone(tz) - - # STRING FORMATTING - - def to_time_string(self) -> str: - """ - Format the instance as time. - """ - return self.format("HH:mm:ss") - - def to_datetime_string(self) -> str: - """ - Format the instance as date and time. - """ - return self.format("YYYY-MM-DD HH:mm:ss") - - def to_day_datetime_string(self) -> str: - """ - Format the instance as day, date and time (in english). - """ - return self.format("ddd, MMM D, YYYY h:mm A", locale="en") - - def to_atom_string(self) -> str: - """ - Format the instance as ATOM. - """ - return self._to_string("atom") - - def to_cookie_string(self) -> str: - """ - Format the instance as COOKIE. - """ - return self._to_string("cookie", locale="en") - - def to_iso8601_string(self) -> str: - """ - Format the instance as ISO 8601. - """ - string = self._to_string("iso8601") - - if self.tz and self.tz.name == "UTC": - string = string.replace("+00:00", "Z") - - return string - - def to_rfc822_string(self) -> str: - """ - Format the instance as RFC 822. - """ - return self._to_string("rfc822") - - def to_rfc850_string(self) -> str: - """ - Format the instance as RFC 850. - """ - return self._to_string("rfc850") - - def to_rfc1036_string(self) -> str: - """ - Format the instance as RFC 1036. - """ - return self._to_string("rfc1036") - - def to_rfc1123_string(self) -> str: - """ - Format the instance as RFC 1123. - """ - return self._to_string("rfc1123") - - def to_rfc2822_string(self) -> str: - """ - Format the instance as RFC 2822. - """ - return self._to_string("rfc2822") - - def to_rfc3339_string(self) -> str: - """ - Format the instance as RFC 3339. - """ - return self._to_string("rfc3339") - - def to_rss_string(self) -> str: - """ - Format the instance as RSS. - """ - return self._to_string("rss") - - def to_w3c_string(self) -> str: - """ - Format the instance as W3C. - """ - return self._to_string("w3c") - - def _to_string(self, fmt: str, locale: str | None = None) -> str: - """ - Format the instance to a common string format. - """ - if fmt not in self._FORMATS: - raise ValueError(f"Format [{fmt}] is not supported") - - fmt_value = self._FORMATS[fmt] - if callable(fmt_value): - return fmt_value(self) - - return self.format(fmt_value, locale=locale) - - def __str__(self) -> str: - return self.isoformat("T") - - def __repr__(self) -> str: - us = "" - if self.microsecond: - us = f", {self.microsecond}" - - repr_ = "{klass}(" "{year}, {month}, {day}, " "{hour}, {minute}, {second}{us}" - - if self.tzinfo is not None: - repr_ += ", tzinfo={tzinfo}" - - repr_ += ")" - - return repr_.format( - klass=self.__class__.__name__, - year=self.year, - month=self.month, - day=self.day, - hour=self.hour, - minute=self.minute, - second=self.second, - us=us, - tzinfo=repr(self.tzinfo), - ) - - # Comparisons - def closest(self, *dts: datetime.datetime) -> DateTime: # type: ignore[override] - """ - Get the farthest date from the instance. - """ - pdts = [pendulum.instance(x) for x in dts] - - return min((abs(self - dt), dt) for dt in pdts)[1] - - def farthest(self, *dts: datetime.datetime) -> DateTime: # type: ignore[override] - """ - Get the farthest date from the instance. - """ - pdts = [pendulum.instance(x) for x in dts] - - return max((abs(self - dt), dt) for dt in pdts)[1] - - def is_future(self) -> bool: - """ - Determines if the instance is in the future, ie. greater than now. - """ - return self > self.now(self.timezone) - - def is_past(self) -> bool: - """ - Determines if the instance is in the past, ie. less than now. - """ - return self < self.now(self.timezone) - - def is_long_year(self) -> bool: - """ - Determines if the instance is a long year - - See link `https://en.wikipedia.org/wiki/ISO_8601#Week_dates`_ - """ - return ( - DateTime.create(self.year, 12, 28, 0, 0, 0, tz=self.tz).isocalendar()[1] - == 53 - ) - - def is_same_day(self, dt: datetime.datetime) -> bool: # type: ignore[override] - """ - Checks if the passed in date is the same day - as the instance current day. - """ - dt = pendulum.instance(dt) - - return self.to_date_string() == dt.to_date_string() - - def is_anniversary( # type: ignore[override] - self, dt: datetime.datetime | None = None - ) -> bool: - """ - Check if its the anniversary. - Compares the date/month values of the two dates. - """ - if dt is None: - dt = self.now(self.tz) - - instance = pendulum.instance(dt) - - return (self.month, self.day) == (instance.month, instance.day) - - # ADDITIONS AND SUBSTRACTIONS - - def add( - self, - years: int = 0, - months: int = 0, - weeks: int = 0, - days: int = 0, - hours: int = 0, - minutes: int = 0, - seconds: float = 0, - microseconds: int = 0, - ) -> DateTime: - """ - Add a duration to the instance. - - If we're adding units of variable length (i.e., years, months), - move forward from current time, otherwise move forward from utc, for accuracy - when moving across DST boundaries. - """ - units_of_variable_length = any([years, months, weeks, days]) - - current_dt = datetime.datetime( - self.year, - self.month, - self.day, - self.hour, - self.minute, - self.second, - self.microsecond, - ) - if not units_of_variable_length: - offset = self.utcoffset() - if offset: - current_dt = current_dt - offset - - dt = add_duration( - current_dt, - years=years, - months=months, - weeks=weeks, - days=days, - hours=hours, - minutes=minutes, - seconds=seconds, - microseconds=microseconds, - ) - - if units_of_variable_length or self.tz is None: - return DateTime.create( - dt.year, - dt.month, - dt.day, - dt.hour, - dt.minute, - dt.second, - dt.microsecond, - tz=self.tz, - ) - - dt = datetime.datetime( - dt.year, - dt.month, - dt.day, - dt.hour, - dt.minute, - dt.second, - dt.microsecond, - tzinfo=UTC, - ) - - dt = self.tz.convert(dt) - - return self.__class__( - dt.year, - dt.month, - dt.day, - dt.hour, - dt.minute, - dt.second, - dt.microsecond, - tzinfo=self.tz, - fold=dt.fold, - ) - - def subtract( - self, - years: int = 0, - months: int = 0, - weeks: int = 0, - days: int = 0, - hours: int = 0, - minutes: int = 0, - seconds: float = 0, - microseconds: int = 0, - ) -> DateTime: - """ - Remove duration from the instance. - """ - return self.add( - years=-years, - months=-months, - weeks=-weeks, - days=-days, - hours=-hours, - minutes=-minutes, - seconds=-seconds, - microseconds=-microseconds, - ) - - # Adding a final underscore to the method name - # to avoid errors for PyPy which already defines - # a _add_timedelta method - def _add_timedelta_(self, delta: datetime.timedelta) -> DateTime: - """ - Add timedelta duration to the instance. - """ - if isinstance(delta, pendulum.Interval): - return self.add( - years=delta.years, - months=delta.months, - weeks=delta.weeks, - days=delta.remaining_days, - hours=delta.hours, - minutes=delta.minutes, - seconds=delta.remaining_seconds, - microseconds=delta.microseconds, - ) - elif isinstance(delta, pendulum.Duration): - return self.add( - years=delta.years, months=delta.months, seconds=delta._total - ) - - return self.add(seconds=delta.total_seconds()) - - def _subtract_timedelta(self, delta: datetime.timedelta) -> DateTime: - """ - Remove timedelta duration from the instance. - """ - if isinstance(delta, pendulum.Duration): - return self.subtract( - years=delta.years, months=delta.months, seconds=delta._total - ) - - return self.subtract(seconds=delta.total_seconds()) - - # DIFFERENCES - - def diff( # type: ignore[override] - self, dt: datetime.datetime | None = None, abs: bool = True - ) -> Interval: - """ - Returns the difference between two DateTime objects represented as an Interval. - """ - if dt is None: - dt = self.now(self.tz) - - return Interval(self, dt, absolute=abs) - - def diff_for_humans( # type: ignore[override] - self, - other: DateTime | None = None, - absolute: bool = False, - locale: str | None = None, - ) -> str: - """ - Get the difference in a human readable format in the current locale. - - When comparing a value in the past to default now: - 1 day ago - 5 months ago - - When comparing a value in the future to default now: - 1 day from now - 5 months from now - - When comparing a value in the past to another value: - 1 day before - 5 months before - - When comparing a value in the future to another value: - 1 day after - 5 months after - """ - is_now = other is None - - if is_now: - other = self.now() - - diff = self.diff(other) - - return pendulum.format_diff(diff, is_now, absolute, locale) - - # Modifiers - def start_of(self, unit: str) -> DateTime: - """ - Returns a copy of the instance with the time reset - with the following rules: - - * second: microsecond set to 0 - * minute: second and microsecond set to 0 - * hour: minute, second and microsecond set to 0 - * day: time to 00:00:00 - * week: date to first day of the week and time to 00:00:00 - * month: date to first day of the month and time to 00:00:00 - * year: date to first day of the year and time to 00:00:00 - * decade: date to first day of the decade and time to 00:00:00 - * century: date to first day of century and time to 00:00:00 - """ - if unit not in self._MODIFIERS_VALID_UNITS: - raise ValueError(f'Invalid unit "{unit}" for start_of()') - - return cast(DateTime, getattr(self, f"_start_of_{unit}")()) - - def end_of(self, unit: str) -> DateTime: - """ - Returns a copy of the instance with the time reset - with the following rules: - - * second: microsecond set to 999999 - * minute: second set to 59 and microsecond set to 999999 - * hour: minute and second set to 59 and microsecond set to 999999 - * day: time to 23:59:59.999999 - * week: date to last day of the week and time to 23:59:59.999999 - * month: date to last day of the month and time to 23:59:59.999999 - * year: date to last day of the year and time to 23:59:59.999999 - * decade: date to last day of the decade and time to 23:59:59.999999 - * century: date to last day of century and time to 23:59:59.999999 - """ - if unit not in self._MODIFIERS_VALID_UNITS: - raise ValueError(f'Invalid unit "{unit}" for end_of()') - - return cast(DateTime, getattr(self, f"_end_of_{unit}")()) - - def _start_of_second(self) -> DateTime: - """ - Reset microseconds to 0. - """ - return self.set(microsecond=0) - - def _end_of_second(self) -> DateTime: - """ - Set microseconds to 999999. - """ - return self.set(microsecond=999999) - - def _start_of_minute(self) -> DateTime: - """ - Reset seconds and microseconds to 0. - """ - return self.set(second=0, microsecond=0) - - def _end_of_minute(self) -> DateTime: - """ - Set seconds to 59 and microseconds to 999999. - """ - return self.set(second=59, microsecond=999999) - - def _start_of_hour(self) -> DateTime: - """ - Reset minutes, seconds and microseconds to 0. - """ - return self.set(minute=0, second=0, microsecond=0) - - def _end_of_hour(self) -> DateTime: - """ - Set minutes and seconds to 59 and microseconds to 999999. - """ - return self.set(minute=59, second=59, microsecond=999999) - - def _start_of_day(self) -> DateTime: - """ - Reset the time to 00:00:00. - """ - return self.at(0, 0, 0, 0) - - def _end_of_day(self) -> DateTime: - """ - Reset the time to 23:59:59.999999. - """ - return self.at(23, 59, 59, 999999) - - def _start_of_month(self) -> DateTime: - """ - Reset the date to the first day of the month and the time to 00:00:00. - """ - return self.set(self.year, self.month, 1, 0, 0, 0, 0) - - def _end_of_month(self) -> DateTime: - """ - Reset the date to the last day of the month - and the time to 23:59:59.999999. - """ - return self.set(self.year, self.month, self.days_in_month, 23, 59, 59, 999999) - - def _start_of_year(self) -> DateTime: - """ - Reset the date to the first day of the year and the time to 00:00:00. - """ - return self.set(self.year, 1, 1, 0, 0, 0, 0) - - def _end_of_year(self) -> DateTime: - """ - Reset the date to the last day of the year - and the time to 23:59:59.999999. - """ - return self.set(self.year, 12, 31, 23, 59, 59, 999999) - - def _start_of_decade(self) -> DateTime: - """ - Reset the date to the first day of the decade - and the time to 00:00:00. - """ - year = self.year - self.year % YEARS_PER_DECADE - return self.set(year, 1, 1, 0, 0, 0, 0) - - def _end_of_decade(self) -> DateTime: - """ - Reset the date to the last day of the decade - and the time to 23:59:59.999999. - """ - year = self.year - self.year % YEARS_PER_DECADE + YEARS_PER_DECADE - 1 - - return self.set(year, 12, 31, 23, 59, 59, 999999) - - def _start_of_century(self) -> DateTime: - """ - Reset the date to the first day of the century - and the time to 00:00:00. - """ - year = self.year - 1 - (self.year - 1) % YEARS_PER_CENTURY + 1 - - return self.set(year, 1, 1, 0, 0, 0, 0) - - def _end_of_century(self) -> DateTime: - """ - Reset the date to the last day of the century - and the time to 23:59:59.999999. - """ - year = self.year - 1 - (self.year - 1) % YEARS_PER_CENTURY + YEARS_PER_CENTURY - - return self.set(year, 12, 31, 23, 59, 59, 999999) - - def _start_of_week(self) -> DateTime: - """ - Reset the date to the first day of the week - and the time to 00:00:00. - """ - dt = self - - if self.day_of_week != pendulum._WEEK_STARTS_AT: - dt = self.previous(pendulum._WEEK_STARTS_AT) - - return dt.start_of("day") - - def _end_of_week(self) -> DateTime: - """ - Reset the date to the last day of the week - and the time to 23:59:59. - """ - dt = self - - if self.day_of_week != pendulum._WEEK_ENDS_AT: - dt = self.next(pendulum._WEEK_ENDS_AT) - - return dt.end_of("day") - - def next(self, day_of_week: int | None = None, keep_time: bool = False) -> DateTime: - """ - Modify to the next occurrence of a given day of the week. - If no day_of_week is provided, modify to the next occurrence - of the current day of the week. Use the supplied consts - to indicate the desired day_of_week, ex. DateTime.MONDAY. - """ - if day_of_week is None: - day_of_week = self.day_of_week - - if day_of_week < SUNDAY or day_of_week > SATURDAY: - raise ValueError("Invalid day of week") - - if keep_time: - dt = self - else: - dt = self.start_of("day") - - dt = dt.add(days=1) - while dt.day_of_week != day_of_week: - dt = dt.add(days=1) - - return dt - - def previous( - self, day_of_week: int | None = None, keep_time: bool = False - ) -> DateTime: - """ - Modify to the previous occurrence of a given day of the week. - If no day_of_week is provided, modify to the previous occurrence - of the current day of the week. Use the supplied consts - to indicate the desired day_of_week, ex. DateTime.MONDAY. - """ - if day_of_week is None: - day_of_week = self.day_of_week - - if day_of_week < SUNDAY or day_of_week > SATURDAY: - raise ValueError("Invalid day of week") - - if keep_time: - dt = self - else: - dt = self.start_of("day") - - dt = dt.subtract(days=1) - while dt.day_of_week != day_of_week: - dt = dt.subtract(days=1) - - return dt - - def first_of(self, unit: str, day_of_week: int | None = None) -> DateTime: - """ - Returns an instance set to the first occurrence - of a given day of the week in the current unit. - If no day_of_week is provided, modify to the first day of the unit. - Use the supplied consts to indicate the desired day_of_week, ex. DateTime.MONDAY. - - Supported units are month, quarter and year. - """ - if unit not in ["month", "quarter", "year"]: - raise ValueError(f'Invalid unit "{unit}" for first_of()') - - return cast(DateTime, getattr(self, f"_first_of_{unit}")(day_of_week)) - - def last_of(self, unit: str, day_of_week: int | None = None) -> DateTime: - """ - Returns an instance set to the last occurrence - of a given day of the week in the current unit. - If no day_of_week is provided, modify to the last day of the unit. - Use the supplied consts to indicate the desired day_of_week, ex. DateTime.MONDAY. - - Supported units are month, quarter and year. - """ - if unit not in ["month", "quarter", "year"]: - raise ValueError(f'Invalid unit "{unit}" for first_of()') - - return cast(DateTime, getattr(self, f"_last_of_{unit}")(day_of_week)) - - def nth_of(self, unit: str, nth: int, day_of_week: int) -> DateTime: - """ - Returns a new instance set to the given occurrence - of a given day of the week in the current unit. - If the calculated occurrence is outside the scope of the current unit, - then raise an error. Use the supplied consts - to indicate the desired day_of_week, ex. DateTime.MONDAY. - - Supported units are month, quarter and year. - """ - if unit not in ["month", "quarter", "year"]: - raise ValueError(f'Invalid unit "{unit}" for first_of()') - - dt = cast( - Optional[DateTime], getattr(self, f"_nth_of_{unit}")(nth, day_of_week) - ) - if not dt: - raise PendulumException( - f"Unable to find occurence {nth}" - f" of {self._days[day_of_week]} in {unit}" - ) - - return dt - - def _first_of_month(self, day_of_week: int | None = None) -> DateTime: - """ - Modify to the first occurrence of a given day of the week - in the current month. If no day_of_week is provided, - modify to the first day of the month. Use the supplied consts - to indicate the desired day_of_week, ex. DateTime.MONDAY. - """ - dt = self.start_of("day") - - if day_of_week is None: - return dt.set(day=1) - - month = calendar.monthcalendar(dt.year, dt.month) - - calendar_day = (day_of_week - 1) % 7 - - if month[0][calendar_day] > 0: - day_of_month = month[0][calendar_day] - else: - day_of_month = month[1][calendar_day] - - return dt.set(day=day_of_month) - - def _last_of_month(self, day_of_week: int | None = None) -> DateTime: - """ - Modify to the last occurrence of a given day of the week - in the current month. If no day_of_week is provided, - modify to the last day of the month. Use the supplied consts - to indicate the desired day_of_week, ex. DateTime.MONDAY. - """ - dt = self.start_of("day") - - if day_of_week is None: - return dt.set(day=self.days_in_month) - - month = calendar.monthcalendar(dt.year, dt.month) - - calendar_day = (day_of_week - 1) % 7 - - if month[-1][calendar_day] > 0: - day_of_month = month[-1][calendar_day] - else: - day_of_month = month[-2][calendar_day] - - return dt.set(day=day_of_month) - - def _nth_of_month( - self, nth: int, day_of_week: int | None = None - ) -> DateTime | None: - """ - Modify to the given occurrence of a given day of the week - in the current month. If the calculated occurrence is outside, - the scope of the current month, then return False and no - modifications are made. Use the supplied consts - to indicate the desired day_of_week, ex. DateTime.MONDAY. - """ - if nth == 1: - return self.first_of("month", day_of_week) - - dt = self.first_of("month") - check = dt.format("%Y-%M") - for _ in range(nth - (1 if dt.day_of_week == day_of_week else 0)): - dt = dt.next(day_of_week) - - if dt.format("%Y-%M") == check: - return self.set(day=dt.day).start_of("day") - - return None - - def _first_of_quarter(self, day_of_week: int | None = None) -> DateTime: - """ - Modify to the first occurrence of a given day of the week - in the current quarter. If no day_of_week is provided, - modify to the first day of the quarter. Use the supplied consts - to indicate the desired day_of_week, ex. DateTime.MONDAY. - """ - return self.on(self.year, self.quarter * 3 - 2, 1).first_of( - "month", day_of_week - ) - - def _last_of_quarter(self, day_of_week: int | None = None) -> DateTime: - """ - Modify to the last occurrence of a given day of the week - in the current quarter. If no day_of_week is provided, - modify to the last day of the quarter. Use the supplied consts - to indicate the desired day_of_week, ex. DateTime.MONDAY. - """ - return self.on(self.year, self.quarter * 3, 1).last_of("month", day_of_week) - - def _nth_of_quarter( - self, nth: int, day_of_week: int | None = None - ) -> DateTime | None: - """ - Modify to the given occurrence of a given day of the week - in the current quarter. If the calculated occurrence is outside, - the scope of the current quarter, then return False and no - modifications are made. Use the supplied consts - to indicate the desired day_of_week, ex. DateTime.MONDAY. - """ - if nth == 1: - return self.first_of("quarter", day_of_week) - - dt = self.set(day=1, month=self.quarter * 3) - last_month = dt.month - year = dt.year - dt = dt.first_of("quarter") - for _ in range(nth - (1 if dt.day_of_week == day_of_week else 0)): - dt = dt.next(day_of_week) - - if last_month < dt.month or year != dt.year: - return None - - return self.on(self.year, dt.month, dt.day).start_of("day") - - def _first_of_year(self, day_of_week: int | None = None) -> DateTime: - """ - Modify to the first occurrence of a given day of the week - in the current year. If no day_of_week is provided, - modify to the first day of the year. Use the supplied consts - to indicate the desired day_of_week, ex. DateTime.MONDAY. - """ - return self.set(month=1).first_of("month", day_of_week) - - def _last_of_year(self, day_of_week: int | None = None) -> DateTime: - """ - Modify to the last occurrence of a given day of the week - in the current year. If no day_of_week is provided, - modify to the last day of the year. Use the supplied consts - to indicate the desired day_of_week, ex. DateTime.MONDAY. - """ - return self.set(month=MONTHS_PER_YEAR).last_of("month", day_of_week) - - def _nth_of_year(self, nth: int, day_of_week: int | None = None) -> DateTime | None: - """ - Modify to the given occurrence of a given day of the week - in the current year. If the calculated occurrence is outside, - the scope of the current year, then return False and no - modifications are made. Use the supplied consts - to indicate the desired day_of_week, ex. DateTime.MONDAY. - """ - if nth == 1: - return self.first_of("year", day_of_week) - - dt = self.first_of("year") - year = dt.year - for _ in range(nth - (1 if dt.day_of_week == day_of_week else 0)): - dt = dt.next(day_of_week) - - if year != dt.year: - return None - - return self.on(self.year, dt.month, dt.day).start_of("day") - - def average( # type: ignore[override] - self, dt: datetime.datetime | None = None - ) -> DateTime: - """ - Modify the current instance to the average - of a given instance (default now) and the current instance. - """ - if dt is None: - dt = self.now(self.tz) - - diff = self.diff(dt, False) - return self.add( - microseconds=(diff.in_seconds() * 1000000 + diff.microseconds) // 2 - ) - - @overload # type: ignore[override] - def __sub__(self, other: datetime.timedelta) -> DateTime: - ... - - @overload - def __sub__(self, other: DateTime) -> Interval: - ... - - def __sub__( - self, other: datetime.datetime | datetime.timedelta - ) -> DateTime | Interval: - if isinstance(other, datetime.timedelta): - return self._subtract_timedelta(other) - - if not isinstance(other, datetime.datetime): - return NotImplemented - - if not isinstance(other, self.__class__): - if other.tzinfo is None: - other = pendulum.naive( - other.year, - other.month, - other.day, - other.hour, - other.minute, - other.second, - other.microsecond, - ) - else: - other = pendulum.instance(other) - - return other.diff(self, False) - - def __rsub__(self, other: datetime.datetime) -> Interval: - if not isinstance(other, datetime.datetime): - return NotImplemented - - if not isinstance(other, self.__class__): - if other.tzinfo is None: - other = pendulum.naive( - other.year, - other.month, - other.day, - other.hour, - other.minute, - other.second, - other.microsecond, - ) - else: - other = pendulum.instance(other) - - return self.diff(other, False) - - def __add__(self, other: datetime.timedelta) -> DateTime: - if not isinstance(other, datetime.timedelta): - return NotImplemented - - if PY38: - # This is a workaround for Python 3.8+ - # since calling astimezone() will call this method - # instead of the base datetime class one. - import inspect - - caller = inspect.stack()[1][3] - if caller == "astimezone": - return cast(DateTime, super().__add__(other)) - - return self._add_timedelta_(other) - - def __radd__(self, other: datetime.timedelta) -> DateTime: - return self.__add__(other) - - # Native methods override - - @classmethod - def fromtimestamp(cls, t: float, tz: datetime.tzinfo | None = None) -> DateTime: - tzinfo = pendulum._safe_timezone(tz) - - return pendulum.instance( - datetime.datetime.fromtimestamp(t, tz=tzinfo), tz=tzinfo - ) - - @classmethod - def utcfromtimestamp(cls, t: float) -> DateTime: - return pendulum.instance(datetime.datetime.utcfromtimestamp(t), tz=None) - - @classmethod - def fromordinal(cls, n: int) -> DateTime: - return pendulum.instance(datetime.datetime.fromordinal(n), tz=None) - - @classmethod - def combine( - cls, - date: datetime.date, - time: datetime.time, - tzinfo: datetime.tzinfo | None = None, - ) -> DateTime: - return pendulum.instance(datetime.datetime.combine(date, time), tz=tzinfo) - - def astimezone(self, tz: datetime.tzinfo | None = None) -> DateTime: - dt = super().astimezone(tz) - - return self.__class__( - dt.year, - dt.month, - dt.day, - dt.hour, - dt.minute, - dt.second, - dt.microsecond, - fold=dt.fold, - tzinfo=dt.tzinfo, - ) - - def replace( - self, - year: int | None = None, - month: int | None = None, - day: int | None = None, - hour: int | None = None, - minute: int | None = None, - second: int | None = None, - microsecond: int | None = None, - tzinfo: bool | datetime.tzinfo | Literal[True] | None = True, - fold: int | None = None, - ) -> DateTime: - if year is None: - year = self.year - if month is None: - month = self.month - if day is None: - day = self.day - if hour is None: - hour = self.hour - if minute is None: - minute = self.minute - if second is None: - second = self.second - if microsecond is None: - microsecond = self.microsecond - if tzinfo is True: - tzinfo = self.tzinfo - if fold is None: - fold = self.fold - - if tzinfo is not None: - tzinfo = pendulum._safe_timezone(tzinfo) - - return DateTime.create( - year, - month, - day, - hour, - minute, - second, - microsecond, - tz=tzinfo, - fold=fold, - ) - - def __getnewargs__(self) -> tuple[DateTime]: - return (self,) - - def _getstate( - self, protocol: int = 3 - ) -> tuple[int, int, int, int, int, int, int, datetime.tzinfo | None]: - return ( - self.year, - self.month, - self.day, - self.hour, - self.minute, - self.second, - self.microsecond, - self.tzinfo, - ) - - def __reduce__( - self, - ) -> tuple[ - type[DateTime], tuple[int, int, int, int, int, int, int, datetime.tzinfo | None] - ]: - return self.__reduce_ex__(2) - - def __reduce_ex__( # type: ignore[override] - self, protocol: int - ) -> tuple[ - type[DateTime], tuple[int, int, int, int, int, int, int, datetime.tzinfo | None] - ]: - return self.__class__, self._getstate(protocol) - - def _cmp(self, other: datetime.datetime, **kwargs: Any) -> int: - # Fix for pypy which compares using this method - # which would lead to infinite recursion if we didn't override - dt = datetime.datetime( - self.year, - self.month, - self.day, - self.hour, - self.minute, - self.second, - self.microsecond, - tzinfo=self.tz, - fold=self.fold, - ) - - return 0 if dt == other else 1 if dt > other else -1 - - -DateTime.min: DateTime = DateTime(1, 1, 1, 0, 0, tzinfo=UTC) # type: ignore[misc] -DateTime.max: DateTime = DateTime( # type: ignore[misc] - 9999, 12, 31, 23, 59, 59, 999999, tzinfo=UTC -) -DateTime.EPOCH: DateTime = DateTime(1970, 1, 1, tzinfo=UTC) # type: ignore[misc] diff --git a/pendulum/duration.py b/pendulum/duration.py deleted file mode 100644 index a3a68b1..0000000 --- a/pendulum/duration.py +++ /dev/null @@ -1,502 +0,0 @@ -from __future__ import annotations - -from datetime import timedelta -from typing import cast -from typing import overload - -import pendulum - -from pendulum.constants import SECONDS_PER_DAY -from pendulum.constants import SECONDS_PER_HOUR -from pendulum.constants import SECONDS_PER_MINUTE -from pendulum.constants import US_PER_SECOND -from pendulum.utils._compat import PYPY - - -def _divide_and_round(a: float, b: float) -> int: - """divide a by b and round result to the nearest integer - - When the ratio is exactly half-way between two integers, - the even integer is returned. - """ - # Based on the reference implementation for divmod_near - # in Objects/longobject.c. - q, r = divmod(a, b) - - # The output of divmod() is either a float or an int, - # but we always want it to be an int. - q = int(q) - - # round up if either r / b > 0.5, or r / b == 0.5 and q is odd. - # The expression r / b > 0.5 is equivalent to 2 * r > b if b is - # positive, 2 * r < b if b negative. - r *= 2 - greater_than_half = r > b if b > 0 else r < b - if greater_than_half or r == b and q % 2 == 1: - q += 1 - - return q - - -class Duration(timedelta): - """ - Replacement for the standard timedelta class. - - Provides several improvements over the base class. - """ - - _total: float = 0 - _years: int = 0 - _months: int = 0 - _weeks: int = 0 - _days: int = 0 - _remaining_days: int = 0 - _seconds: int = 0 - _microseconds: int = 0 - - _y = None - _m = None - _w = None - _d = None - _h = None - _i = None - _s = None - _invert = None - - def __new__( - cls, - days: float = 0, - seconds: float = 0, - microseconds: float = 0, - milliseconds: float = 0, - minutes: float = 0, - hours: float = 0, - weeks: float = 0, - years: float = 0, - months: float = 0, - ) -> Duration: - if not isinstance(years, int) or not isinstance(months, int): - raise ValueError("Float year and months are not supported") - - self = timedelta.__new__( - cls, - days + years * 365 + months * 30, - seconds, - microseconds, - milliseconds, - minutes, - hours, - weeks, - ) - - # Intuitive normalization - total = self.total_seconds() - (years * 365 + months * 30) * SECONDS_PER_DAY - self._total = total - - m = 1 - if total < 0: - m = -1 - - self._microseconds = round(total % m * 1e6) - self._seconds = abs(int(total)) % SECONDS_PER_DAY * m - - _days = abs(int(total)) // SECONDS_PER_DAY * m - self._days = _days - self._remaining_days = abs(_days) % 7 * m - self._weeks = abs(_days) // 7 * m - self._months = months - self._years = years - - return self - - def total_minutes(self) -> float: - return self.total_seconds() / SECONDS_PER_MINUTE - - def total_hours(self) -> float: - return self.total_seconds() / SECONDS_PER_HOUR - - def total_days(self) -> float: - return self.total_seconds() / SECONDS_PER_DAY - - def total_weeks(self) -> float: - return self.total_days() / 7 - - if PYPY: - - def total_seconds(self) -> float: - days = 0 - - if hasattr(self, "_years"): - days += self._years * 365 - - if hasattr(self, "_months"): - days += self._months * 30 - - if hasattr(self, "_remaining_days"): - days += self._weeks * 7 + self._remaining_days - else: - days += self._days - - return ( - (days * SECONDS_PER_DAY + self._seconds) * US_PER_SECOND - + self._microseconds - ) / US_PER_SECOND - - @property - def years(self) -> int: - return self._years - - @property - def months(self) -> int: - return self._months - - @property - def weeks(self) -> int: - return self._weeks - - if PYPY: - - @property - def days(self) -> int: - return self._years * 365 + self._months * 30 + self._days - - @property - def remaining_days(self) -> int: - return self._remaining_days - - @property - def hours(self) -> int: - if self._h is None: - seconds = self._seconds - self._h = 0 - if abs(seconds) >= 3600: - self._h = (abs(seconds) // 3600 % 24) * self._sign(seconds) - - return self._h - - @property - def minutes(self) -> int: - if self._i is None: - seconds = self._seconds - self._i = 0 - if abs(seconds) >= 60: - self._i = (abs(seconds) // 60 % 60) * self._sign(seconds) - - return self._i - - @property - def seconds(self) -> int: - return self._seconds - - @property - def remaining_seconds(self) -> int: - if self._s is None: - self._s = self._seconds - self._s = abs(self._s) % 60 * self._sign(self._s) - - return self._s - - @property - def microseconds(self) -> int: - return self._microseconds - - @property - def invert(self) -> bool: - if self._invert is None: - self._invert = self.total_seconds() < 0 - - return self._invert - - def in_weeks(self) -> int: - return int(self.total_weeks()) - - def in_days(self) -> int: - return int(self.total_days()) - - def in_hours(self) -> int: - return int(self.total_hours()) - - def in_minutes(self) -> int: - return int(self.total_minutes()) - - def in_seconds(self) -> int: - return int(self.total_seconds()) - - def in_words(self, locale: str | None = None, separator: str = " ") -> str: - """ - Get the current interval in words in the current locale. - - Ex: 6 jours 23 heures 58 minutes - - :param locale: The locale to use. Defaults to current locale. - :param separator: The separator to use between each unit - """ - periods = [ - ("year", self.years), - ("month", self.months), - ("week", self.weeks), - ("day", self.remaining_days), - ("hour", self.hours), - ("minute", self.minutes), - ("second", self.remaining_seconds), - ] - - if locale is None: - locale = pendulum.get_locale() - - loaded_locale = pendulum.locale(locale) - - parts = [] - for period in periods: - unit, period_count = period - if abs(period_count) > 0: - translation = loaded_locale.translation( - f"units.{unit}.{loaded_locale.plural(abs(period_count))}" - ) - parts.append(translation.format(period_count)) - - if not parts: - count: int | str = 0 - if abs(self.microseconds) > 0: - unit = f"units.second.{loaded_locale.plural(1)}" - count = f"{abs(self.microseconds) / 1e6:.2f}" - else: - unit = f"units.microsecond.{loaded_locale.plural(0)}" - translation = loaded_locale.translation(unit) - parts.append(translation.format(count)) - - return separator.join(parts) - - def _sign(self, value: float) -> int: - if value < 0: - return -1 - - return 1 - - def as_timedelta(self) -> timedelta: - """ - Return the interval as a native timedelta. - """ - return timedelta(seconds=self.total_seconds()) - - def __str__(self) -> str: - return self.in_words() - - def __repr__(self) -> str: - rep = f"{self.__class__.__name__}(" - - if self._years: - rep += f"years={self._years}, " - - if self._months: - rep += f"months={self._months}, " - - if self._weeks: - rep += f"weeks={self._weeks}, " - - if self._days: - rep += f"days={self._remaining_days}, " - - if self.hours: - rep += f"hours={self.hours}, " - - if self.minutes: - rep += f"minutes={self.minutes}, " - - if self.remaining_seconds: - rep += f"seconds={self.remaining_seconds}, " - - if self.microseconds: - rep += f"microseconds={self.microseconds}, " - - rep += ")" - - return rep.replace(", )", ")") - - def __add__(self, other: timedelta) -> Duration: - if isinstance(other, timedelta): - return self.__class__(seconds=self.total_seconds() + other.total_seconds()) - - return NotImplemented - - __radd__ = __add__ - - def __sub__(self, other: timedelta) -> Duration: - if isinstance(other, timedelta): - return self.__class__(seconds=self.total_seconds() - other.total_seconds()) - - return NotImplemented - - def __neg__(self) -> Duration: - return self.__class__( - years=-self._years, - months=-self._months, - weeks=-self._weeks, - days=-self._remaining_days, - seconds=-self._seconds, - microseconds=-self._microseconds, - ) - - def _to_microseconds(self) -> int: - return (self._days * (24 * 3600) + self._seconds) * 1000000 + self._microseconds - - def __mul__(self, other: int | float) -> Duration: - if isinstance(other, int): - return self.__class__( - years=self._years * other, - months=self._months * other, - seconds=self._total * other, - ) - - if isinstance(other, float): - usec = self._to_microseconds() - a, b = other.as_integer_ratio() - - return self.__class__(0, 0, _divide_and_round(usec * a, b)) - - return NotImplemented - - __rmul__ = __mul__ - - @overload - def __floordiv__(self, other: timedelta) -> int: - ... - - @overload - def __floordiv__(self, other: int) -> Duration: - ... - - def __floordiv__(self, other: int | timedelta) -> int | Duration: - if not isinstance(other, (int, timedelta)): - return NotImplemented - - usec = self._to_microseconds() - if isinstance(other, timedelta): - return cast(int, usec // other._to_microseconds()) # type: ignore[attr-defined] - - if isinstance(other, int): - return self.__class__( - 0, - 0, - usec // other, - years=self._years // other, - months=self._months // other, - ) - - @overload - def __truediv__(self, other: timedelta) -> float: - ... - - @overload - def __truediv__(self, other: float) -> Duration: - ... - - def __truediv__(self, other: int | float | timedelta) -> Duration | float: - if not isinstance(other, (int, float, timedelta)): - return NotImplemented - - usec = self._to_microseconds() - if isinstance(other, timedelta): - return cast(float, usec / other._to_microseconds()) # type: ignore[attr-defined] - - if isinstance(other, int): - return self.__class__( - 0, - 0, - _divide_and_round(usec, other), - years=_divide_and_round(self._years, other), - months=_divide_and_round(self._months, other), - ) - - if isinstance(other, float): - a, b = other.as_integer_ratio() - - return self.__class__( - 0, - 0, - _divide_and_round(b * usec, a), - years=_divide_and_round(self._years * b, a), - months=_divide_and_round(self._months, other), - ) - - __div__ = __floordiv__ - - def __mod__(self, other: timedelta) -> Duration: - if isinstance(other, timedelta): - r = self._to_microseconds() % other._to_microseconds() # type: ignore[attr-defined] - - return self.__class__(0, 0, r) - - return NotImplemented - - def __divmod__(self, other: timedelta) -> tuple[int, Duration]: - if isinstance(other, timedelta): - q, r = divmod(self._to_microseconds(), other._to_microseconds()) # type: ignore[attr-defined] - - return q, self.__class__(0, 0, r) - - return NotImplemented - - -Duration.min = Duration(days=-999999999) -Duration.max = Duration( - days=999999999, hours=23, minutes=59, seconds=59, microseconds=999999 -) -Duration.resolution = Duration(microseconds=1) - - -class AbsoluteDuration(Duration): - """ - Duration that expresses a time difference in absolute values. - """ - - def __new__( - cls, - days: float = 0, - seconds: float = 0, - microseconds: float = 0, - milliseconds: float = 0, - minutes: float = 0, - hours: float = 0, - weeks: float = 0, - years: float = 0, - months: float = 0, - ) -> AbsoluteDuration: - if not isinstance(years, int) or not isinstance(months, int): - raise ValueError("Float year and months are not supported") - - self = timedelta.__new__( - cls, days, seconds, microseconds, milliseconds, minutes, hours, weeks - ) - - # We need to compute the total_seconds() value - # on a native timedelta object - delta = timedelta( - days, seconds, microseconds, milliseconds, minutes, hours, weeks - ) - - # Intuitive normalization - self._total = delta.total_seconds() - total = abs(self._total) - - self._microseconds = round(total % 1 * 1e6) - self._seconds = int(total) % SECONDS_PER_DAY - - days = int(total) // SECONDS_PER_DAY - self._days = abs(days + years * 365 + months * 30) - self._remaining_days = days % 7 - self._weeks = days // 7 - self._months = abs(months) - self._years = abs(years) - - return self - - def total_seconds(self) -> float: - return abs(self._total) - - @property - def invert(self) -> bool: - if self._invert is None: - self._invert = self._total < 0 - - return self._invert diff --git a/pendulum/exceptions.py b/pendulum/exceptions.py deleted file mode 100644 index 3ab4db9..0000000 --- a/pendulum/exceptions.py +++ /dev/null @@ -1,8 +0,0 @@ -from __future__ import annotations - -from .parsing.exceptions import ParserError # noqa - - -class PendulumException(Exception): - - pass diff --git a/pendulum/formatting/__init__.py b/pendulum/formatting/__init__.py deleted file mode 100644 index 975c409..0000000 --- a/pendulum/formatting/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from __future__ import annotations - -from pendulum.formatting.formatter import Formatter - -__all__ = ["Formatter"] diff --git a/pendulum/formatting/difference_formatter.py b/pendulum/formatting/difference_formatter.py deleted file mode 100644 index dad219d..0000000 --- a/pendulum/formatting/difference_formatter.py +++ /dev/null @@ -1,146 +0,0 @@ -from __future__ import annotations - -import typing as t - -from pendulum.locales.locale import Locale - -if t.TYPE_CHECKING: - from pendulum import Duration - - -class DifferenceFormatter: - """ - Handles formatting differences in text. - """ - - def __init__(self, locale: str = "en") -> None: - self._locale = Locale.load(locale) - - def format( - self, - diff: Duration, - is_now: bool = True, - absolute: bool = False, - locale: str | Locale | None = None, - ) -> str: - """ - Formats a difference. - - :param diff: The difference to format - :param is_now: Whether the difference includes now - :param absolute: Whether it's an absolute difference or not - :param locale: The locale to use - """ - if locale is None: - locale = self._locale - else: - locale = Locale.load(locale) - - if diff.years > 0: - unit = "year" - count = diff.years - - if diff.months > 6: - count += 1 - elif diff.months == 11 and (diff.weeks * 7 + diff.remaining_days) > 15: - unit = "year" - count = 1 - elif diff.months > 0: - unit = "month" - count = diff.months - - if (diff.weeks * 7 + diff.remaining_days) >= 27: - count += 1 - elif diff.weeks > 0: - unit = "week" - count = diff.weeks - - if diff.remaining_days > 3: - count += 1 - elif diff.remaining_days > 0: - unit = "day" - count = diff.remaining_days - - if diff.hours >= 22: - count += 1 - elif diff.hours > 0: - unit = "hour" - count = diff.hours - elif diff.minutes > 0: - unit = "minute" - count = diff.minutes - elif 10 < diff.remaining_seconds <= 59: - unit = "second" - count = diff.remaining_seconds - else: - # We check if the "a few seconds" unit exists - time = locale.get("custom.units.few_second") - if time is not None: - if absolute: - return t.cast(str, time) - - key = "custom" - is_future = diff.invert - if is_now: - if is_future: - key += ".from_now" - else: - key += ".ago" - else: - if is_future: - key += ".after" - else: - key += ".before" - - return t.cast(str, locale.get(key).format(time)) - else: - unit = "second" - count = diff.remaining_seconds - - if count == 0: - count = 1 - - if absolute: - key = f"translations.units.{unit}" - else: - is_future = diff.invert - - if is_now: - # Relative to now, so we can use - # the CLDR data - key = f"translations.relative.{unit}" - - if is_future: - key += ".future" - else: - key += ".past" - else: - # Absolute comparison - # So we have to use the custom locale data - - # Checking for special pluralization rules - key = "custom.units_relative" - if is_future: - key += f".{unit}.future" - else: - key += f".{unit}.past" - - trans = locale.get(key) - if not trans: - # No special rule - key = f"translations.units.{unit}.{locale.plural(count)}" - time = locale.get(key).format(count) - else: - time = trans[locale.plural(count)].format(count) - - key = "custom" - if is_future: - key += ".after" - else: - key += ".before" - - return t.cast(str, locale.get(key).format(time)) - - key += f".{locale.plural(count)}" - - return t.cast(str, locale.get(key).format(count)) diff --git a/pendulum/formatting/formatter.py b/pendulum/formatting/formatter.py deleted file mode 100644 index f91d5d9..0000000 --- a/pendulum/formatting/formatter.py +++ /dev/null @@ -1,683 +0,0 @@ -from __future__ import annotations - -import datetime -import re - -from typing import TYPE_CHECKING -from typing import Any -from typing import Callable -from typing import Match -from typing import Sequence -from typing import cast - -import pendulum - -from pendulum.locales.locale import Locale - -if TYPE_CHECKING: - from pendulum import Timezone - -_MATCH_1 = r"\d" -_MATCH_2 = r"\d\d" -_MATCH_3 = r"\d{3}" -_MATCH_4 = r"\d{4}" -_MATCH_6 = r"[+-]?\d{6}" -_MATCH_1_TO_2 = r"\d\d?" -_MATCH_1_TO_2_LEFT_PAD = r"[0-9 ]\d?" -_MATCH_1_TO_3 = r"\d{1,3}" -_MATCH_1_TO_4 = r"\d{1,4}" -_MATCH_1_TO_6 = r"[+-]?\d{1,6}" -_MATCH_3_TO_4 = r"\d{3}\d?" -_MATCH_5_TO_6 = r"\d{5}\d?" -_MATCH_UNSIGNED = r"\d+" -_MATCH_SIGNED = r"[+-]?\d+" -_MATCH_OFFSET = r"[Zz]|[+-]\d\d:?\d\d" -_MATCH_SHORT_OFFSET = r"[Zz]|[+-]\d\d(?::?\d\d)?" -_MATCH_TIMESTAMP = r"[+-]?\d+(\.\d{1,6})?" -_MATCH_WORD = ( - "(?i)[0-9]*" - "['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+" - r"|[\u0600-\u06FF/]+(\s*?[\u0600-\u06FF]+){1,2}" -) -_MATCH_TIMEZONE = "[A-Za-z0-9-+]+(/[A-Za-z0-9-+_]+)?" - - -class Formatter: - _TOKENS: str = ( - r"\[([^\[]*)\]|\\(.)|" - "(" - "Mo|MM?M?M?" - "|Do|DDDo|DD?D?D?|ddd?d?|do?" - "|E{1,4}" - "|w[o|w]?|W[o|W]?|Qo?" - "|YYYY|YY|Y" - "|gg(ggg?)?|GG(GGG?)?" - "|a|A" - "|hh?|HH?|kk?" - "|mm?|ss?|S{1,9}" - "|x|X" - "|zz?|ZZ?" - "|LTS|LT|LL?L?L?" - ")" - ) - - _FORMAT_RE: re.Pattern[str] = re.compile(_TOKENS) - - _FROM_FORMAT_RE: re.Pattern[str] = re.compile(r"(? str: - """ - Formats a DateTime instance with a given format and locale. - - :param dt: The instance to format - :param fmt: The format to use - :param locale: The locale to use - """ - loaded_locale: Locale = Locale.load(locale or pendulum.get_locale()) - - result = self._FORMAT_RE.sub( - lambda m: m.group(1) - if m.group(1) - else m.group(2) - if m.group(2) - else self._format_token(dt, m.group(3), loaded_locale), - fmt, - ) - - return result - - def _format_token(self, dt: pendulum.DateTime, token: str, locale: Locale) -> str: - """ - Formats a DateTime instance with a given token and locale. - - :param dt: The instance to format - :param token: The token to use - :param locale: The locale to use - """ - if token in self._DATE_FORMATS: - fmt = locale.get(f"custom.date_formats.{token}") - if fmt is None: - fmt = self._DEFAULT_DATE_FORMATS[token] - - return self.format(dt, fmt, locale) - - if token in self._LOCALIZABLE_TOKENS: - return self._format_localizable_token(dt, token, locale) - - if token in self._TOKENS_RULES: - return self._TOKENS_RULES[token](dt) - - # Timezone - if token in ["ZZ", "Z"]: - if dt.tzinfo is None: - return "" - - separator = ":" if token == "Z" else "" - offset = dt.utcoffset() or datetime.timedelta() - minutes = offset.total_seconds() / 60 - - if minutes >= 0: - sign = "+" - else: - sign = "-" - - hour, minute = divmod(abs(int(minutes)), 60) - - return f"{sign}{hour:02d}{separator}{minute:02d}" - - return token - - def _format_localizable_token( - self, dt: pendulum.DateTime, token: str, locale: Locale - ) -> str: - """ - Formats a DateTime instance - with a given localizable token and locale. - - :param dt: The instance to format - :param token: The token to use - :param locale: The locale to use - """ - if token == "MMM": - return cast(str, locale.get("translations.months.abbreviated")[dt.month]) - elif token == "MMMM": - return cast(str, locale.get("translations.months.wide")[dt.month]) - elif token == "dd": - return cast(str, locale.get("translations.days.short")[dt.day_of_week]) - elif token == "ddd": - return cast( - str, locale.get("translations.days.abbreviated")[dt.day_of_week] - ) - elif token == "dddd": - return cast(str, locale.get("translations.days.wide")[dt.day_of_week]) - elif token == "Do": - return locale.ordinalize(dt.day) - elif token == "do": - return locale.ordinalize(dt.day_of_week) - elif token == "Mo": - return locale.ordinalize(dt.month) - elif token == "Qo": - return locale.ordinalize(dt.quarter) - elif token == "wo": - return locale.ordinalize(dt.week_of_year) - elif token == "DDDo": - return locale.ordinalize(dt.day_of_year) - elif token == "A": - key = "translations.day_periods" - if dt.hour >= 12: - key += ".pm" - else: - key += ".am" - - return cast(str, locale.get(key)) - else: - return token - - def parse( - self, - time: str, - fmt: str, - now: pendulum.DateTime, - locale: str | None = None, - ) -> dict[str, Any]: - """ - Parses a time string matching a given format as a tuple. - - :param time: The timestring - :param fmt: The format - :param now: The datetime to use as "now" - :param locale: The locale to use - - :return: The parsed elements - """ - escaped_fmt = re.escape(fmt) - - tokens = self._FROM_FORMAT_RE.findall(escaped_fmt) - if not tokens: - raise ValueError("The given time string does not match the given format") - - if not locale: - locale = pendulum.get_locale() - - loaded_locale: Locale = Locale.load(locale) - - parsed = { - "year": None, - "month": None, - "day": None, - "hour": None, - "minute": None, - "second": None, - "microsecond": None, - "tz": None, - "quarter": None, - "day_of_week": None, - "day_of_year": None, - "meridiem": None, - "timestamp": None, - } - - pattern = self._FROM_FORMAT_RE.sub( - lambda m: self._replace_tokens(m.group(0), loaded_locale), escaped_fmt - ) - - if not re.search("^" + pattern + "$", time): - raise ValueError(f"String does not match format {fmt}") - - _get_parsed_values: Callable[ - [Match[str]], Any - ] = lambda m: self._get_parsed_values(m, parsed, loaded_locale, now) - - re.sub(pattern, _get_parsed_values, time) - - return self._check_parsed(parsed, now) - - def _check_parsed( - self, parsed: dict[str, Any], now: pendulum.DateTime - ) -> dict[str, Any]: - """ - Checks validity of parsed elements. - - :param parsed: The elements to parse. - - :return: The validated elements. - """ - validated: dict[str, int | Timezone | None] = { - "year": parsed["year"], - "month": parsed["month"], - "day": parsed["day"], - "hour": parsed["hour"], - "minute": parsed["minute"], - "second": parsed["second"], - "microsecond": parsed["microsecond"], - "tz": None, - } - - # If timestamp has been specified - # we use it and don't go any further - if parsed["timestamp"] is not None: - str_us = str(parsed["timestamp"]) - if "." in str_us: - microseconds = int(f'{str_us.split(".")[1].ljust(6, "0")}') - else: - microseconds = 0 - - from pendulum.helpers import local_time - - time = local_time(parsed["timestamp"], 0, microseconds) - validated["year"] = time[0] - validated["month"] = time[1] - validated["day"] = time[2] - validated["hour"] = time[3] - validated["minute"] = time[4] - validated["second"] = time[5] - validated["microsecond"] = time[6] - - return validated - - if parsed["quarter"] is not None: - if validated["year"] is not None: - dt = pendulum.datetime(validated["year"], 1, 1) - else: - dt = now - - dt = dt.start_of("year") - - while dt.quarter != parsed["quarter"]: - dt = dt.add(months=3) - - validated["year"] = dt.year - validated["month"] = dt.month - validated["day"] = dt.day - - if validated["year"] is None: - validated["year"] = now.year - - if parsed["day_of_year"] is not None: - dt = cast( - pendulum.DateTime, - pendulum.parse(f'{validated["year"]}-{parsed["day_of_year"]:>03d}'), - ) - - validated["month"] = dt.month - validated["day"] = dt.day - - if parsed["day_of_week"] is not None: - dt = pendulum.datetime( - cast(int, validated["year"]), - validated["month"] or now.month, - validated["day"] or now.day, - ) - dt = dt.start_of("week").subtract(days=1) - dt = dt.next(parsed["day_of_week"]) - validated["year"] = dt.year - validated["month"] = dt.month - validated["day"] = dt.day - - # Meridiem - if parsed["meridiem"] is not None: - # If the time is greater than 13:00:00 - # This is not valid - if validated["hour"] is None: - raise ValueError("Invalid Date") - - t = ( - validated["hour"], - validated["minute"], - validated["second"], - validated["microsecond"], - ) - if t >= (13, 0, 0, 0): - raise ValueError("Invalid date") - - pm = parsed["meridiem"] == "pm" - validated["hour"] %= 12 - if pm: - validated["hour"] += 12 - - if validated["month"] is None: - if parsed["year"] is not None: - validated["month"] = parsed["month"] or 1 - else: - validated["month"] = parsed["month"] or now.month - - if validated["day"] is None: - if parsed["year"] is not None or parsed["month"] is not None: - validated["day"] = parsed["day"] or 1 - else: - validated["day"] = parsed["day"] or now.day - - for part in ["hour", "minute", "second", "microsecond"]: - if validated[part] is None: - validated[part] = 0 - - validated["tz"] = parsed["tz"] - - return validated - - def _get_parsed_values( - self, - m: Match[str], - parsed: dict[str, Any], - locale: Locale, - now: pendulum.DateTime, - ) -> None: - for token, index in m.re.groupindex.items(): - if token in self._LOCALIZABLE_TOKENS: - self._get_parsed_locale_value(token, m.group(index), parsed, locale) - else: - self._get_parsed_value(token, m.group(index), parsed, now) - - def _get_parsed_value( - self, - token: str, - value: str, - parsed: dict[str, Any], - now: pendulum.DateTime, - ) -> None: - parsed_token = self._PARSE_TOKENS[token](value) - - if "Y" in token: - if token == "YY": - parsed_token = now.year // 100 * 100 + parsed_token - - parsed["year"] = parsed_token - elif token == "Q": - parsed["quarter"] = parsed_token - elif token in ["MM", "M"]: - parsed["month"] = parsed_token - elif token in ["DDDD", "DDD"]: - parsed["day_of_year"] = parsed_token - elif "D" in token: - parsed["day"] = parsed_token - elif "H" in token: - parsed["hour"] = parsed_token - elif token in ["hh", "h"]: - if parsed_token > 12: - raise ValueError("Invalid date") - - parsed["hour"] = parsed_token - elif "m" in token: - parsed["minute"] = parsed_token - elif "s" in token: - parsed["second"] = parsed_token - elif "S" in token: - parsed["microsecond"] = parsed_token - elif token in ["d", "E"]: - parsed["day_of_week"] = parsed_token - elif token in ["X", "x"]: - parsed["timestamp"] = parsed_token - elif token in ["ZZ", "Z"]: - negative = bool(value.startswith("-")) - tz = value[1:] - if ":" not in tz: - if len(tz) == 2: - tz = f"{tz}00" - - off_hour = tz[0:2] - off_minute = tz[2:4] - else: - off_hour, off_minute = tz.split(":") - - offset = ((int(off_hour) * 60) + int(off_minute)) * 60 - - if negative: - offset = -1 * offset - - parsed["tz"] = pendulum.timezone(offset) - elif token == "z": - # Full timezone - if value not in pendulum.timezones(): - raise ValueError("Invalid date") - - parsed["tz"] = pendulum.timezone(value) - - def _get_parsed_locale_value( - self, token: str, value: str, parsed: dict[str, Any], locale: Locale - ) -> None: - if token == "MMMM": - unit = "month" - match = "months.wide" - elif token == "MMM": - unit = "month" - match = "months.abbreviated" - elif token == "Do": - parsed["day"] = int(cast(Match[str], re.match(r"(\d+)", value)).group(1)) - - return - elif token == "dddd": - unit = "day_of_week" - match = "days.wide" - elif token == "ddd": - unit = "day_of_week" - match = "days.abbreviated" - elif token == "dd": - unit = "day_of_week" - match = "days.short" - elif token in ["a", "A"]: - valid_values = [ - locale.translation("day_periods.am"), - locale.translation("day_periods.pm"), - ] - - if token == "a": - value = value.lower() - valid_values = [x.lower() for x in valid_values] - - if value not in valid_values: - raise ValueError("Invalid date") - - parsed["meridiem"] = ["am", "pm"][valid_values.index(value)] - - return - else: - raise ValueError(f'Invalid token "{token}"') - - parsed[unit] = locale.match_translation(match, value) - if value is None: - raise ValueError("Invalid date") - - def _replace_tokens(self, token: str, locale: Locale) -> str: - if token.startswith("[") and token.endswith("]"): - return token[1:-1] - elif token.startswith("\\"): - if len(token) == 2 and token[1] in {"[", "]"}: - return "" - - return token - elif token not in self._REGEX_TOKENS and token not in self._LOCALIZABLE_TOKENS: - raise ValueError(f"Unsupported token: {token}") - - if token in self._LOCALIZABLE_TOKENS: - values = self._LOCALIZABLE_TOKENS[token] - if callable(values): - candidates = values(locale) - else: - candidates = tuple( - locale.translation( - cast(str, self._LOCALIZABLE_TOKENS[token]) - ).values() - ) - else: - candidates = cast(Sequence[str], self._REGEX_TOKENS[token]) - - if not candidates: - raise ValueError(f"Unsupported token: {token}") - - if not isinstance(candidates, tuple): - candidates = (cast(str, candidates),) - - pattern = f'(?P<{token}>{"|".join(candidates)})' - - return pattern diff --git a/pendulum/helpers.py b/pendulum/helpers.py deleted file mode 100644 index 13b7f22..0000000 --- a/pendulum/helpers.py +++ /dev/null @@ -1,223 +0,0 @@ -from __future__ import annotations - -import os -import struct - -from datetime import date -from datetime import datetime -from datetime import timedelta -from math import copysign -from typing import TYPE_CHECKING -from typing import TypeVar -from typing import overload - -import pendulum - -from pendulum.constants import DAYS_PER_MONTHS -from pendulum.formatting.difference_formatter import DifferenceFormatter -from pendulum.locales.locale import Locale - -if TYPE_CHECKING: - # Prevent import cycles - from pendulum.duration import Duration - -with_extensions = os.getenv("PENDULUM_EXTENSIONS", "1") == "1" - -_DT = TypeVar("_DT", bound=datetime) -_D = TypeVar("_D", bound=date) - -try: - # nopycln: file # noqa: E800 - if not with_extensions or struct.calcsize("P") == 4: - raise ImportError() - - from pendulum._extensions._helpers import PreciseDiff - from pendulum._extensions._helpers import days_in_year - from pendulum._extensions._helpers import is_leap - from pendulum._extensions._helpers import is_long_year - from pendulum._extensions._helpers import local_time - from pendulum._extensions._helpers import precise_diff - from pendulum._extensions._helpers import timestamp - from pendulum._extensions._helpers import week_day -except ImportError: - from pendulum._extensions.helpers import PreciseDiff # type: ignore[misc] - from pendulum._extensions.helpers import days_in_year - from pendulum._extensions.helpers import is_leap - from pendulum._extensions.helpers import is_long_year - from pendulum._extensions.helpers import local_time - from pendulum._extensions.helpers import precise_diff # type: ignore[misc] - from pendulum._extensions.helpers import timestamp - from pendulum._extensions.helpers import week_day - -difference_formatter = DifferenceFormatter() - - -@overload -def add_duration( - dt: datetime, - years: int = 0, - months: int = 0, - weeks: int = 0, - days: int = 0, - hours: int = 0, - minutes: int = 0, - seconds: float = 0, - microseconds: int = 0, -) -> datetime: - ... - - -@overload -def add_duration( - dt: date, - years: int = 0, - months: int = 0, - weeks: int = 0, - days: int = 0, -) -> date: - pass - - -def add_duration( - dt: date | datetime, - years: int = 0, - months: int = 0, - weeks: int = 0, - days: int = 0, - hours: int = 0, - minutes: int = 0, - seconds: float = 0, - microseconds: int = 0, -) -> date | datetime: - """ - Adds a duration to a date/datetime instance. - """ - days += weeks * 7 - - if ( - isinstance(dt, date) - and not isinstance(dt, datetime) - and any([hours, minutes, seconds, microseconds]) - ): - raise RuntimeError("Time elements cannot be added to a date instance.") - - # Normalizing - if abs(microseconds) > 999999: - s = _sign(microseconds) - div, mod = divmod(microseconds * s, 1000000) - microseconds = mod * s - seconds += div * s - - if abs(seconds) > 59: - s = _sign(seconds) - div, mod = divmod(seconds * s, 60) # type: ignore[assignment] - seconds = mod * s - minutes += div * s - - if abs(minutes) > 59: - s = _sign(minutes) - div, mod = divmod(minutes * s, 60) - minutes = mod * s - hours += div * s - - if abs(hours) > 23: - s = _sign(hours) - div, mod = divmod(hours * s, 24) - hours = mod * s - days += div * s - - if abs(months) > 11: - s = _sign(months) - div, mod = divmod(months * s, 12) - months = mod * s - years += div * s - - year = dt.year + years - month = dt.month - - if months: - month += months - if month > 12: - year += 1 - month -= 12 - elif month < 1: - year -= 1 - month += 12 - - day = min(DAYS_PER_MONTHS[int(is_leap(year))][month], dt.day) - - dt = dt.replace(year=year, month=month, day=day) - - return dt + timedelta( - days=days, - hours=hours, - minutes=minutes, - seconds=seconds, - microseconds=microseconds, - ) - - -def format_diff( - diff: Duration, - is_now: bool = True, - absolute: bool = False, - locale: str | None = None, -) -> str: - if locale is None: - locale = get_locale() - - return difference_formatter.format(diff, is_now, absolute, locale) - - -def _sign(x: float) -> int: - return int(copysign(1, x)) - - -# Global helpers - - -def locale(name: str) -> Locale: - return Locale.load(name) - - -def set_locale(name: str) -> None: - locale(name) - - pendulum._LOCALE = name - - -def get_locale() -> str: - return pendulum._LOCALE - - -def week_starts_at(wday: int) -> None: - if wday < pendulum.SUNDAY or wday > pendulum.SATURDAY: - raise ValueError("Invalid week day as start of week.") - - pendulum._WEEK_STARTS_AT = wday - - -def week_ends_at(wday: int) -> None: - if wday < pendulum.SUNDAY or wday > pendulum.SATURDAY: - raise ValueError("Invalid week day as start of week.") - - pendulum._WEEK_ENDS_AT = wday - - -__all__ = [ - "PreciseDiff", - "days_in_year", - "is_leap", - "is_long_year", - "local_time", - "precise_diff", - "timestamp", - "week_day", - "add_duration", - "format_diff", - "locale", - "set_locale", - "get_locale", - "week_starts_at", - "week_ends_at", -] diff --git a/pendulum/interval.py b/pendulum/interval.py deleted file mode 100644 index f20042b..0000000 --- a/pendulum/interval.py +++ /dev/null @@ -1,448 +0,0 @@ -from __future__ import annotations - -import operator - -from datetime import date -from datetime import datetime -from datetime import timedelta -from typing import TYPE_CHECKING -from typing import Iterator -from typing import Union -from typing import cast -from typing import overload - -import pendulum - -from pendulum.constants import MONTHS_PER_YEAR -from pendulum.duration import Duration -from pendulum.helpers import precise_diff - -if TYPE_CHECKING: - from typing import SupportsIndex - - from pendulum.helpers import PreciseDiff - from pendulum.locales.locale import Locale # noqa - - -class Interval(Duration): - """ - A period of time between two datetimes. - """ - - @overload - def __new__( - cls, - start: pendulum.DateTime | datetime, - end: pendulum.DateTime | datetime, - absolute: bool = False, - ) -> Interval: - ... - - @overload - def __new__( - cls, - start: pendulum.Date | date, - end: pendulum.Date | date, - absolute: bool = False, - ) -> Interval: - ... - - def __new__( - cls, - start: pendulum.DateTime | pendulum.Date | datetime | date, - end: pendulum.DateTime | pendulum.Date | datetime | date, - absolute: bool = False, - ) -> Interval: - if ( - isinstance(start, datetime) - and not isinstance(end, datetime) - or not isinstance(start, datetime) - and isinstance(end, datetime) - ): - raise ValueError("Both start and end of a Period must have the same type") - - if ( - isinstance(start, datetime) - and isinstance(end, datetime) - and ( - start.tzinfo is None - and end.tzinfo is not None - or start.tzinfo is not None - and end.tzinfo is None - ) - ): - raise TypeError("can't compare offset-naive and offset-aware datetimes") - - if absolute and start > end: - end, start = start, end - - _start = start - _end = end - if isinstance(start, pendulum.DateTime): - _start = datetime( - start.year, - start.month, - start.day, - start.hour, - start.minute, - start.second, - start.microsecond, - tzinfo=start.tzinfo, - fold=start.fold, - ) - elif isinstance(start, pendulum.Date): - _start = date(start.year, start.month, start.day) - - if isinstance(end, pendulum.DateTime): - _end = datetime( - end.year, - end.month, - end.day, - end.hour, - end.minute, - end.second, - end.microsecond, - tzinfo=end.tzinfo, - fold=end.fold, - ) - elif isinstance(end, pendulum.Date): - _end = date(end.year, end.month, end.day) - - # Fixing issues with datetime.__sub__() - # not handling offsets if the tzinfo is the same - if ( - isinstance(_start, datetime) - and isinstance(_end, datetime) - and _start.tzinfo is _end.tzinfo - ): - if _start.tzinfo is not None: - offset = cast(timedelta, cast(datetime, start).utcoffset()) - _start = (_start - offset).replace(tzinfo=None) - - if isinstance(end, datetime) and _end.tzinfo is not None: - offset = cast(timedelta, end.utcoffset()) - _end = (_end - offset).replace(tzinfo=None) - - delta: timedelta = _end - _start # type: ignore[operator] - - return cast(Interval, super().__new__(cls, seconds=delta.total_seconds())) - - def __init__( - self, - start: pendulum.DateTime | pendulum.Date | datetime | date, - end: pendulum.DateTime | pendulum.Date | datetime | date, - absolute: bool = False, - ) -> None: - super().__init__() - - _start: pendulum.DateTime | pendulum.Date | datetime | date - if not isinstance(start, pendulum.Date): - if isinstance(start, datetime): - start = pendulum.instance(start) - else: - start = pendulum.date(start.year, start.month, start.day) - - _start = start - else: - if isinstance(start, pendulum.DateTime): - _start = datetime( - start.year, - start.month, - start.day, - start.hour, - start.minute, - start.second, - start.microsecond, - tzinfo=start.tzinfo, - ) - else: - _start = date(start.year, start.month, start.day) - - _end: pendulum.DateTime | pendulum.Date | datetime | date - if not isinstance(end, pendulum.Date): - if isinstance(end, datetime): - end = pendulum.instance(end) - else: - end = pendulum.date(end.year, end.month, end.day) - - _end = end - else: - if isinstance(end, pendulum.DateTime): - _end = datetime( - end.year, - end.month, - end.day, - end.hour, - end.minute, - end.second, - end.microsecond, - tzinfo=end.tzinfo, - ) - else: - _end = date(end.year, end.month, end.day) - - self._invert = False - if start > end: - self._invert = True - - if absolute: - end, start = start, end - _end, _start = _start, _end - - self._absolute = absolute - self._start: pendulum.DateTime | pendulum.Date = start - self._end: pendulum.DateTime | pendulum.Date = end - self._delta: PreciseDiff = precise_diff(_start, _end) - - @property - def years(self) -> int: - return self._delta.years - - @property - def months(self) -> int: - return self._delta.months - - @property - def weeks(self) -> int: - return abs(self._delta.days) // 7 * self._sign(self._delta.days) - - @property - def days(self) -> int: - return self._days - - @property - def remaining_days(self) -> int: - return abs(self._delta.days) % 7 * self._sign(self._days) - - @property - def hours(self) -> int: - return self._delta.hours - - @property - def minutes(self) -> int: - return self._delta.minutes - - @property - def start(self) -> pendulum.DateTime | pendulum.Date | datetime | date: - return self._start - - @property - def end(self) -> pendulum.DateTime | pendulum.Date | datetime | date: - return self._end - - def in_years(self) -> int: - """ - Gives the duration of the Period in full years. - """ - return self.years - - def in_months(self) -> int: - """ - Gives the duration of the Period in full months. - """ - return self.years * MONTHS_PER_YEAR + self.months - - def in_weeks(self) -> int: - days = self.in_days() - sign = 1 - - if days < 0: - sign = -1 - - return sign * (abs(days) // 7) - - def in_days(self) -> int: - return self._delta.total_days - - def in_words(self, locale: str | None = None, separator: str = " ") -> str: - """ - Get the current interval in words in the current locale. - - Ex: 6 jours 23 heures 58 minutes - - :param locale: The locale to use. Defaults to current locale. - :param separator: The separator to use between each unit - """ - from pendulum.locales.locale import Locale # noqa - - periods = [ - ("year", self.years), - ("month", self.months), - ("week", self.weeks), - ("day", self.remaining_days), - ("hour", self.hours), - ("minute", self.minutes), - ("second", self.remaining_seconds), - ] - loaded_locale: Locale = Locale.load(locale or pendulum.get_locale()) - parts = [] - for period in periods: - unit, period_count = period - if abs(period_count) > 0: - translation = loaded_locale.translation( - f"units.{unit}.{loaded_locale.plural(abs(period_count))}" - ) - parts.append(translation.format(period_count)) - - if not parts: - count: str | int = 0 - if abs(self.microseconds) > 0: - unit = f"units.second.{loaded_locale.plural(1)}" - count = f"{abs(self.microseconds) / 1e6:.2f}" - else: - unit = f"units.microsecond.{loaded_locale.plural(0)}" - - translation = loaded_locale.translation(unit) - parts.append(translation.format(count)) - - return separator.join(parts) - - def range( - self, unit: str, amount: int = 1 - ) -> Iterator[pendulum.DateTime | pendulum.Date]: - method = "add" - op = operator.le - if not self._absolute and self.invert: - method = "subtract" - op = operator.ge - - start, end = self.start, self.end - - i = amount - while op(start, end): - yield cast(Union[pendulum.DateTime, pendulum.Date], start) - - start = getattr(self.start, method)(**{unit: i}) - - i += amount - - def as_interval(self) -> Duration: - """ - Return the Period as a Duration. - """ - return Duration(seconds=self.total_seconds()) - - def __iter__(self) -> Iterator[pendulum.DateTime | pendulum.Date]: - return self.range("days") - - def __contains__( - self, item: datetime | date | pendulum.DateTime | pendulum.Date - ) -> bool: - return self.start <= item <= self.end - - def __add__(self, other: timedelta) -> Duration: - return self.as_interval().__add__(other) - - __radd__ = __add__ - - def __sub__(self, other: timedelta) -> Duration: - return self.as_interval().__sub__(other) - - def __neg__(self) -> Interval: - return self.__class__(self.end, self.start, self._absolute) - - def __mul__(self, other: int | float) -> Duration: - return self.as_interval().__mul__(other) - - __rmul__ = __mul__ - - @overload - def __floordiv__(self, other: timedelta) -> int: - ... - - @overload - def __floordiv__(self, other: int) -> Duration: - ... - - def __floordiv__(self, other: int | timedelta) -> int | Duration: - return self.as_interval().__floordiv__(other) - - __div__ = __floordiv__ # type: ignore[assignment] - - @overload - def __truediv__(self, other: timedelta) -> float: - ... - - @overload - def __truediv__(self, other: float) -> Duration: - ... - - def __truediv__(self, other: float | timedelta) -> Duration | float: - return self.as_interval().__truediv__(other) - - def __mod__(self, other: timedelta) -> Duration: - return self.as_interval().__mod__(other) - - def __divmod__(self, other: timedelta) -> tuple[int, Duration]: - return self.as_interval().__divmod__(other) - - def __abs__(self) -> Interval: - return self.__class__(self.start, self.end, absolute=True) - - def __repr__(self) -> str: - return f" {self._end}]>" - - def __str__(self) -> str: - return self.__repr__() - - def _cmp(self, other: timedelta) -> int: - # Only needed for PyPy - assert isinstance(other, timedelta) - - if isinstance(other, Interval): - other = other.as_timedelta() - - td = self.as_timedelta() - - return 0 if td == other else 1 if td > other else -1 - - def _getstate( - self, protocol: SupportsIndex = 3 - ) -> tuple[ - pendulum.DateTime | pendulum.Date | datetime | date, - pendulum.DateTime | pendulum.Date | datetime | date, - bool, - ]: - start, end = self.start, self.end - - if self._invert and self._absolute: - end, start = start, end - - return start, end, self._absolute - - def __reduce__( - self, - ) -> tuple[ - type[Interval], - tuple[ - pendulum.DateTime | pendulum.Date | datetime | date, - pendulum.DateTime | pendulum.Date | datetime | date, - bool, - ], - ]: - return self.__reduce_ex__(2) - - def __reduce_ex__( - self, protocol: SupportsIndex - ) -> tuple[ - type[Interval], - tuple[ - pendulum.DateTime | pendulum.Date | datetime | date, - pendulum.DateTime | pendulum.Date | datetime | date, - bool, - ], - ]: - return self.__class__, self._getstate(protocol) - - def __hash__(self) -> int: - return hash((self.start, self.end, self._absolute)) - - def __eq__(self, other: object) -> bool: - if isinstance(other, Interval): - return (self.start, self.end, self._absolute) == ( - other.start, - other.end, - other._absolute, - ) - else: - return self.as_interval() == other diff --git a/pendulum/locales/__init__.py b/pendulum/locales/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/cs/__init__.py b/pendulum/locales/cs/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/cs/custom.py b/pendulum/locales/cs/custom.py deleted file mode 100644 index 5f66b69..0000000 --- a/pendulum/locales/cs/custom.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -cs custom locale file. -""" - -translations = { - "units": {"few_second": "pár vteřin"}, - # Relative time - "ago": "{} zpět", - "from_now": "za {}", - "after": "{0} po", - "before": "{0} zpět", - # Ordinals - "ordinal": {"one": ".", "two": ".", "few": ".", "other": "."}, - # Date formats - "date_formats": { - "LTS": "h:mm:ss", - "LT": "h:mm", - "L": "DD. M. YYYY", - "LL": "D. MMMM, YYYY", - "LLL": "D. MMMM, YYYY h:mm", - "LLLL": "dddd, D. MMMM, YYYY h:mm", - }, -} diff --git a/pendulum/locales/cs/locale.py b/pendulum/locales/cs/locale.py deleted file mode 100644 index 2c51c78..0000000 --- a/pendulum/locales/cs/locale.py +++ /dev/null @@ -1,266 +0,0 @@ -from .custom import translations as custom_translations - - -""" -cs locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "few" - if ((n == n and (n >= 2 and n <= 4)) and (0 == 0 and (0 == 0))) - else "many" - if (not (0 == 0 and (0 == 0))) - else "one" - if ((n == n and (n == 1)) and (0 == 0 and (0 == 0))) - else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "ne", - 1: "po", - 2: "út", - 3: "st", - 4: "čt", - 5: "pá", - 6: "so", - }, - "narrow": { - 0: "N", - 1: "P", - 2: "Ú", - 3: "S", - 4: "Č", - 5: "P", - 6: "S", - }, - "short": { - 0: "ne", - 1: "po", - 2: "út", - 3: "st", - 4: "čt", - 5: "pá", - 6: "so", - }, - "wide": { - 0: "neděle", - 1: "pondělí", - 2: "úterý", - 3: "středa", - 4: "čtvrtek", - 5: "pátek", - 6: "sobota", - }, - }, - "months": { - "abbreviated": { - 1: "led", - 2: "úno", - 3: "bře", - 4: "dub", - 5: "kvě", - 6: "čvn", - 7: "čvc", - 8: "srp", - 9: "zář", - 10: "říj", - 11: "lis", - 12: "pro", - }, - "narrow": { - 1: "1", - 2: "2", - 3: "3", - 4: "4", - 5: "5", - 6: "6", - 7: "7", - 8: "8", - 9: "9", - 10: "10", - 11: "11", - 12: "12", - }, - "wide": { - 1: "ledna", - 2: "února", - 3: "března", - 4: "dubna", - 5: "května", - 6: "června", - 7: "července", - 8: "srpna", - 9: "září", - 10: "října", - 11: "listopadu", - 12: "prosince", - }, - }, - "units": { - "year": { - "one": "{0} rok", - "few": "{0} roky", - "many": "{0} roku", - "other": "{0} let", - }, - "month": { - "one": "{0} měsíc", - "few": "{0} měsíce", - "many": "{0} měsíce", - "other": "{0} měsíců", - }, - "week": { - "one": "{0} týden", - "few": "{0} týdny", - "many": "{0} týdne", - "other": "{0} týdnů", - }, - "day": { - "one": "{0} den", - "few": "{0} dny", - "many": "{0} dne", - "other": "{0} dní", - }, - "hour": { - "one": "{0} hodina", - "few": "{0} hodiny", - "many": "{0} hodiny", - "other": "{0} hodin", - }, - "minute": { - "one": "{0} minuta", - "few": "{0} minuty", - "many": "{0} minuty", - "other": "{0} minut", - }, - "second": { - "one": "{0} sekunda", - "few": "{0} sekundy", - "many": "{0} sekundy", - "other": "{0} sekund", - }, - "microsecond": { - "one": "{0} mikrosekunda", - "few": "{0} mikrosekundy", - "many": "{0} mikrosekundy", - "other": "{0} mikrosekund", - }, - }, - "relative": { - "year": { - "future": { - "other": "za {0} let", - "one": "za {0} rok", - "few": "za {0} roky", - "many": "za {0} roku", - }, - "past": { - "other": "před {0} lety", - "one": "před {0} rokem", - "few": "před {0} lety", - "many": "před {0} roku", - }, - }, - "month": { - "future": { - "other": "za {0} měsíců", - "one": "za {0} měsíc", - "few": "za {0} měsíce", - "many": "za {0} měsíce", - }, - "past": { - "other": "před {0} měsíci", - "one": "před {0} měsícem", - "few": "před {0} měsíci", - "many": "před {0} měsíce", - }, - }, - "week": { - "future": { - "other": "za {0} týdnů", - "one": "za {0} týden", - "few": "za {0} týdny", - "many": "za {0} týdne", - }, - "past": { - "other": "před {0} týdny", - "one": "před {0} týdnem", - "few": "před {0} týdny", - "many": "před {0} týdne", - }, - }, - "day": { - "future": { - "other": "za {0} dní", - "one": "za {0} den", - "few": "za {0} dny", - "many": "za {0} dne", - }, - "past": { - "other": "před {0} dny", - "one": "před {0} dnem", - "few": "před {0} dny", - "many": "před {0} dne", - }, - }, - "hour": { - "future": { - "other": "za {0} hodin", - "one": "za {0} hodinu", - "few": "za {0} hodiny", - "many": "za {0} hodiny", - }, - "past": { - "other": "před {0} hodinami", - "one": "před {0} hodinou", - "few": "před {0} hodinami", - "many": "před {0} hodiny", - }, - }, - "minute": { - "future": { - "other": "za {0} minut", - "one": "za {0} minutu", - "few": "za {0} minuty", - "many": "za {0} minuty", - }, - "past": { - "other": "před {0} minutami", - "one": "před {0} minutou", - "few": "před {0} minutami", - "many": "před {0} minuty", - }, - }, - "second": { - "future": { - "other": "za {0} sekund", - "one": "za {0} sekundu", - "few": "za {0} sekundy", - "many": "za {0} sekundy", - }, - "past": { - "other": "před {0} sekundami", - "one": "před {0} sekundou", - "few": "před {0} sekundami", - "many": "před {0} sekundy", - }, - }, - }, - "day_periods": { - "midnight": "půlnoc", - "am": "dop.", - "noon": "poledne", - "pm": "odp.", - "morning1": "ráno", - "morning2": "dopoledne", - "afternoon1": "odpoledne", - "evening1": "večer", - "night1": "v noci", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/da/__init__.py b/pendulum/locales/da/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/da/custom.py b/pendulum/locales/da/custom.py deleted file mode 100644 index c62ab83..0000000 --- a/pendulum/locales/da/custom.py +++ /dev/null @@ -1,18 +0,0 @@ -""" -da custom locale file. -""" - -translations = { - # Relative time - "after": "{0} efter", - "before": "{0} før", - # Date formats - "date_formats": { - "LTS": "HH:mm:ss", - "LT": "HH:mm", - "LLLL": "dddd [d.] D. MMMM YYYY HH:mm", - "LLL": "D. MMMM YYYY HH:mm", - "LL": "D. MMMM YYYY", - "L": "DD/MM/YYYY", - }, -} diff --git a/pendulum/locales/da/locale.py b/pendulum/locales/da/locale.py deleted file mode 100644 index 936af3a..0000000 --- a/pendulum/locales/da/locale.py +++ /dev/null @@ -1,147 +0,0 @@ -from .custom import translations as custom_translations - - -""" -da locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "one" - if ( - (n == n and (n == 1)) - or ((not (0 == 0 and (0 == 0))) and (n == n and ((n == 0) or (n == 1)))) - ) - else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "søn.", - 1: "man.", - 2: "tir.", - 3: "ons.", - 4: "tor.", - 5: "fre.", - 6: "lør.", - }, - "narrow": {0: "S", 1: "M", 2: "T", 3: "O", 4: "T", 5: "F", 6: "L"}, - "short": {0: "sø", 1: "ma", 2: "ti", 3: "on", 4: "to", 5: "fr", 6: "lø"}, - "wide": { - 0: "søndag", - 1: "mandag", - 2: "tirsdag", - 3: "onsdag", - 4: "torsdag", - 5: "fredag", - 6: "lørdag", - }, - }, - "months": { - "abbreviated": { - 1: "jan.", - 2: "feb.", - 3: "mar.", - 4: "apr.", - 5: "maj", - 6: "jun.", - 7: "jul.", - 8: "aug.", - 9: "sep.", - 10: "okt.", - 11: "nov.", - 12: "dec.", - }, - "narrow": { - 1: "J", - 2: "F", - 3: "M", - 4: "A", - 5: "M", - 6: "J", - 7: "J", - 8: "A", - 9: "S", - 10: "O", - 11: "N", - 12: "D", - }, - "wide": { - 1: "januar", - 2: "februar", - 3: "marts", - 4: "april", - 5: "maj", - 6: "juni", - 7: "juli", - 8: "august", - 9: "september", - 10: "oktober", - 11: "november", - 12: "december", - }, - }, - "units": { - "year": {"one": "{0} år", "other": "{0} år"}, - "month": {"one": "{0} måned", "other": "{0} måneder"}, - "week": {"one": "{0} uge", "other": "{0} uger"}, - "day": {"one": "{0} dag", "other": "{0} dage"}, - "hour": {"one": "{0} time", "other": "{0} timer"}, - "minute": {"one": "{0} minut", "other": "{0} minutter"}, - "second": {"one": "{0} sekund", "other": "{0} sekunder"}, - "microsecond": {"one": "{0} mikrosekund", "other": "{0} mikrosekunder"}, - }, - "relative": { - "year": { - "future": {"other": "om {0} år", "one": "om {0} år"}, - "past": {"other": "for {0} år siden", "one": "for {0} år siden"}, - }, - "month": { - "future": {"other": "om {0} måneder", "one": "om {0} måned"}, - "past": { - "other": "for {0} måneder siden", - "one": "for {0} måned siden", - }, - }, - "week": { - "future": {"other": "om {0} uger", "one": "om {0} uge"}, - "past": {"other": "for {0} uger siden", "one": "for {0} uge siden"}, - }, - "day": { - "future": {"other": "om {0} dage", "one": "om {0} dag"}, - "past": {"other": "for {0} dage siden", "one": "for {0} dag siden"}, - }, - "hour": { - "future": {"other": "om {0} timer", "one": "om {0} time"}, - "past": {"other": "for {0} timer siden", "one": "for {0} time siden"}, - }, - "minute": { - "future": {"other": "om {0} minutter", "one": "om {0} minut"}, - "past": { - "other": "for {0} minutter siden", - "one": "for {0} minut siden", - }, - }, - "second": { - "future": {"other": "om {0} sekunder", "one": "om {0} sekund"}, - "past": { - "other": "for {0} sekunder siden", - "one": "for {0} sekund siden", - }, - }, - }, - "day_periods": { - "midnight": "midnat", - "am": "AM", - "pm": "PM", - "morning1": "om morgenen", - "morning2": "om formiddagen", - "afternoon1": "om eftermiddagen", - "evening1": "om aftenen", - "night1": "om natten", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/de/__init__.py b/pendulum/locales/de/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/de/custom.py b/pendulum/locales/de/custom.py deleted file mode 100644 index a19a8e1..0000000 --- a/pendulum/locales/de/custom.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -de custom locale file. -""" - -translations = { - # Relative time - "after": "{0} später", - "before": "{0} zuvor", - "units_relative": { - "year": { - "future": {"one": "{0} Jahr", "other": "{0} Jahren"}, - "past": {"one": "{0} Jahr", "other": "{0} Jahren"}, - }, - "month": { - "future": {"one": "{0} Monat", "other": "{0} Monaten"}, - "past": {"one": "{0} Monat", "other": "{0} Monaten"}, - }, - "week": { - "future": {"one": "{0} Woche", "other": "{0} Wochen"}, - "past": {"one": "{0} Woche", "other": "{0} Wochen"}, - }, - "day": { - "future": {"one": "{0} Tag", "other": "{0} Tagen"}, - "past": {"one": "{0} Tag", "other": "{0} Tagen"}, - }, - }, - # Date formats - "date_formats": { - "LTS": "HH:mm:ss", - "LT": "HH:mm", - "LLLL": "dddd, D. MMMM YYYY HH:mm", - "LLL": "D. MMMM YYYY HH:mm", - "LL": "D. MMMM YYYY", - "L": "DD.MM.YYYY", - }, -} diff --git a/pendulum/locales/de/locale.py b/pendulum/locales/de/locale.py deleted file mode 100644 index 94d2ff1..0000000 --- a/pendulum/locales/de/locale.py +++ /dev/null @@ -1,144 +0,0 @@ -from .custom import translations as custom_translations - - -""" -de locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "one" - if ((n == n and (n == 1)) and (0 == 0 and (0 == 0))) - else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "So.", - 1: "Mo.", - 2: "Di.", - 3: "Mi.", - 4: "Do.", - 5: "Fr.", - 6: "Sa.", - }, - "narrow": {0: "S", 1: "M", 2: "D", 3: "M", 4: "D", 5: "F", 6: "S"}, - "short": { - 0: "So.", - 1: "Mo.", - 2: "Di.", - 3: "Mi.", - 4: "Do.", - 5: "Fr.", - 6: "Sa.", - }, - "wide": { - 0: "Sonntag", - 1: "Montag", - 2: "Dienstag", - 3: "Mittwoch", - 4: "Donnerstag", - 5: "Freitag", - 6: "Samstag", - }, - }, - "months": { - "abbreviated": { - 1: "Jan.", - 2: "Feb.", - 3: "März", - 4: "Apr.", - 5: "Mai", - 6: "Juni", - 7: "Juli", - 8: "Aug.", - 9: "Sep.", - 10: "Okt.", - 11: "Nov.", - 12: "Dez.", - }, - "narrow": { - 1: "J", - 2: "F", - 3: "M", - 4: "A", - 5: "M", - 6: "J", - 7: "J", - 8: "A", - 9: "S", - 10: "O", - 11: "N", - 12: "D", - }, - "wide": { - 1: "Januar", - 2: "Februar", - 3: "März", - 4: "April", - 5: "Mai", - 6: "Juni", - 7: "Juli", - 8: "August", - 9: "September", - 10: "Oktober", - 11: "November", - 12: "Dezember", - }, - }, - "units": { - "year": {"one": "{0} Jahr", "other": "{0} Jahre"}, - "month": {"one": "{0} Monat", "other": "{0} Monate"}, - "week": {"one": "{0} Woche", "other": "{0} Wochen"}, - "day": {"one": "{0} Tag", "other": "{0} Tage"}, - "hour": {"one": "{0} Stunde", "other": "{0} Stunden"}, - "minute": {"one": "{0} Minute", "other": "{0} Minuten"}, - "second": {"one": "{0} Sekunde", "other": "{0} Sekunden"}, - "microsecond": {"one": "{0} Mikrosekunde", "other": "{0} Mikrosekunden"}, - }, - "relative": { - "year": { - "future": {"other": "in {0} Jahren", "one": "in {0} Jahr"}, - "past": {"other": "vor {0} Jahren", "one": "vor {0} Jahr"}, - }, - "month": { - "future": {"other": "in {0} Monaten", "one": "in {0} Monat"}, - "past": {"other": "vor {0} Monaten", "one": "vor {0} Monat"}, - }, - "week": { - "future": {"other": "in {0} Wochen", "one": "in {0} Woche"}, - "past": {"other": "vor {0} Wochen", "one": "vor {0} Woche"}, - }, - "day": { - "future": {"other": "in {0} Tagen", "one": "in {0} Tag"}, - "past": {"other": "vor {0} Tagen", "one": "vor {0} Tag"}, - }, - "hour": { - "future": {"other": "in {0} Stunden", "one": "in {0} Stunde"}, - "past": {"other": "vor {0} Stunden", "one": "vor {0} Stunde"}, - }, - "minute": { - "future": {"other": "in {0} Minuten", "one": "in {0} Minute"}, - "past": {"other": "vor {0} Minuten", "one": "vor {0} Minute"}, - }, - "second": { - "future": {"other": "in {0} Sekunden", "one": "in {0} Sekunde"}, - "past": {"other": "vor {0} Sekunden", "one": "vor {0} Sekunde"}, - }, - }, - "day_periods": { - "midnight": "Mitternacht", - "am": "vorm.", - "pm": "nachm.", - "morning1": "morgens", - "morning2": "vormittags", - "afternoon1": "mittags", - "afternoon2": "nachmittags", - "evening1": "abends", - "night1": "nachts", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/en/__init__.py b/pendulum/locales/en/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/en/custom.py b/pendulum/locales/en/custom.py deleted file mode 100644 index a403ad8..0000000 --- a/pendulum/locales/en/custom.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -en custom locale file. -""" - -translations = { - "units": {"few_second": "a few seconds"}, - # Relative time - "ago": "{} ago", - "from_now": "in {}", - "after": "{0} after", - "before": "{0} before", - # Ordinals - "ordinal": {"one": "st", "two": "nd", "few": "rd", "other": "th"}, - # Date formats - "date_formats": { - "LTS": "h:mm:ss A", - "LT": "h:mm A", - "L": "MM/DD/YYYY", - "LL": "MMMM D, YYYY", - "LLL": "MMMM D, YYYY h:mm A", - "LLLL": "dddd, MMMM D, YYYY h:mm A", - }, -} diff --git a/pendulum/locales/en/locale.py b/pendulum/locales/en/locale.py deleted file mode 100644 index 00eafc2..0000000 --- a/pendulum/locales/en/locale.py +++ /dev/null @@ -1,150 +0,0 @@ -from .custom import translations as custom_translations - - -""" -en locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "one" - if ((n == n and (n == 1)) and (0 == 0 and (0 == 0))) - else "other", - "ordinal": lambda n: "few" - if ( - ((n % 10) == (n % 10) and ((n % 10) == 3)) - and (not ((n % 100) == (n % 100) and ((n % 100) == 13))) - ) - else "one" - if ( - ((n % 10) == (n % 10) and ((n % 10) == 1)) - and (not ((n % 100) == (n % 100) and ((n % 100) == 11))) - ) - else "two" - if ( - ((n % 10) == (n % 10) and ((n % 10) == 2)) - and (not ((n % 100) == (n % 100) and ((n % 100) == 12))) - ) - else "other", - "translations": { - "days": { - "abbreviated": { - 0: "Sun", - 1: "Mon", - 2: "Tue", - 3: "Wed", - 4: "Thu", - 5: "Fri", - 6: "Sat", - }, - "narrow": {0: "S", 1: "M", 2: "T", 3: "W", 4: "T", 5: "F", 6: "S"}, - "short": {0: "Su", 1: "Mo", 2: "Tu", 3: "We", 4: "Th", 5: "Fr", 6: "Sa"}, - "wide": { - 0: "Sunday", - 1: "Monday", - 2: "Tuesday", - 3: "Wednesday", - 4: "Thursday", - 5: "Friday", - 6: "Saturday", - }, - }, - "months": { - "abbreviated": { - 1: "Jan", - 2: "Feb", - 3: "Mar", - 4: "Apr", - 5: "May", - 6: "Jun", - 7: "Jul", - 8: "Aug", - 9: "Sep", - 10: "Oct", - 11: "Nov", - 12: "Dec", - }, - "narrow": { - 1: "J", - 2: "F", - 3: "M", - 4: "A", - 5: "M", - 6: "J", - 7: "J", - 8: "A", - 9: "S", - 10: "O", - 11: "N", - 12: "D", - }, - "wide": { - 1: "January", - 2: "February", - 3: "March", - 4: "April", - 5: "May", - 6: "June", - 7: "July", - 8: "August", - 9: "September", - 10: "October", - 11: "November", - 12: "December", - }, - }, - "units": { - "year": {"one": "{0} year", "other": "{0} years"}, - "month": {"one": "{0} month", "other": "{0} months"}, - "week": {"one": "{0} week", "other": "{0} weeks"}, - "day": {"one": "{0} day", "other": "{0} days"}, - "hour": {"one": "{0} hour", "other": "{0} hours"}, - "minute": {"one": "{0} minute", "other": "{0} minutes"}, - "second": {"one": "{0} second", "other": "{0} seconds"}, - "microsecond": {"one": "{0} microsecond", "other": "{0} microseconds"}, - }, - "relative": { - "year": { - "future": {"other": "in {0} years", "one": "in {0} year"}, - "past": {"other": "{0} years ago", "one": "{0} year ago"}, - }, - "month": { - "future": {"other": "in {0} months", "one": "in {0} month"}, - "past": {"other": "{0} months ago", "one": "{0} month ago"}, - }, - "week": { - "future": {"other": "in {0} weeks", "one": "in {0} week"}, - "past": {"other": "{0} weeks ago", "one": "{0} week ago"}, - }, - "day": { - "future": {"other": "in {0} days", "one": "in {0} day"}, - "past": {"other": "{0} days ago", "one": "{0} day ago"}, - }, - "hour": { - "future": {"other": "in {0} hours", "one": "in {0} hour"}, - "past": {"other": "{0} hours ago", "one": "{0} hour ago"}, - }, - "minute": { - "future": {"other": "in {0} minutes", "one": "in {0} minute"}, - "past": {"other": "{0} minutes ago", "one": "{0} minute ago"}, - }, - "second": { - "future": {"other": "in {0} seconds", "one": "in {0} second"}, - "past": {"other": "{0} seconds ago", "one": "{0} second ago"}, - }, - }, - "day_periods": { - "midnight": "midnight", - "am": "AM", - "noon": "noon", - "pm": "PM", - "morning1": "in the morning", - "afternoon1": "in the afternoon", - "evening1": "in the evening", - "night1": "at night", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/es/__init__.py b/pendulum/locales/es/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/es/custom.py b/pendulum/locales/es/custom.py deleted file mode 100644 index 4b7e2b5..0000000 --- a/pendulum/locales/es/custom.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -es custom locale file. -""" - -translations = { - "units": {"few_second": "unos segundos"}, - # Relative time - "ago": "hace {0}", - "from_now": "dentro de {0}", - "after": "{0} después", - "before": "{0} antes", - # Ordinals - "ordinal": {"other": "º"}, - # Date formats - "date_formats": { - "LTS": "H:mm:ss", - "LT": "H:mm", - "LLLL": "dddd, D [de] MMMM [de] YYYY H:mm", - "LLL": "D [de] MMMM [de] YYYY H:mm", - "LL": "D [de] MMMM [de] YYYY", - "L": "DD/MM/YYYY", - }, -} diff --git a/pendulum/locales/es/locale.py b/pendulum/locales/es/locale.py deleted file mode 100644 index edba4d3..0000000 --- a/pendulum/locales/es/locale.py +++ /dev/null @@ -1,141 +0,0 @@ -from .custom import translations as custom_translations - - -""" -es locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "one" if (n == n and (n == 1)) else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "dom.", - 1: "lun.", - 2: "mar.", - 3: "mié.", - 4: "jue.", - 5: "vie.", - 6: "sáb.", - }, - "narrow": {0: "D", 1: "L", 2: "M", 3: "X", 4: "J", 5: "V", 6: "S"}, - "short": {0: "DO", 1: "LU", 2: "MA", 3: "MI", 4: "JU", 5: "VI", 6: "SA"}, - "wide": { - 0: "domingo", - 1: "lunes", - 2: "martes", - 3: "miércoles", - 4: "jueves", - 5: "viernes", - 6: "sábado", - }, - }, - "months": { - "abbreviated": { - 1: "ene.", - 2: "feb.", - 3: "mar.", - 4: "abr.", - 5: "may.", - 6: "jun.", - 7: "jul.", - 8: "ago.", - 9: "sept.", - 10: "oct.", - 11: "nov.", - 12: "dic.", - }, - "narrow": { - 1: "E", - 2: "F", - 3: "M", - 4: "A", - 5: "M", - 6: "J", - 7: "J", - 8: "A", - 9: "S", - 10: "O", - 11: "N", - 12: "D", - }, - "wide": { - 1: "enero", - 2: "febrero", - 3: "marzo", - 4: "abril", - 5: "mayo", - 6: "junio", - 7: "julio", - 8: "agosto", - 9: "septiembre", - 10: "octubre", - 11: "noviembre", - 12: "diciembre", - }, - }, - "units": { - "year": {"one": "{0} año", "other": "{0} años"}, - "month": {"one": "{0} mes", "other": "{0} meses"}, - "week": {"one": "{0} semana", "other": "{0} semanas"}, - "day": {"one": "{0} día", "other": "{0} días"}, - "hour": {"one": "{0} hora", "other": "{0} horas"}, - "minute": {"one": "{0} minuto", "other": "{0} minutos"}, - "second": {"one": "{0} segundo", "other": "{0} segundos"}, - "microsecond": {"one": "{0} microsegundo", "other": "{0} microsegundos"}, - }, - "relative": { - "year": { - "future": {"other": "dentro de {0} años", "one": "dentro de {0} año"}, - "past": {"other": "hace {0} años", "one": "hace {0} año"}, - }, - "month": { - "future": {"other": "dentro de {0} meses", "one": "dentro de {0} mes"}, - "past": {"other": "hace {0} meses", "one": "hace {0} mes"}, - }, - "week": { - "future": { - "other": "dentro de {0} semanas", - "one": "dentro de {0} semana", - }, - "past": {"other": "hace {0} semanas", "one": "hace {0} semana"}, - }, - "day": { - "future": {"other": "dentro de {0} días", "one": "dentro de {0} día"}, - "past": {"other": "hace {0} días", "one": "hace {0} día"}, - }, - "hour": { - "future": {"other": "dentro de {0} horas", "one": "dentro de {0} hora"}, - "past": {"other": "hace {0} horas", "one": "hace {0} hora"}, - }, - "minute": { - "future": { - "other": "dentro de {0} minutos", - "one": "dentro de {0} minuto", - }, - "past": {"other": "hace {0} minutos", "one": "hace {0} minuto"}, - }, - "second": { - "future": { - "other": "dentro de {0} segundos", - "one": "dentro de {0} segundo", - }, - "past": {"other": "hace {0} segundos", "one": "hace {0} segundo"}, - }, - }, - "day_periods": { - "am": "a. m.", - "noon": "del mediodía", - "pm": "p. m.", - "morning1": "de la madrugada", - "morning2": "de la mañana", - "evening1": "de la tarde", - "night1": "de la noche", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/fa/__init__.py b/pendulum/locales/fa/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/fa/custom.py b/pendulum/locales/fa/custom.py deleted file mode 100644 index 082bfad..0000000 --- a/pendulum/locales/fa/custom.py +++ /dev/null @@ -1,18 +0,0 @@ -""" -fa custom locale file. -""" - -translations = { - # Relative time - "after": "{0} پس از", - "before": "{0} پیش از", - # Date formats - "date_formats": { - "LTS": "HH:mm:ss", - "LT": "HH:mm", - "LLLL": "dddd, D MMMM YYYY HH:mm", - "LLL": "D MMMM YYYY HH:mm", - "LL": "D MMMM YYYY", - "L": "DD/MM/YYYY", - }, -} diff --git a/pendulum/locales/fa/locale.py b/pendulum/locales/fa/locale.py deleted file mode 100644 index 32f8e5f..0000000 --- a/pendulum/locales/fa/locale.py +++ /dev/null @@ -1,135 +0,0 @@ -from .custom import translations as custom_translations - - -""" -fa locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "one" - if ((n == n and (n == 0)) or (n == n and (n == 1))) - else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "یکشنبه", - 1: "دوشنبه", - 2: "سه\u200cشنبه", - 3: "چهارشنبه", - 4: "پنجشنبه", - 5: "جمعه", - 6: "شنبه", - }, - "narrow": {0: "ی", 1: "د", 2: "س", 3: "چ", 4: "پ", 5: "ج", 6: "ش"}, - "short": {0: "۱ش", 1: "۲ش", 2: "۳ش", 3: "۴ش", 4: "۵ش", 5: "ج", 6: "ش"}, - "wide": { - 0: "یکشنبه", - 1: "دوشنبه", - 2: "سه\u200cشنبه", - 3: "چهارشنبه", - 4: "پنجشنبه", - 5: "جمعه", - 6: "شنبه", - }, - }, - "months": { - "abbreviated": { - 1: "ژانویهٔ", - 2: "فوریهٔ", - 3: "مارس", - 4: "آوریل", - 5: "مهٔ", - 6: "ژوئن", - 7: "ژوئیهٔ", - 8: "اوت", - 9: "سپتامبر", - 10: "اکتبر", - 11: "نوامبر", - 12: "دسامبر", - }, - "narrow": { - 1: "ژ", - 2: "ف", - 3: "م", - 4: "آ", - 5: "م", - 6: "ژ", - 7: "ژ", - 8: "ا", - 9: "س", - 10: "ا", - 11: "ن", - 12: "د", - }, - "wide": { - 1: "ژانویهٔ", - 2: "فوریهٔ", - 3: "مارس", - 4: "آوریل", - 5: "مهٔ", - 6: "ژوئن", - 7: "ژوئیهٔ", - 8: "اوت", - 9: "سپتامبر", - 10: "اکتبر", - 11: "نوامبر", - 12: "دسامبر", - }, - }, - "units": { - "year": {"one": "{0} سال", "other": "{0} سال"}, - "month": {"one": "{0} ماه", "other": "{0} ماه"}, - "week": {"one": "{0} هفته", "other": "{0} هفته"}, - "day": {"one": "{0} روز", "other": "{0} روز"}, - "hour": {"one": "{0} ساعت", "other": "{0} ساعت"}, - "minute": {"one": "{0} دقیقه", "other": "{0} دقیقه"}, - "second": {"one": "{0} ثانیه", "other": "{0} ثانیه"}, - "microsecond": {"one": "{0} میکروثانیه", "other": "{0} میکروثانیه"}, - }, - "relative": { - "year": { - "future": {"other": "{0} سال بعد", "one": "{0} سال بعد"}, - "past": {"other": "{0} سال پیش", "one": "{0} سال پیش"}, - }, - "month": { - "future": {"other": "{0} ماه بعد", "one": "{0} ماه بعد"}, - "past": {"other": "{0} ماه پیش", "one": "{0} ماه پیش"}, - }, - "week": { - "future": {"other": "{0} هفته بعد", "one": "{0} هفته بعد"}, - "past": {"other": "{0} هفته پیش", "one": "{0} هفته پیش"}, - }, - "day": { - "future": {"other": "{0} روز بعد", "one": "{0} روز بعد"}, - "past": {"other": "{0} روز پیش", "one": "{0} روز پیش"}, - }, - "hour": { - "future": {"other": "{0} ساعت بعد", "one": "{0} ساعت بعد"}, - "past": {"other": "{0} ساعت پیش", "one": "{0} ساعت پیش"}, - }, - "minute": { - "future": {"other": "{0} دقیقه بعد", "one": "{0} دقیقه بعد"}, - "past": {"other": "{0} دقیقه پیش", "one": "{0} دقیقه پیش"}, - }, - "second": { - "future": {"other": "{0} ثانیه بعد", "one": "{0} ثانیه بعد"}, - "past": {"other": "{0} ثانیه پیش", "one": "{0} ثانیه پیش"}, - }, - }, - "day_periods": { - "midnight": "نیمه\u200cشب", - "am": "قبل\u200cازظهر", - "noon": "ظهر", - "pm": "بعدازظهر", - "morning1": "صبح", - "afternoon1": "عصر", - "evening1": "عصر", - "night1": "شب", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/fo/__init__.py b/pendulum/locales/fo/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/fo/custom.py b/pendulum/locales/fo/custom.py deleted file mode 100644 index 456dd59..0000000 --- a/pendulum/locales/fo/custom.py +++ /dev/null @@ -1,20 +0,0 @@ -""" -fo custom locale file. -""" - -translations = { - # Relative time - "after": "{0} aftaná", - "before": "{0} áðrenn", - # Ordinals - "ordinal": {"other": "."}, - # Date formats - "date_formats": { - "LTS": "HH:mm:ss", - "LT": "HH:mm", - "LLLL": "dddd D. MMMM, YYYY HH:mm", - "LLL": "D MMMM YYYY HH:mm", - "LL": "D MMMM YYYY", - "L": "DD/MM/YYYY", - }, -} diff --git a/pendulum/locales/fo/locale.py b/pendulum/locales/fo/locale.py deleted file mode 100644 index 10319ea..0000000 --- a/pendulum/locales/fo/locale.py +++ /dev/null @@ -1,132 +0,0 @@ -from .custom import translations as custom_translations - - -""" -fo locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "one" if (n == n and (n == 1)) else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "sun.", - 1: "mán.", - 2: "týs.", - 3: "mik.", - 4: "hós.", - 5: "frí.", - 6: "ley.", - }, - "narrow": {0: "S", 1: "M", 2: "T", 3: "M", 4: "H", 5: "F", 6: "L"}, - "short": { - 0: "su.", - 1: "má.", - 2: "tý.", - 3: "mi.", - 4: "hó.", - 5: "fr.", - 6: "le.", - }, - "wide": { - 0: "sunnudagur", - 1: "mánadagur", - 2: "týsdagur", - 3: "mikudagur", - 4: "hósdagur", - 5: "fríggjadagur", - 6: "leygardagur", - }, - }, - "months": { - "abbreviated": { - 1: "jan.", - 2: "feb.", - 3: "mar.", - 4: "apr.", - 5: "mai", - 6: "jun.", - 7: "jul.", - 8: "aug.", - 9: "sep.", - 10: "okt.", - 11: "nov.", - 12: "des.", - }, - "narrow": { - 1: "J", - 2: "F", - 3: "M", - 4: "A", - 5: "M", - 6: "J", - 7: "J", - 8: "A", - 9: "S", - 10: "O", - 11: "N", - 12: "D", - }, - "wide": { - 1: "januar", - 2: "februar", - 3: "mars", - 4: "apríl", - 5: "mai", - 6: "juni", - 7: "juli", - 8: "august", - 9: "september", - 10: "oktober", - 11: "november", - 12: "desember", - }, - }, - "units": { - "year": {"one": "{0} ár", "other": "{0} ár"}, - "month": {"one": "{0} mánaður", "other": "{0} mánaðir"}, - "week": {"one": "{0} vika", "other": "{0} vikur"}, - "day": {"one": "{0} dagur", "other": "{0} dagar"}, - "hour": {"one": "{0} tími", "other": "{0} tímar"}, - "minute": {"one": "{0} minuttur", "other": "{0} minuttir"}, - "second": {"one": "{0} sekund", "other": "{0} sekundir"}, - "microsecond": {"one": "{0} mikrosekund", "other": "{0} mikrosekundir"}, - }, - "relative": { - "year": { - "future": {"other": "um {0} ár", "one": "um {0} ár"}, - "past": {"other": "{0} ár síðan", "one": "{0} ár síðan"}, - }, - "month": { - "future": {"other": "um {0} mánaðir", "one": "um {0} mánað"}, - "past": {"other": "{0} mánaðir síðan", "one": "{0} mánað síðan"}, - }, - "week": { - "future": {"other": "um {0} vikur", "one": "um {0} viku"}, - "past": {"other": "{0} vikur síðan", "one": "{0} vika síðan"}, - }, - "day": { - "future": {"other": "um {0} dagar", "one": "um {0} dag"}, - "past": {"other": "{0} dagar síðan", "one": "{0} dagur síðan"}, - }, - "hour": { - "future": {"other": "um {0} tímar", "one": "um {0} tíma"}, - "past": {"other": "{0} tímar síðan", "one": "{0} tími síðan"}, - }, - "minute": { - "future": {"other": "um {0} minuttir", "one": "um {0} minutt"}, - "past": {"other": "{0} minuttir síðan", "one": "{0} minutt síðan"}, - }, - "second": { - "future": {"other": "um {0} sekund", "one": "um {0} sekund"}, - "past": {"other": "{0} sekund síðan", "one": "{0} sekund síðan"}, - }, - }, - "day_periods": {"am": "AM", "pm": "PM"}, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/fr/__init__.py b/pendulum/locales/fr/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/fr/custom.py b/pendulum/locales/fr/custom.py deleted file mode 100644 index 134f297..0000000 --- a/pendulum/locales/fr/custom.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -fr custom locale file. -""" - -translations = { - "units": {"few_second": "quelques secondes"}, - # Relative Time - "ago": "il y a {0}", - "from_now": "dans {0}", - "after": "{0} après", - "before": "{0} avant", - # Ordinals - "ordinal": {"one": "er", "other": "e"}, - # Date formats - "date_formats": { - "LTS": "HH:mm:ss", - "LT": "HH:mm", - "LLLL": "dddd D MMMM YYYY HH:mm", - "LLL": "D MMMM YYYY HH:mm", - "LL": "D MMMM YYYY", - "L": "DD/MM/YYYY", - }, -} diff --git a/pendulum/locales/fr/locale.py b/pendulum/locales/fr/locale.py deleted file mode 100644 index 8855d53..0000000 --- a/pendulum/locales/fr/locale.py +++ /dev/null @@ -1,133 +0,0 @@ -from .custom import translations as custom_translations - - -""" -fr locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "one" if (n == n and ((n == 0) or (n == 1))) else "other", - "ordinal": lambda n: "one" if (n == n and (n == 1)) else "other", - "translations": { - "days": { - "abbreviated": { - 0: "dim.", - 1: "lun.", - 2: "mar.", - 3: "mer.", - 4: "jeu.", - 5: "ven.", - 6: "sam.", - }, - "narrow": {0: "D", 1: "L", 2: "M", 3: "M", 4: "J", 5: "V", 6: "S"}, - "short": {0: "di", 1: "lu", 2: "ma", 3: "me", 4: "je", 5: "ve", 6: "sa"}, - "wide": { - 0: "dimanche", - 1: "lundi", - 2: "mardi", - 3: "mercredi", - 4: "jeudi", - 5: "vendredi", - 6: "samedi", - }, - }, - "months": { - "abbreviated": { - 1: "janv.", - 2: "févr.", - 3: "mars", - 4: "avr.", - 5: "mai", - 6: "juin", - 7: "juil.", - 8: "août", - 9: "sept.", - 10: "oct.", - 11: "nov.", - 12: "déc.", - }, - "narrow": { - 1: "J", - 2: "F", - 3: "M", - 4: "A", - 5: "M", - 6: "J", - 7: "J", - 8: "A", - 9: "S", - 10: "O", - 11: "N", - 12: "D", - }, - "wide": { - 1: "janvier", - 2: "février", - 3: "mars", - 4: "avril", - 5: "mai", - 6: "juin", - 7: "juillet", - 8: "août", - 9: "septembre", - 10: "octobre", - 11: "novembre", - 12: "décembre", - }, - }, - "units": { - "year": {"one": "{0} an", "other": "{0} ans"}, - "month": {"one": "{0} mois", "other": "{0} mois"}, - "week": {"one": "{0} semaine", "other": "{0} semaines"}, - "day": {"one": "{0} jour", "other": "{0} jours"}, - "hour": {"one": "{0} heure", "other": "{0} heures"}, - "minute": {"one": "{0} minute", "other": "{0} minutes"}, - "second": {"one": "{0} seconde", "other": "{0} secondes"}, - "microsecond": {"one": "{0} microseconde", "other": "{0} microsecondes"}, - }, - "relative": { - "year": { - "future": {"other": "dans {0} ans", "one": "dans {0} an"}, - "past": {"other": "il y a {0} ans", "one": "il y a {0} an"}, - }, - "month": { - "future": {"other": "dans {0} mois", "one": "dans {0} mois"}, - "past": {"other": "il y a {0} mois", "one": "il y a {0} mois"}, - }, - "week": { - "future": {"other": "dans {0} semaines", "one": "dans {0} semaine"}, - "past": {"other": "il y a {0} semaines", "one": "il y a {0} semaine"}, - }, - "day": { - "future": {"other": "dans {0} jours", "one": "dans {0} jour"}, - "past": {"other": "il y a {0} jours", "one": "il y a {0} jour"}, - }, - "hour": { - "future": {"other": "dans {0} heures", "one": "dans {0} heure"}, - "past": {"other": "il y a {0} heures", "one": "il y a {0} heure"}, - }, - "minute": { - "future": {"other": "dans {0} minutes", "one": "dans {0} minute"}, - "past": {"other": "il y a {0} minutes", "one": "il y a {0} minute"}, - }, - "second": { - "future": {"other": "dans {0} secondes", "one": "dans {0} seconde"}, - "past": {"other": "il y a {0} secondes", "one": "il y a {0} seconde"}, - }, - }, - "day_periods": { - "midnight": "minuit", - "am": "AM", - "noon": "midi", - "pm": "PM", - "morning1": "du matin", - "afternoon1": "de l’après-midi", - "evening1": "du soir", - "night1": "de nuit", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/he/__init__.py b/pendulum/locales/he/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/he/custom.py b/pendulum/locales/he/custom.py deleted file mode 100644 index 51f8476..0000000 --- a/pendulum/locales/he/custom.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -he custom locale file. -""" - -translations = { - "units": {"few_second": "כמה שניות"}, - # Relative time - "ago": "לפני {0}", - "from_now": "תוך {0}", - "after": "בעוד {0}", - "before": "{0} קודם", - # Ordinals - "ordinal": {"other": "º"}, - # Date formats - "date_formats": { - "LTS": "H:mm:ss", - "LT": "H:mm", - "LLLL": "dddd, D [ב] MMMM [ב] YYYY H:mm", - "LLL": "D [ב] MMMM [ב] YYYY H:mm", - "LL": "D [ב] MMMM [ב] YYYY", - "L": "DD/MM/YYYY", - }, -} diff --git a/pendulum/locales/he/locale.py b/pendulum/locales/he/locale.py deleted file mode 100644 index 457c101..0000000 --- a/pendulum/locales/he/locale.py +++ /dev/null @@ -1,269 +0,0 @@ -from .custom import translations as custom_translations - - -""" -he locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "many" - if ( - ((0 == 0 and (0 == 0)) and (not (n == n and (n >= 0 and n <= 10)))) - and ((n % 10) == (n % 10) and ((n % 10) == 0)) - ) - else "one" - if ((n == n and (n == 1)) and (0 == 0 and (0 == 0))) - else "two" - if ((n == n and (n == 2)) and (0 == 0 and (0 == 0))) - else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "יום א׳", - 1: "יום ב׳", - 2: "יום ג׳", - 3: "יום ד׳", - 4: "יום ה׳", - 5: "יום ו׳", - 6: "שבת", - }, - "narrow": { - 0: "א׳", - 1: "ב׳", - 2: "ג׳", - 3: "ד׳", - 4: "ה׳", - 5: "ו׳", - 6: "ש׳", - }, - "short": { - 0: "א׳", - 1: "ב׳", - 2: "ג׳", - 3: "ד׳", - 4: "ה׳", - 5: "ו׳", - 6: "ש׳", - }, - "wide": { - 0: "יום ראשון", - 1: "יום שני", - 2: "יום שלישי", - 3: "יום רביעי", - 4: "יום חמישי", - 5: "יום שישי", - 6: "יום שבת", - }, - }, - "months": { - "abbreviated": { - 1: "ינו׳", - 2: "פבר׳", - 3: "מרץ", - 4: "אפר׳", - 5: "מאי", - 6: "יוני", - 7: "יולי", - 8: "אוג׳", - 9: "ספט׳", - 10: "אוק׳", - 11: "נוב׳", - 12: "דצמ׳", - }, - "narrow": { - 1: "1", - 2: "2", - 3: "3", - 4: "4", - 5: "5", - 6: "6", - 7: "7", - 8: "8", - 9: "9", - 10: "10", - 11: "11", - 12: "12", - }, - "wide": { - 1: "ינואר", - 2: "פברואר", - 3: "מרץ", - 4: "אפריל", - 5: "מאי", - 6: "יוני", - 7: "יולי", - 8: "אוגוסט", - 9: "ספטמבר", - 10: "אוקטובר", - 11: "נובמבר", - 12: "דצמבר", - }, - }, - "units": { - "year": { - "one": "שנה", - "two": "שנתיים", - "many": "{0} שנים", - "other": "{0} שנים", - }, - "month": { - "one": "חודש", - "two": "חודשיים", - "many": "{0} חודשים", - "other": "{0} חודשים", - }, - "week": { - "one": "שבוע", - "two": "שבועיים", - "many": "{0} שבועות", - "other": "{0} שבועות", - }, - "day": { - "one": "יום {0}", - "two": "יומיים", - "many": "{0} יום", - "other": "{0} ימים", - }, - "hour": { - "one": "שעה", - "two": "שעתיים", - "many": "{0} שעות", - "other": "{0} שעות", - }, - "minute": { - "one": "דקה", - "two": "שתי דקות", - "many": "{0} דקות", - "other": "{0} דקות", - }, - "second": { - "one": "שניה", - "two": "שתי שניות", - "many": "\u200f{0} שניות", - "other": "{0} שניות", - }, - "microsecond": { - "one": "{0} מיליונית שנייה", - "two": "{0} מיליוניות שנייה", - "many": "{0} מיליוניות שנייה", - "other": "{0} מיליוניות שנייה", - }, - }, - "relative": { - "year": { - "future": { - "other": "בעוד {0} שנים", - "one": "בעוד שנה", - "two": "בעוד שנתיים", - "many": "בעוד {0} שנה", - }, - "past": { - "other": "לפני {0} שנים", - "one": "לפני שנה", - "two": "לפני שנתיים", - "many": "לפני {0} שנה", - }, - }, - "month": { - "future": { - "other": "בעוד {0} חודשים", - "one": "בעוד חודש", - "two": "בעוד חודשיים", - "many": "בעוד {0} חודשים", - }, - "past": { - "other": "לפני {0} חודשים", - "one": "לפני חודש", - "two": "לפני חודשיים", - "many": "לפני {0} חודשים", - }, - }, - "week": { - "future": { - "other": "בעוד {0} שבועות", - "one": "בעוד שבוע", - "two": "בעוד שבועיים", - "many": "בעוד {0} שבועות", - }, - "past": { - "other": "לפני {0} שבועות", - "one": "לפני שבוע", - "two": "לפני שבועיים", - "many": "לפני {0} שבועות", - }, - }, - "day": { - "future": { - "other": "בעוד {0} ימים", - "one": "בעוד יום {0}", - "two": "בעוד יומיים", - "many": "בעוד {0} ימים", - }, - "past": { - "other": "לפני {0} ימים", - "one": "לפני יום {0}", - "two": "לפני יומיים", - "many": "לפני {0} ימים", - }, - }, - "hour": { - "future": { - "other": "בעוד {0} שעות", - "one": "בעוד שעה", - "two": "בעוד שעתיים", - "many": "בעוד {0} שעות", - }, - "past": { - "other": "לפני {0} שעות", - "one": "לפני שעה", - "two": "לפני שעתיים", - "many": "לפני {0} שעות", - }, - }, - "minute": { - "future": { - "other": "בעוד {0} דקות", - "one": "בעוד דקה", - "two": "בעוד שתי דקות", - "many": "בעוד {0} דקות", - }, - "past": { - "other": "לפני {0} דקות", - "one": "לפני דקה", - "two": "לפני שתי דקות", - "many": "לפני {0} דקות", - }, - }, - "second": { - "future": { - "other": "בעוד {0} שניות", - "one": "בעוד שנייה", - "two": "בעוד שתי שניות", - "many": "בעוד {0} שניות", - }, - "past": { - "other": "לפני {0} שניות", - "one": "לפני שנייה", - "two": "לפני שתי שניות", - "many": "לפני {0} שניות", - }, - }, - }, - "day_periods": { - "midnight": "חצות", - "am": "לפנה״צ", - "pm": "אחה״צ", - "morning1": "בבוקר", - "afternoon1": "בצהריים", - "afternoon2": "אחר הצהריים", - "evening1": "בערב", - "night1": "בלילה", - "night2": "לפנות בוקר", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/id/__init__.py b/pendulum/locales/id/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/id/custom.py b/pendulum/locales/id/custom.py deleted file mode 100644 index 3ba2035..0000000 --- a/pendulum/locales/id/custom.py +++ /dev/null @@ -1,19 +0,0 @@ -""" -id custom locale file. -""" - -translations = { - "units": {"few_second": "beberapa detik"}, - "ago": "{} yang lalu", - "from_now": "dalam {}", - "after": "{0} kemudian", - "before": "{0} yang lalu", - "date_formats": { - "LTS": "HH:mm:ss", - "LT": "HH:mm", - "LLLL": "dddd [d.] D. MMMM YYYY HH:mm", - "LLL": "D. MMMM YYYY HH:mm", - "LL": "D. MMMM YYYY", - "L": "DD/MM/YYYY", - }, -} diff --git a/pendulum/locales/id/locale.py b/pendulum/locales/id/locale.py deleted file mode 100644 index bc994ce..0000000 --- a/pendulum/locales/id/locale.py +++ /dev/null @@ -1,141 +0,0 @@ -from .custom import translations as custom_translations - - -""" -id locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "Min", - 1: "Sen", - 2: "Sel", - 3: "Rab", - 4: "Kam", - 5: "Jum", - 6: "Sab", - }, - "narrow": {0: "M", 1: "S", 2: "S", 3: "R", 4: "K", 5: "J", 6: "S"}, - "short": { - 0: "Min", - 1: "Sen", - 2: "Sel", - 3: "Rab", - 4: "Kam", - 5: "Jum", - 6: "Sab", - }, - "wide": { - 0: "Minggu", - 1: "Senin", - 2: "Selasa", - 3: "Rabu", - 4: "Kamis", - 5: "Jumat", - 6: "Sabtu", - }, - }, - "months": { - "abbreviated": { - 1: "Jan", - 2: "Feb", - 3: "Mar", - 4: "Apr", - 5: "Mei", - 6: "Jun", - 7: "Jul", - 8: "Agt", - 9: "Sep", - 10: "Okt", - 11: "Nov", - 12: "Des", - }, - "narrow": { - 1: "J", - 2: "F", - 3: "M", - 4: "A", - 5: "M", - 6: "J", - 7: "J", - 8: "A", - 9: "S", - 10: "O", - 11: "N", - 12: "D", - }, - "wide": { - 1: "Januari", - 2: "Februari", - 3: "Maret", - 4: "April", - 5: "Mei", - 6: "Juni", - 7: "Juli", - 8: "Agustus", - 9: "September", - 10: "Oktober", - 11: "November", - 12: "Desember", - }, - }, - "units": { - "year": {"other": "{0} tahun"}, - "month": {"other": "{0} bulan"}, - "week": {"other": "{0} minggu"}, - "day": {"other": "{0} hari"}, - "hour": {"other": "{0} jam"}, - "minute": {"other": "{0} menit"}, - "second": {"other": "{0} detik"}, - "microsecond": {"other": "{0} mikrodetik"}, - }, - "relative": { - "year": { - "future": {"other": "dalam {0} tahun"}, - "past": {"other": "{0} tahun yang lalu"}, - }, - "month": { - "future": {"other": "dalam {0} bulan"}, - "past": {"other": "{0} bulan yang lalu"}, - }, - "week": { - "future": {"other": "dalam {0} minggu"}, - "past": {"other": "{0} minggu yang lalu"}, - }, - "day": { - "future": {"other": "dalam {0} hari"}, - "past": {"other": "{0} hari yang lalu"}, - }, - "hour": { - "future": {"other": "dalam {0} jam"}, - "past": {"other": "{0} jam yang lalu"}, - }, - "minute": { - "future": {"other": "dalam {0} menit"}, - "past": {"other": "{0} menit yang lalu"}, - }, - "second": { - "future": {"other": "dalam {0} detik"}, - "past": {"other": "{0} detik yang lalu"}, - }, - }, - "day_periods": { - "midnight": "tengah malam", - "am": "AM", - "noon": "tengah hari", - "pm": "PM", - "morning1": "pagi", - "afternoon1": "siang", - "evening1": "sore", - "night1": "malam", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/it/__init__.py b/pendulum/locales/it/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/it/custom.py b/pendulum/locales/it/custom.py deleted file mode 100644 index e5cf1cc..0000000 --- a/pendulum/locales/it/custom.py +++ /dev/null @@ -1,24 +0,0 @@ -""" -it custom locale file. -""" - - -translations = { - "units": {"few_second": "alcuni secondi"}, - # Relative Time - "ago": "{0} fa", - "from_now": "in {0}", - "after": "{0} dopo", - "before": "{0} prima", - # Ordinals - "ordinal": {"other": "°"}, - # Date formats - "date_formats": { - "LTS": "H:mm:ss", - "LT": "H:mm", - "L": "DD/MM/YYYY", - "LL": "D MMMM YYYY", - "LLL": "D MMMM YYYY [alle] H:mm", - "LLLL": "dddd, D MMMM YYYY [alle] H:mm", - }, -} diff --git a/pendulum/locales/it/locale.py b/pendulum/locales/it/locale.py deleted file mode 100644 index bb3fdcf..0000000 --- a/pendulum/locales/it/locale.py +++ /dev/null @@ -1,145 +0,0 @@ -from .custom import translations as custom_translations - - -""" -it locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "one" - if ((n == n and (n == 1)) and (0 == 0 and (0 == 0))) - else "other", - "ordinal": lambda n: "many" - if (n == n and ((n == 11) or (n == 8) or (n == 80) or (n == 800))) - else "other", - "translations": { - "days": { - "abbreviated": { - 0: "dom", - 1: "lun", - 2: "mar", - 3: "mer", - 4: "gio", - 5: "ven", - 6: "sab", - }, - "narrow": {0: "D", 1: "L", 2: "M", 3: "M", 4: "G", 5: "V", 6: "S"}, - "short": { - 0: "dom", - 1: "lun", - 2: "mar", - 3: "mer", - 4: "gio", - 5: "ven", - 6: "sab", - }, - "wide": { - 0: "domenica", - 1: "lunedì", - 2: "martedì", - 3: "mercoledì", - 4: "giovedì", - 5: "venerdì", - 6: "sabato", - }, - }, - "months": { - "abbreviated": { - 1: "gen", - 2: "feb", - 3: "mar", - 4: "apr", - 5: "mag", - 6: "giu", - 7: "lug", - 8: "ago", - 9: "set", - 10: "ott", - 11: "nov", - 12: "dic", - }, - "narrow": { - 1: "G", - 2: "F", - 3: "M", - 4: "A", - 5: "M", - 6: "G", - 7: "L", - 8: "A", - 9: "S", - 10: "O", - 11: "N", - 12: "D", - }, - "wide": { - 1: "gennaio", - 2: "febbraio", - 3: "marzo", - 4: "aprile", - 5: "maggio", - 6: "giugno", - 7: "luglio", - 8: "agosto", - 9: "settembre", - 10: "ottobre", - 11: "novembre", - 12: "dicembre", - }, - }, - "units": { - "year": {"one": "{0} anno", "other": "{0} anni"}, - "month": {"one": "{0} mese", "other": "{0} mesi"}, - "week": {"one": "{0} settimana", "other": "{0} settimane"}, - "day": {"one": "{0} giorno", "other": "{0} giorni"}, - "hour": {"one": "{0} ora", "other": "{0} ore"}, - "minute": {"one": "{0} minuto", "other": "{0} minuti"}, - "second": {"one": "{0} secondo", "other": "{0} secondi"}, - "microsecond": {"one": "{0} microsecondo", "other": "{0} microsecondi"}, - }, - "relative": { - "year": { - "future": {"other": "tra {0} anni", "one": "tra {0} anno"}, - "past": {"other": "{0} anni fa", "one": "{0} anno fa"}, - }, - "month": { - "future": {"other": "tra {0} mesi", "one": "tra {0} mese"}, - "past": {"other": "{0} mesi fa", "one": "{0} mese fa"}, - }, - "week": { - "future": {"other": "tra {0} settimane", "one": "tra {0} settimana"}, - "past": {"other": "{0} settimane fa", "one": "{0} settimana fa"}, - }, - "day": { - "future": {"other": "tra {0} giorni", "one": "tra {0} giorno"}, - "past": {"other": "{0} giorni fa", "one": "{0} giorno fa"}, - }, - "hour": { - "future": {"other": "tra {0} ore", "one": "tra {0} ora"}, - "past": {"other": "{0} ore fa", "one": "{0} ora fa"}, - }, - "minute": { - "future": {"other": "tra {0} minuti", "one": "tra {0} minuto"}, - "past": {"other": "{0} minuti fa", "one": "{0} minuto fa"}, - }, - "second": { - "future": {"other": "tra {0} secondi", "one": "tra {0} secondo"}, - "past": {"other": "{0} secondi fa", "one": "{0} secondo fa"}, - }, - }, - "day_periods": { - "midnight": "mezzanotte", - "am": "AM", - "noon": "mezzogiorno", - "pm": "PM", - "morning1": "di mattina", - "afternoon1": "del pomeriggio", - "evening1": "di sera", - "night1": "di notte", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/ja/__init__.py b/pendulum/locales/ja/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/ja/custom.py b/pendulum/locales/ja/custom.py deleted file mode 100644 index c076250..0000000 --- a/pendulum/locales/ja/custom.py +++ /dev/null @@ -1,21 +0,0 @@ -""" -ja custom locale file. -""" - -translations = { - "units": {"few_second": "数秒"}, - # Relative time - "ago": "{} 前に", - "from_now": "今から {}", - "after": "{0} 後", - "before": "{0} 前", - # Date formats - "date_formats": { - "LTS": "h:mm:ss A", - "LT": "h:mm A", - "L": "MM/DD/YYYY", - "LL": "MMMM D, YYYY", - "LLL": "MMMM D, YYYY h:mm A", - "LLLL": "dddd, MMMM D, YYYY h:mm A", - }, -} diff --git a/pendulum/locales/ja/locale.py b/pendulum/locales/ja/locale.py deleted file mode 100644 index 574d2ec..0000000 --- a/pendulum/locales/ja/locale.py +++ /dev/null @@ -1,194 +0,0 @@ -from .custom import translations as custom_translations - - -""" -ja locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "日", - 1: "月", - 2: "火", - 3: "水", - 4: "木", - 5: "金", - 6: "土", - }, - "narrow": { - 0: "日", - 1: "月", - 2: "火", - 3: "水", - 4: "木", - 5: "金", - 6: "土", - }, - "short": { - 0: "日", - 1: "月", - 2: "火", - 3: "水", - 4: "木", - 5: "金", - 6: "土", - }, - "wide": { - 0: "日曜日", - 1: "月曜日", - 2: "火曜日", - 3: "水曜日", - 4: "木曜日", - 5: "金曜日", - 6: "土曜日", - }, - }, - "months": { - "abbreviated": { - 1: "1月", - 2: "2月", - 3: "3月", - 4: "4月", - 5: "5月", - 6: "6月", - 7: "7月", - 8: "8月", - 9: "9月", - 10: "10月", - 11: "11月", - 12: "12月", - }, - "narrow": { - 1: "1", - 2: "2", - 3: "3", - 4: "4", - 5: "5", - 6: "6", - 7: "7", - 8: "8", - 9: "9", - 10: "10", - 11: "11", - 12: "12", - }, - "wide": { - 1: "1月", - 2: "2月", - 3: "3月", - 4: "4月", - 5: "5月", - 6: "6月", - 7: "7月", - 8: "8月", - 9: "9月", - 10: "10月", - 11: "11月", - 12: "12月", - }, - }, - "units": { - "year": { - "other": "{0} 年", - }, - "month": { - "other": "{0} か月", - }, - "week": { - "other": "{0} 週間", - }, - "day": { - "other": "{0} 日", - }, - "hour": { - "other": "{0} 時間", - }, - "minute": { - "other": "{0} 分", - }, - "second": { - "other": "{0} 秒", - }, - "microsecond": { - "other": "{0} マイクロ秒", - }, - }, - "relative": { - "year": { - "future": { - "other": "{0} 年後", - }, - "past": { - "other": "{0} 年前", - }, - }, - "month": { - "future": { - "other": "{0} か月後", - }, - "past": { - "other": "{0} か月前", - }, - }, - "week": { - "future": { - "other": "{0} 週間後", - }, - "past": { - "other": "{0} 週間前", - }, - }, - "day": { - "future": { - "other": "{0} 日後", - }, - "past": { - "other": "{0} 日前", - }, - }, - "hour": { - "future": { - "other": "{0} 時間後", - }, - "past": { - "other": "{0} 時間前", - }, - }, - "minute": { - "future": { - "other": "{0} 分後", - }, - "past": { - "other": "{0} 分前", - }, - }, - "second": { - "future": { - "other": "{0} 秒後", - }, - "past": { - "other": "{0} 秒前", - }, - }, - }, - "day_periods": { - "midnight": "真夜中", - "am": "午前", - "noon": "正午", - "pm": "午後", - "morning1": "朝", - "afternoon1": "昼", - "evening1": "夕方", - "night1": "夜", - "night2": "夜中", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/ko/__init__.py b/pendulum/locales/ko/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/ko/custom.py b/pendulum/locales/ko/custom.py deleted file mode 100644 index 2c0e50c..0000000 --- a/pendulum/locales/ko/custom.py +++ /dev/null @@ -1,18 +0,0 @@ -""" -ko custom locale file. -""" - -translations = { - # Relative time - "after": "{0} 뒤", - "before": "{0} 앞", - # Date formats - "date_formats": { - "LTS": "A h시 m분 s초", - "LT": "A h시 m분", - "LLLL": "YYYY년 MMMM D일 dddd A h시 m분", - "LLL": "YYYY년 MMMM D일 A h시 m분", - "LL": "YYYY년 MMMM D일", - "L": "YYYY.MM.DD", - }, -} diff --git a/pendulum/locales/ko/locale.py b/pendulum/locales/ko/locale.py deleted file mode 100644 index 0f5a346..0000000 --- a/pendulum/locales/ko/locale.py +++ /dev/null @@ -1,105 +0,0 @@ -from .custom import translations as custom_translations - - -""" -ko locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": {0: "일", 1: "월", 2: "화", 3: "수", 4: "목", 5: "금", 6: "토"}, - "narrow": {0: "일", 1: "월", 2: "화", 3: "수", 4: "목", 5: "금", 6: "토"}, - "short": {0: "일", 1: "월", 2: "화", 3: "수", 4: "목", 5: "금", 6: "토"}, - "wide": { - 0: "일요일", - 1: "월요일", - 2: "화요일", - 3: "수요일", - 4: "목요일", - 5: "금요일", - 6: "토요일", - }, - }, - "months": { - "abbreviated": { - 1: "1월", - 2: "2월", - 3: "3월", - 4: "4월", - 5: "5월", - 6: "6월", - 7: "7월", - 8: "8월", - 9: "9월", - 10: "10월", - 11: "11월", - 12: "12월", - }, - "narrow": { - 1: "1월", - 2: "2월", - 3: "3월", - 4: "4월", - 5: "5월", - 6: "6월", - 7: "7월", - 8: "8월", - 9: "9월", - 10: "10월", - 11: "11월", - 12: "12월", - }, - "wide": { - 1: "1월", - 2: "2월", - 3: "3월", - 4: "4월", - 5: "5월", - 6: "6월", - 7: "7월", - 8: "8월", - 9: "9월", - 10: "10월", - 11: "11월", - 12: "12월", - }, - }, - "units": { - "year": {"other": "{0}년"}, - "month": {"other": "{0}개월"}, - "week": {"other": "{0}주"}, - "day": {"other": "{0}일"}, - "hour": {"other": "{0}시간"}, - "minute": {"other": "{0}분"}, - "second": {"other": "{0}초"}, - "microsecond": {"other": "{0}마이크로초"}, - }, - "relative": { - "year": {"future": {"other": "{0}년 후"}, "past": {"other": "{0}년 전"}}, - "month": {"future": {"other": "{0}개월 후"}, "past": {"other": "{0}개월 전"}}, - "week": {"future": {"other": "{0}주 후"}, "past": {"other": "{0}주 전"}}, - "day": {"future": {"other": "{0}일 후"}, "past": {"other": "{0}일 전"}}, - "hour": {"future": {"other": "{0}시간 후"}, "past": {"other": "{0}시간 전"}}, - "minute": {"future": {"other": "{0}분 후"}, "past": {"other": "{0}분 전"}}, - "second": {"future": {"other": "{0}초 후"}, "past": {"other": "{0}초 전"}}, - }, - "day_periods": { - "midnight": "자정", - "am": "오전", - "noon": "정오", - "pm": "오후", - "morning1": "새벽", - "morning2": "오전", - "afternoon1": "오후", - "evening1": "저녁", - "night1": "밤", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/locale.py b/pendulum/locales/locale.py deleted file mode 100644 index 637509a..0000000 --- a/pendulum/locales/locale.py +++ /dev/null @@ -1,102 +0,0 @@ -from __future__ import annotations - -from importlib import import_module -from pathlib import Path - -import re -import sys -from typing import Any, cast -from typing import Dict - -if sys.version_info >= (3, 9): - from importlib import resources -else: - import importlib_resources as resources - - -class Locale: - """ - Represent a specific locale. - """ - - _cache: dict[str, Locale] = {} - - def __init__(self, locale: str, data: Any) -> None: - self._locale: str = locale - self._data: Any = data - self._key_cache: dict[str, str] = {} - - @classmethod - def load(cls, locale: str | Locale) -> Locale: - if isinstance(locale, Locale): - return locale - - locale = cls.normalize_locale(locale) - if locale in cls._cache: - return cls._cache[locale] - - # Checking locale existence - actual_locale = locale - locale_path = cast(Path, resources.files(__package__).joinpath(actual_locale)) - while not locale_path.exists(): - if actual_locale == locale: - raise ValueError(f"Locale [{locale}] does not exist.") - - actual_locale = actual_locale.split("_")[0] - - m = import_module(f"pendulum.locales.{actual_locale}.locale") - - cls._cache[locale] = cls(locale, m.locale) - - return cls._cache[locale] - - @classmethod - def normalize_locale(cls, locale: str) -> str: - m = re.match("([a-z]{2})[-_]([a-z]{2})", locale, re.I) - if m: - return f"{m.group(1).lower()}_{m.group(2).lower()}" - else: - return locale.lower() - - def get(self, key: str, default: Any | None = None) -> Any: - if key in self._key_cache: - return self._key_cache[key] - - parts = key.split(".") - try: - result = self._data[parts[0]] - for part in parts[1:]: - result = result[part] - except KeyError: - result = default - - self._key_cache[key] = result - - return self._key_cache[key] - - def translation(self, key: str) -> Any: - return self.get(f"translations.{key}") - - def plural(self, number: int) -> str: - return cast(str, self._data["plural"](number)) - - def ordinal(self, number: int) -> str: - return cast(str, self._data["ordinal"](number)) - - def ordinalize(self, number: int) -> str: - ordinal = self.get(f"custom.ordinal.{self.ordinal(number)}") - - if not ordinal: - return f"{number}" - - return f"{number}{ordinal}" - - def match_translation(self, key: str, value: Any) -> dict[str, str] | None: - translations = self.translation(key) - if value not in translations.values(): - return None - - return cast(Dict[str, str], {v: k for k, v in translations.items()}[value]) - - def __repr__(self) -> str: - return f"{self.__class__.__name__}('{self._locale}')" diff --git a/pendulum/locales/lt/__init__.py b/pendulum/locales/lt/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/lt/custom.py b/pendulum/locales/lt/custom.py deleted file mode 100644 index 6480c31..0000000 --- a/pendulum/locales/lt/custom.py +++ /dev/null @@ -1,118 +0,0 @@ -""" -lt custom locale file. -""" - -translations = { - # Relative time - "units_relative": { - "year": { - "future": { - "other": "{0} metų", - "one": "{0} metų", - "few": "{0} metų", - "many": "{0} metų", - }, - "past": { - "other": "{0} metų", - "one": "{0} metus", - "few": "{0} metus", - "many": "{0} metų", - }, - }, - "month": { - "future": { - "other": "{0} mėnesių", - "one": "{0} mėnesio", - "few": "{0} mėnesių", - "many": "{0} mėnesio", - }, - "past": { - "other": "{0} mėnesių", - "one": "{0} mėnesį", - "few": "{0} mėnesius", - "many": "{0} mėnesio", - }, - }, - "week": { - "future": { - "other": "{0} savaičių", - "one": "{0} savaitės", - "few": "{0} savaičių", - "many": "{0} savaitės", - }, - "past": { - "other": "{0} savaičių", - "one": "{0} savaitę", - "few": "{0} savaites", - "many": "{0} savaitės", - }, - }, - "day": { - "future": { - "other": "{0} dienų", - "one": "{0} dienos", - "few": "{0} dienų", - "many": "{0} dienos", - }, - "past": { - "other": "{0} dienų", - "one": "{0} dieną", - "few": "{0} dienas", - "many": "{0} dienos", - }, - }, - "hour": { - "future": { - "other": "{0} valandų", - "one": "{0} valandos", - "few": "{0} valandų", - "many": "{0} valandos", - }, - "past": { - "other": "{0} valandų", - "one": "{0} valandą", - "few": "{0} valandas", - "many": "{0} valandos", - }, - }, - "minute": { - "future": { - "other": "{0} minučių", - "one": "{0} minutės", - "few": "{0} minučių", - "many": "{0} minutės", - }, - "past": { - "other": "{0} minučių", - "one": "{0} minutę", - "few": "{0} minutes", - "many": "{0} minutės", - }, - }, - "second": { - "future": { - "other": "{0} sekundžių", - "one": "{0} sekundės", - "few": "{0} sekundžių", - "many": "{0} sekundės", - }, - "past": { - "other": "{0} sekundžių", - "one": "{0} sekundę", - "few": "{0} sekundes", - "many": "{0} sekundės", - }, - }, - }, - "after": "po {0}", - "before": "{0} nuo dabar", - # Date formats - "date_formats": { - "LTS": "HH:mm:ss", - "LT": "HH:mm", - "LLLL": "YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]", - "LLL": "YYYY [m.] MMMM D [d.], HH:mm [val.]", - "LL": "YYYY [m.] MMMM D [d.]", - "L": "YYYY-MM-DD", - }, -} diff --git a/pendulum/locales/lt/locale.py b/pendulum/locales/lt/locale.py deleted file mode 100644 index fb017ef..0000000 --- a/pendulum/locales/lt/locale.py +++ /dev/null @@ -1,255 +0,0 @@ -from .custom import translations as custom_translations - - -""" -lt locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "few" - if ( - ((n % 10) == (n % 10) and ((n % 10) >= 2 and (n % 10) <= 9)) - and (not ((n % 100) == (n % 100) and ((n % 100) >= 11 and (n % 100) <= 19))) - ) - else "many" - if (not (0 == 0 and (0 == 0))) - else "one" - if ( - ((n % 10) == (n % 10) and ((n % 10) == 1)) - and (not ((n % 100) == (n % 100) and ((n % 100) >= 11 and (n % 100) <= 19))) - ) - else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "sk", - 1: "pr", - 2: "an", - 3: "tr", - 4: "kt", - 5: "pn", - 6: "št", - }, - "narrow": {0: "S", 1: "P", 2: "A", 3: "T", 4: "K", 5: "P", 6: "Š"}, - "short": {0: "Sk", 1: "Pr", 2: "An", 3: "Tr", 4: "Kt", 5: "Pn", 6: "Št"}, - "wide": { - 0: "sekmadienis", - 1: "pirmadienis", - 2: "antradienis", - 3: "trečiadienis", - 4: "ketvirtadienis", - 5: "penktadienis", - 6: "šeštadienis", - }, - }, - "months": { - "abbreviated": { - 1: "saus.", - 2: "vas.", - 3: "kov.", - 4: "bal.", - 5: "geg.", - 6: "birž.", - 7: "liep.", - 8: "rugp.", - 9: "rugs.", - 10: "spal.", - 11: "lapkr.", - 12: "gruod.", - }, - "narrow": { - 1: "S", - 2: "V", - 3: "K", - 4: "B", - 5: "G", - 6: "B", - 7: "L", - 8: "R", - 9: "R", - 10: "S", - 11: "L", - 12: "G", - }, - "wide": { - 1: "sausio", - 2: "vasario", - 3: "kovo", - 4: "balandžio", - 5: "gegužės", - 6: "birželio", - 7: "liepos", - 8: "rugpjūčio", - 9: "rugsėjo", - 10: "spalio", - 11: "lapkričio", - 12: "gruodžio", - }, - }, - "units": { - "year": { - "one": "{0} metai", - "few": "{0} metai", - "many": "{0} metų", - "other": "{0} metų", - }, - "month": { - "one": "{0} mėnuo", - "few": "{0} mėnesiai", - "many": "{0} mėnesio", - "other": "{0} mėnesių", - }, - "week": { - "one": "{0} savaitė", - "few": "{0} savaitės", - "many": "{0} savaitės", - "other": "{0} savaičių", - }, - "day": { - "one": "{0} diena", - "few": "{0} dienos", - "many": "{0} dienos", - "other": "{0} dienų", - }, - "hour": { - "one": "{0} valanda", - "few": "{0} valandos", - "many": "{0} valandos", - "other": "{0} valandų", - }, - "minute": { - "one": "{0} minutė", - "few": "{0} minutės", - "many": "{0} minutės", - "other": "{0} minučių", - }, - "second": { - "one": "{0} sekundė", - "few": "{0} sekundės", - "many": "{0} sekundės", - "other": "{0} sekundžių", - }, - "microsecond": { - "one": "{0} mikrosekundė", - "few": "{0} mikrosekundės", - "many": "{0} mikrosekundės", - "other": "{0} mikrosekundžių", - }, - }, - "relative": { - "year": { - "future": { - "other": "po {0} metų", - "one": "po {0} metų", - "few": "po {0} metų", - "many": "po {0} metų", - }, - "past": { - "other": "prieš {0} metų", - "one": "prieš {0} metus", - "few": "prieš {0} metus", - "many": "prieš {0} metų", - }, - }, - "month": { - "future": { - "other": "po {0} mėnesių", - "one": "po {0} mėnesio", - "few": "po {0} mėnesių", - "many": "po {0} mėnesio", - }, - "past": { - "other": "prieš {0} mėnesių", - "one": "prieš {0} mėnesį", - "few": "prieš {0} mėnesius", - "many": "prieš {0} mėnesio", - }, - }, - "week": { - "future": { - "other": "po {0} savaičių", - "one": "po {0} savaitės", - "few": "po {0} savaičių", - "many": "po {0} savaitės", - }, - "past": { - "other": "prieš {0} savaičių", - "one": "prieš {0} savaitę", - "few": "prieš {0} savaites", - "many": "prieš {0} savaitės", - }, - }, - "day": { - "future": { - "other": "po {0} dienų", - "one": "po {0} dienos", - "few": "po {0} dienų", - "many": "po {0} dienos", - }, - "past": { - "other": "prieš {0} dienų", - "one": "prieš {0} dieną", - "few": "prieš {0} dienas", - "many": "prieš {0} dienos", - }, - }, - "hour": { - "future": { - "other": "po {0} valandų", - "one": "po {0} valandos", - "few": "po {0} valandų", - "many": "po {0} valandos", - }, - "past": { - "other": "prieš {0} valandų", - "one": "prieš {0} valandą", - "few": "prieš {0} valandas", - "many": "prieš {0} valandos", - }, - }, - "minute": { - "future": { - "other": "po {0} minučių", - "one": "po {0} minutės", - "few": "po {0} minučių", - "many": "po {0} minutės", - }, - "past": { - "other": "prieš {0} minučių", - "one": "prieš {0} minutę", - "few": "prieš {0} minutes", - "many": "prieš {0} minutės", - }, - }, - "second": { - "future": { - "other": "po {0} sekundžių", - "one": "po {0} sekundės", - "few": "po {0} sekundžių", - "many": "po {0} sekundės", - }, - "past": { - "other": "prieš {0} sekundžių", - "one": "prieš {0} sekundę", - "few": "prieš {0} sekundes", - "many": "prieš {0} sekundės", - }, - }, - }, - "day_periods": { - "midnight": "vidurnaktis", - "am": "priešpiet", - "noon": "perpiet", - "pm": "popiet", - "morning1": "rytas", - "afternoon1": "popietė", - "evening1": "vakaras", - "night1": "naktis", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/nb/__init__.py b/pendulum/locales/nb/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/nb/custom.py b/pendulum/locales/nb/custom.py deleted file mode 100644 index 4c7cd6a..0000000 --- a/pendulum/locales/nb/custom.py +++ /dev/null @@ -1,20 +0,0 @@ -""" -nn custom locale file. -""" - -translations = { - # Relative time - "after": "{0} etter", - "before": "{0} før", - # Ordinals - "ordinal": {"one": ".", "two": ".", "few": ".", "other": "."}, - # Date formats - "date_formats": { - "LTS": "HH:mm:ss", - "LT": "HH:mm", - "LLLL": "dddd Do MMMM YYYY HH:mm", - "LLL": "Do MMMM YYYY HH:mm", - "LL": "Do MMMM YYYY", - "L": "DD.MM.YYYY", - }, -} diff --git a/pendulum/locales/nb/locale.py b/pendulum/locales/nb/locale.py deleted file mode 100644 index c8297a8..0000000 --- a/pendulum/locales/nb/locale.py +++ /dev/null @@ -1,150 +0,0 @@ -from .custom import translations as custom_translations - - -""" -nb locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "one" if (n == n and (n == 1)) else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "søn.", - 1: "man.", - 2: "tir.", - 3: "ons.", - 4: "tor.", - 5: "fre.", - 6: "lør.", - }, - "narrow": {0: "S", 1: "M", 2: "T", 3: "O", 4: "T", 5: "F", 6: "L"}, - "short": { - 0: "sø.", - 1: "ma.", - 2: "ti.", - 3: "on.", - 4: "to.", - 5: "fr.", - 6: "lø.", - }, - "wide": { - 0: "søndag", - 1: "mandag", - 2: "tirsdag", - 3: "onsdag", - 4: "torsdag", - 5: "fredag", - 6: "lørdag", - }, - }, - "months": { - "abbreviated": { - 1: "jan.", - 2: "feb.", - 3: "mar.", - 4: "apr.", - 5: "mai", - 6: "jun.", - 7: "jul.", - 8: "aug.", - 9: "sep.", - 10: "okt.", - 11: "nov.", - 12: "des.", - }, - "narrow": { - 1: "J", - 2: "F", - 3: "M", - 4: "A", - 5: "M", - 6: "J", - 7: "J", - 8: "A", - 9: "S", - 10: "O", - 11: "N", - 12: "D", - }, - "wide": { - 1: "januar", - 2: "februar", - 3: "mars", - 4: "april", - 5: "mai", - 6: "juni", - 7: "juli", - 8: "august", - 9: "september", - 10: "oktober", - 11: "november", - 12: "desember", - }, - }, - "units": { - "year": {"one": "{0} år", "other": "{0} år"}, - "month": {"one": "{0} måned", "other": "{0} måneder"}, - "week": {"one": "{0} uke", "other": "{0} uker"}, - "day": {"one": "{0} dag", "other": "{0} dager"}, - "hour": {"one": "{0} time", "other": "{0} timer"}, - "minute": {"one": "{0} minutt", "other": "{0} minutter"}, - "second": {"one": "{0} sekund", "other": "{0} sekunder"}, - "microsecond": {"one": "{0} mikrosekund", "other": "{0} mikrosekunder"}, - }, - "relative": { - "year": { - "future": {"other": "om {0} år", "one": "om {0} år"}, - "past": {"other": "for {0} år siden", "one": "for {0} år siden"}, - }, - "month": { - "future": {"other": "om {0} måneder", "one": "om {0} måned"}, - "past": { - "other": "for {0} måneder siden", - "one": "for {0} måned siden", - }, - }, - "week": { - "future": {"other": "om {0} uker", "one": "om {0} uke"}, - "past": {"other": "for {0} uker siden", "one": "for {0} uke siden"}, - }, - "day": { - "future": {"other": "om {0} dager", "one": "om {0} dag"}, - "past": {"other": "for {0} dager siden", "one": "for {0} dag siden"}, - }, - "hour": { - "future": {"other": "om {0} timer", "one": "om {0} time"}, - "past": {"other": "for {0} timer siden", "one": "for {0} time siden"}, - }, - "minute": { - "future": {"other": "om {0} minutter", "one": "om {0} minutt"}, - "past": { - "other": "for {0} minutter siden", - "one": "for {0} minutt siden", - }, - }, - "second": { - "future": {"other": "om {0} sekunder", "one": "om {0} sekund"}, - "past": { - "other": "for {0} sekunder siden", - "one": "for {0} sekund siden", - }, - }, - }, - "day_periods": { - "midnight": "midnatt", - "am": "a.m.", - "pm": "p.m.", - "morning1": "morgenen", - "morning2": "formiddagen", - "afternoon1": "ettermiddagen", - "evening1": "kvelden", - "night1": "natten", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/nl/__init__.py b/pendulum/locales/nl/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/nl/custom.py b/pendulum/locales/nl/custom.py deleted file mode 100644 index 2ca5a85..0000000 --- a/pendulum/locales/nl/custom.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -nl custom locale file. -""" - -translations = { - "units": {"few_second": "enkele seconden"}, - # Relative time - "ago": "{} geleden", - "from_now": "over {}", - "after": "{0} later", - "before": "{0} eerder", - # Ordinals - "ordinal": {"other": "e"}, - # Date formats - "date_formats": { - "L": "DD-MM-YYYY", - "LL": "D MMMM YYYY", - "LLL": "D MMMM YYYY HH:mm", - "LLLL": "dddd D MMMM YYYY HH:mm", - "LT": "HH:mm", - "LTS": "HH:mm:ss", - }, -} diff --git a/pendulum/locales/nl/locale.py b/pendulum/locales/nl/locale.py deleted file mode 100644 index cb1570d..0000000 --- a/pendulum/locales/nl/locale.py +++ /dev/null @@ -1,134 +0,0 @@ -from .custom import translations as custom_translations - - -""" -nl locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "one" - if ((n == n and (n == 1)) and (0 == 0 and (0 == 0))) - else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "zo", - 1: "ma", - 2: "di", - 3: "wo", - 4: "do", - 5: "vr", - 6: "za", - }, - "narrow": {0: "Z", 1: "M", 2: "D", 3: "W", 4: "D", 5: "V", 6: "Z"}, - "short": {0: "zo", 1: "ma", 2: "di", 3: "wo", 4: "do", 5: "vr", 6: "za"}, - "wide": { - 0: "zondag", - 1: "maandag", - 2: "dinsdag", - 3: "woensdag", - 4: "donderdag", - 5: "vrijdag", - 6: "zaterdag", - }, - }, - "months": { - "abbreviated": { - 1: "jan.", - 2: "feb.", - 3: "mrt.", - 4: "apr.", - 5: "mei", - 6: "jun.", - 7: "jul.", - 8: "aug.", - 9: "sep.", - 10: "okt.", - 11: "nov.", - 12: "dec.", - }, - "narrow": { - 1: "J", - 2: "F", - 3: "M", - 4: "A", - 5: "M", - 6: "J", - 7: "J", - 8: "A", - 9: "S", - 10: "O", - 11: "N", - 12: "D", - }, - "wide": { - 1: "januari", - 2: "februari", - 3: "maart", - 4: "april", - 5: "mei", - 6: "juni", - 7: "juli", - 8: "augustus", - 9: "september", - 10: "oktober", - 11: "november", - 12: "december", - }, - }, - "units": { - "year": {"one": "{0} jaar", "other": "{0} jaar"}, - "month": {"one": "{0} maand", "other": "{0} maanden"}, - "week": {"one": "{0} week", "other": "{0} weken"}, - "day": {"one": "{0} dag", "other": "{0} dagen"}, - "hour": {"one": "{0} uur", "other": "{0} uur"}, - "minute": {"one": "{0} minuut", "other": "{0} minuten"}, - "second": {"one": "{0} seconde", "other": "{0} seconden"}, - "microsecond": {"one": "{0} microseconde", "other": "{0} microseconden"}, - }, - "relative": { - "year": { - "future": {"other": "over {0} jaar", "one": "over {0} jaar"}, - "past": {"other": "{0} jaar geleden", "one": "{0} jaar geleden"}, - }, - "month": { - "future": {"other": "over {0} maanden", "one": "over {0} maand"}, - "past": {"other": "{0} maanden geleden", "one": "{0} maand geleden"}, - }, - "week": { - "future": {"other": "over {0} weken", "one": "over {0} week"}, - "past": {"other": "{0} weken geleden", "one": "{0} week geleden"}, - }, - "day": { - "future": {"other": "over {0} dagen", "one": "over {0} dag"}, - "past": {"other": "{0} dagen geleden", "one": "{0} dag geleden"}, - }, - "hour": { - "future": {"other": "over {0} uur", "one": "over {0} uur"}, - "past": {"other": "{0} uur geleden", "one": "{0} uur geleden"}, - }, - "minute": { - "future": {"other": "over {0} minuten", "one": "over {0} minuut"}, - "past": {"other": "{0} minuten geleden", "one": "{0} minuut geleden"}, - }, - "second": { - "future": {"other": "over {0} seconden", "one": "over {0} seconde"}, - "past": {"other": "{0} seconden geleden", "one": "{0} seconde geleden"}, - }, - }, - "day_periods": { - "midnight": "middernacht", - "am": "a.m.", - "pm": "p.m.", - "morning1": "‘s ochtends", - "afternoon1": "‘s middags", - "evening1": "‘s avonds", - "night1": "‘s nachts", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/nn/__init__.py b/pendulum/locales/nn/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/nn/custom.py b/pendulum/locales/nn/custom.py deleted file mode 100644 index 4c7cd6a..0000000 --- a/pendulum/locales/nn/custom.py +++ /dev/null @@ -1,20 +0,0 @@ -""" -nn custom locale file. -""" - -translations = { - # Relative time - "after": "{0} etter", - "before": "{0} før", - # Ordinals - "ordinal": {"one": ".", "two": ".", "few": ".", "other": "."}, - # Date formats - "date_formats": { - "LTS": "HH:mm:ss", - "LT": "HH:mm", - "LLLL": "dddd Do MMMM YYYY HH:mm", - "LLL": "Do MMMM YYYY HH:mm", - "LL": "Do MMMM YYYY", - "L": "DD.MM.YYYY", - }, -} diff --git a/pendulum/locales/nn/locale.py b/pendulum/locales/nn/locale.py deleted file mode 100644 index eb46e1d..0000000 --- a/pendulum/locales/nn/locale.py +++ /dev/null @@ -1,141 +0,0 @@ -from .custom import translations as custom_translations - - -""" -nn locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "one" if (n == n and (n == 1)) else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "søn.", - 1: "mån.", - 2: "tys.", - 3: "ons.", - 4: "tor.", - 5: "fre.", - 6: "lau.", - }, - "narrow": {0: "S", 1: "M", 2: "T", 3: "O", 4: "T", 5: "F", 6: "L"}, - "short": { - 0: "sø.", - 1: "må.", - 2: "ty.", - 3: "on.", - 4: "to.", - 5: "fr.", - 6: "la.", - }, - "wide": { - 0: "søndag", - 1: "måndag", - 2: "tysdag", - 3: "onsdag", - 4: "torsdag", - 5: "fredag", - 6: "laurdag", - }, - }, - "months": { - "abbreviated": { - 1: "jan.", - 2: "feb.", - 3: "mars", - 4: "apr.", - 5: "mai", - 6: "juni", - 7: "juli", - 8: "aug.", - 9: "sep.", - 10: "okt.", - 11: "nov.", - 12: "des.", - }, - "narrow": { - 1: "J", - 2: "F", - 3: "M", - 4: "A", - 5: "M", - 6: "J", - 7: "J", - 8: "A", - 9: "S", - 10: "O", - 11: "N", - 12: "D", - }, - "wide": { - 1: "januar", - 2: "februar", - 3: "mars", - 4: "april", - 5: "mai", - 6: "juni", - 7: "juli", - 8: "august", - 9: "september", - 10: "oktober", - 11: "november", - 12: "desember", - }, - }, - "units": { - "year": {"one": "{0} år", "other": "{0} år"}, - "month": {"one": "{0} månad", "other": "{0} månadar"}, - "week": {"one": "{0} veke", "other": "{0} veker"}, - "day": {"one": "{0} dag", "other": "{0} dagar"}, - "hour": {"one": "{0} time", "other": "{0} timar"}, - "minute": {"one": "{0} minutt", "other": "{0} minutt"}, - "second": {"one": "{0} sekund", "other": "{0} sekund"}, - "microsecond": {"one": "{0} mikrosekund", "other": "{0} mikrosekund"}, - }, - "relative": { - "year": { - "future": {"other": "om {0} år", "one": "om {0} år"}, - "past": {"other": "for {0} år sidan", "one": "for {0} år sidan"}, - }, - "month": { - "future": {"other": "om {0} månadar", "one": "om {0} månad"}, - "past": { - "other": "for {0} månadar sidan", - "one": "for {0} månad sidan", - }, - }, - "week": { - "future": {"other": "om {0} veker", "one": "om {0} veke"}, - "past": {"other": "for {0} veker sidan", "one": "for {0} veke sidan"}, - }, - "day": { - "future": {"other": "om {0} dagar", "one": "om {0} dag"}, - "past": {"other": "for {0} dagar sidan", "one": "for {0} dag sidan"}, - }, - "hour": { - "future": {"other": "om {0} timar", "one": "om {0} time"}, - "past": {"other": "for {0} timar sidan", "one": "for {0} time sidan"}, - }, - "minute": { - "future": {"other": "om {0} minutt", "one": "om {0} minutt"}, - "past": { - "other": "for {0} minutt sidan", - "one": "for {0} minutt sidan", - }, - }, - "second": { - "future": {"other": "om {0} sekund", "one": "om {0} sekund"}, - "past": { - "other": "for {0} sekund sidan", - "one": "for {0} sekund sidan", - }, - }, - }, - "day_periods": {"am": "formiddag", "pm": "ettermiddag"}, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/pl/__init__.py b/pendulum/locales/pl/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/pl/custom.py b/pendulum/locales/pl/custom.py deleted file mode 100644 index 9741b74..0000000 --- a/pendulum/locales/pl/custom.py +++ /dev/null @@ -1,21 +0,0 @@ -""" -pl custom locale file. -""" - -translations = { - "units": {"few_second": "kilka sekund"}, - # Relative time - "ago": "{} temu", - "from_now": "za {}", - "after": "{0} po", - "before": "{0} przed", - # Date formats - "date_formats": { - "LTS": "HH:mm:ss", - "LT": "HH:mm", - "L": "DD.MM.YYYY", - "LL": "D MMMM YYYY", - "LLL": "D MMMM YYYY HH:mm", - "LLLL": "dddd, D MMMM YYYY HH:mm", - }, -} diff --git a/pendulum/locales/pl/locale.py b/pendulum/locales/pl/locale.py deleted file mode 100644 index bf6af10..0000000 --- a/pendulum/locales/pl/locale.py +++ /dev/null @@ -1,279 +0,0 @@ -from .custom import translations as custom_translations - - -""" -pl locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "few" - if ( - ( - (0 == 0 and (0 == 0)) - and ((n % 10) == (n % 10) and ((n % 10) >= 2 and (n % 10) <= 4)) - ) - and (not ((n % 100) == (n % 100) and ((n % 100) >= 12 and (n % 100) <= 14))) - ) - else "many" - if ( - ( - ( - ((0 == 0 and (0 == 0)) and (not (n == n and (n == 1)))) - and ((n % 10) == (n % 10) and ((n % 10) >= 0 and (n % 10) <= 1)) - ) - or ( - (0 == 0 and (0 == 0)) - and ((n % 10) == (n % 10) and ((n % 10) >= 5 and (n % 10) <= 9)) - ) - ) - or ( - (0 == 0 and (0 == 0)) - and ((n % 100) == (n % 100) and ((n % 100) >= 12 and (n % 100) <= 14)) - ) - ) - else "one" - if ((n == n and (n == 1)) and (0 == 0 and (0 == 0))) - else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "niedz.", - 1: "pon.", - 2: "wt.", - 3: "śr.", - 4: "czw.", - 5: "pt.", - 6: "sob.", - }, - "narrow": {0: "n", 1: "p", 2: "w", 3: "ś", 4: "c", 5: "p", 6: "s"}, - "short": { - 0: "nie", - 1: "pon", - 2: "wto", - 3: "śro", - 4: "czw", - 5: "pią", - 6: "sob", - }, - "wide": { - 0: "niedziela", - 1: "poniedziałek", - 2: "wtorek", - 3: "środa", - 4: "czwartek", - 5: "piątek", - 6: "sobota", - }, - }, - "months": { - "abbreviated": { - 1: "sty", - 2: "lut", - 3: "mar", - 4: "kwi", - 5: "maj", - 6: "cze", - 7: "lip", - 8: "sie", - 9: "wrz", - 10: "paź", - 11: "lis", - 12: "gru", - }, - "narrow": { - 1: "s", - 2: "l", - 3: "m", - 4: "k", - 5: "m", - 6: "c", - 7: "l", - 8: "s", - 9: "w", - 10: "p", - 11: "l", - 12: "g", - }, - "wide": { - 1: "stycznia", - 2: "lutego", - 3: "marca", - 4: "kwietnia", - 5: "maja", - 6: "czerwca", - 7: "lipca", - 8: "sierpnia", - 9: "września", - 10: "października", - 11: "listopada", - 12: "grudnia", - }, - }, - "units": { - "year": { - "one": "{0} rok", - "few": "{0} lata", - "many": "{0} lat", - "other": "{0} roku", - }, - "month": { - "one": "{0} miesiąc", - "few": "{0} miesiące", - "many": "{0} miesięcy", - "other": "{0} miesiąca", - }, - "week": { - "one": "{0} tydzień", - "few": "{0} tygodnie", - "many": "{0} tygodni", - "other": "{0} tygodnia", - }, - "day": { - "one": "{0} dzień", - "few": "{0} dni", - "many": "{0} dni", - "other": "{0} dnia", - }, - "hour": { - "one": "{0} godzina", - "few": "{0} godziny", - "many": "{0} godzin", - "other": "{0} godziny", - }, - "minute": { - "one": "{0} minuta", - "few": "{0} minuty", - "many": "{0} minut", - "other": "{0} minuty", - }, - "second": { - "one": "{0} sekunda", - "few": "{0} sekundy", - "many": "{0} sekund", - "other": "{0} sekundy", - }, - "microsecond": { - "one": "{0} mikrosekunda", - "few": "{0} mikrosekundy", - "many": "{0} mikrosekund", - "other": "{0} mikrosekundy", - }, - }, - "relative": { - "year": { - "future": { - "other": "za {0} roku", - "one": "za {0} rok", - "few": "za {0} lata", - "many": "za {0} lat", - }, - "past": { - "other": "{0} roku temu", - "one": "{0} rok temu", - "few": "{0} lata temu", - "many": "{0} lat temu", - }, - }, - "month": { - "future": { - "other": "za {0} miesiąca", - "one": "za {0} miesiąc", - "few": "za {0} miesiące", - "many": "za {0} miesięcy", - }, - "past": { - "other": "{0} miesiąca temu", - "one": "{0} miesiąc temu", - "few": "{0} miesiące temu", - "many": "{0} miesięcy temu", - }, - }, - "week": { - "future": { - "other": "za {0} tygodnia", - "one": "za {0} tydzień", - "few": "za {0} tygodnie", - "many": "za {0} tygodni", - }, - "past": { - "other": "{0} tygodnia temu", - "one": "{0} tydzień temu", - "few": "{0} tygodnie temu", - "many": "{0} tygodni temu", - }, - }, - "day": { - "future": { - "other": "za {0} dnia", - "one": "za {0} dzień", - "few": "za {0} dni", - "many": "za {0} dni", - }, - "past": { - "other": "{0} dnia temu", - "one": "{0} dzień temu", - "few": "{0} dni temu", - "many": "{0} dni temu", - }, - }, - "hour": { - "future": { - "other": "za {0} godziny", - "one": "za {0} godzinę", - "few": "za {0} godziny", - "many": "za {0} godzin", - }, - "past": { - "other": "{0} godziny temu", - "one": "{0} godzinę temu", - "few": "{0} godziny temu", - "many": "{0} godzin temu", - }, - }, - "minute": { - "future": { - "other": "za {0} minuty", - "one": "za {0} minutę", - "few": "za {0} minuty", - "many": "za {0} minut", - }, - "past": { - "other": "{0} minuty temu", - "one": "{0} minutę temu", - "few": "{0} minuty temu", - "many": "{0} minut temu", - }, - }, - "second": { - "future": { - "other": "za {0} sekundy", - "one": "za {0} sekundę", - "few": "za {0} sekundy", - "many": "za {0} sekund", - }, - "past": { - "other": "{0} sekundy temu", - "one": "{0} sekundę temu", - "few": "{0} sekundy temu", - "many": "{0} sekund temu", - }, - }, - }, - "day_periods": { - "midnight": "o północy", - "am": "AM", - "noon": "w południe", - "pm": "PM", - "morning1": "rano", - "morning2": "przed południem", - "afternoon1": "po południu", - "evening1": "wieczorem", - "night1": "w nocy", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/pt_br/__init__.py b/pendulum/locales/pt_br/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/pt_br/custom.py b/pendulum/locales/pt_br/custom.py deleted file mode 100644 index 12aced7..0000000 --- a/pendulum/locales/pt_br/custom.py +++ /dev/null @@ -1,18 +0,0 @@ -""" -pt-br custom locale file. -""" - -translations = { - # Relative time - "after": "após {0}", - "before": "{0} atrás", - # Date formats - "date_formats": { - "LTS": "HH:mm:ss", - "LT": "HH:mm", - "LLLL": "dddd, D [de] MMMM [de] YYYY [às] HH:mm", - "LLL": "D [de] MMMM [de] YYYY [às] HH:mm", - "LL": "D [de] MMMM [de] YYYY", - "L": "DD/MM/YYYY", - }, -} diff --git a/pendulum/locales/pt_br/locale.py b/pendulum/locales/pt_br/locale.py deleted file mode 100644 index 742c41f..0000000 --- a/pendulum/locales/pt_br/locale.py +++ /dev/null @@ -1,143 +0,0 @@ -from .custom import translations as custom_translations - - -""" -pt_br locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "one" - if ((n == n and (n >= 0 and n <= 2)) and (not (n == n and (n == 2)))) - else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "dom", - 1: "seg", - 2: "ter", - 3: "qua", - 4: "qui", - 5: "sex", - 6: "sáb", - }, - "narrow": {0: "D", 1: "S", 2: "T", 3: "Q", 4: "Q", 5: "S", 6: "S"}, - "short": { - 0: "dom", - 1: "seg", - 2: "ter", - 3: "qua", - 4: "qui", - 5: "sex", - 6: "sáb", - }, - "wide": { - 0: "domingo", - 1: "segunda-feira", - 2: "terça-feira", - 3: "quarta-feira", - 4: "quinta-feira", - 5: "sexta-feira", - 6: "sábado", - }, - }, - "months": { - "abbreviated": { - 1: "jan", - 2: "fev", - 3: "mar", - 4: "abr", - 5: "mai", - 6: "jun", - 7: "jul", - 8: "ago", - 9: "set", - 10: "out", - 11: "nov", - 12: "dez", - }, - "narrow": { - 1: "J", - 2: "F", - 3: "M", - 4: "A", - 5: "M", - 6: "J", - 7: "J", - 8: "A", - 9: "S", - 10: "O", - 11: "N", - 12: "D", - }, - "wide": { - 1: "janeiro", - 2: "fevereiro", - 3: "março", - 4: "abril", - 5: "maio", - 6: "junho", - 7: "julho", - 8: "agosto", - 9: "setembro", - 10: "outubro", - 11: "novembro", - 12: "dezembro", - }, - }, - "units": { - "year": {"one": "{0} ano", "other": "{0} anos"}, - "month": {"one": "{0} mês", "other": "{0} meses"}, - "week": {"one": "{0} semana", "other": "{0} semanas"}, - "day": {"one": "{0} dia", "other": "{0} dias"}, - "hour": {"one": "{0} hora", "other": "{0} horas"}, - "minute": {"one": "{0} minuto", "other": "{0} minutos"}, - "second": {"one": "{0} segundo", "other": "{0} segundos"}, - "microsecond": {"one": "{0} microssegundo", "other": "{0} microssegundos"}, - }, - "relative": { - "year": { - "future": {"other": "em {0} anos", "one": "em {0} ano"}, - "past": {"other": "há {0} anos", "one": "há {0} ano"}, - }, - "month": { - "future": {"other": "em {0} meses", "one": "em {0} mês"}, - "past": {"other": "há {0} meses", "one": "há {0} mês"}, - }, - "week": { - "future": {"other": "em {0} semanas", "one": "em {0} semana"}, - "past": {"other": "há {0} semanas", "one": "há {0} semana"}, - }, - "day": { - "future": {"other": "em {0} dias", "one": "em {0} dia"}, - "past": {"other": "há {0} dias", "one": "há {0} dia"}, - }, - "hour": { - "future": {"other": "em {0} horas", "one": "em {0} hora"}, - "past": {"other": "há {0} horas", "one": "há {0} hora"}, - }, - "minute": { - "future": {"other": "em {0} minutos", "one": "em {0} minuto"}, - "past": {"other": "há {0} minutos", "one": "há {0} minuto"}, - }, - "second": { - "future": {"other": "em {0} segundos", "one": "em {0} segundo"}, - "past": {"other": "há {0} segundos", "one": "há {0} segundo"}, - }, - }, - "day_periods": { - "midnight": "meia-noite", - "am": "AM", - "noon": "meio-dia", - "pm": "PM", - "morning1": "da manhã", - "afternoon1": "da tarde", - "evening1": "da noite", - "night1": "da madrugada", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/ru/__init__.py b/pendulum/locales/ru/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/ru/custom.py b/pendulum/locales/ru/custom.py deleted file mode 100644 index b4c89bb..0000000 --- a/pendulum/locales/ru/custom.py +++ /dev/null @@ -1,20 +0,0 @@ -""" -ru custom locale file. -""" - -translations = { - # Relative time - "ago": "{} назад", - "from_now": "через {}", - "after": "{0} после", - "before": "{0} до", - # Date formats - "date_formats": { - "LTS": "HH:mm:ss", - "LT": "HH:mm", - "L": "DD.MM.YYYY", - "LL": "D MMMM YYYY г.", - "LLL": "D MMMM YYYY г., HH:mm", - "LLLL": "dddd, D MMMM YYYY г., HH:mm", - }, -} diff --git a/pendulum/locales/ru/locale.py b/pendulum/locales/ru/locale.py deleted file mode 100644 index 3736e0b..0000000 --- a/pendulum/locales/ru/locale.py +++ /dev/null @@ -1,270 +0,0 @@ -from .custom import translations as custom_translations - - -""" -ru locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "few" - if ( - ( - (0 == 0 and (0 == 0)) - and ((n % 10) == (n % 10) and ((n % 10) >= 2 and (n % 10) <= 4)) - ) - and (not ((n % 100) == (n % 100) and ((n % 100) >= 12 and (n % 100) <= 14))) - ) - else "many" - if ( - ( - ((0 == 0 and (0 == 0)) and ((n % 10) == (n % 10) and ((n % 10) == 0))) - or ( - (0 == 0 and (0 == 0)) - and ((n % 10) == (n % 10) and ((n % 10) >= 5 and (n % 10) <= 9)) - ) - ) - or ( - (0 == 0 and (0 == 0)) - and ((n % 100) == (n % 100) and ((n % 100) >= 11 and (n % 100) <= 14)) - ) - ) - else "one" - if ( - ((0 == 0 and (0 == 0)) and ((n % 10) == (n % 10) and ((n % 10) == 1))) - and (not ((n % 100) == (n % 100) and ((n % 100) == 11))) - ) - else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "вс", - 1: "пн", - 2: "вт", - 3: "ср", - 4: "чт", - 5: "пт", - 6: "сб", - }, - "narrow": {0: "вс", 1: "пн", 2: "вт", 3: "ср", 4: "чт", 5: "пт", 6: "сб"}, - "short": {0: "вс", 1: "пн", 2: "вт", 3: "ср", 4: "чт", 5: "пт", 6: "сб"}, - "wide": { - 0: "воскресенье", - 1: "понедельник", - 2: "вторник", - 3: "среда", - 4: "четверг", - 5: "пятница", - 6: "суббота", - }, - }, - "months": { - "abbreviated": { - 1: "янв.", - 2: "февр.", - 3: "мар.", - 4: "апр.", - 5: "мая", - 6: "июн.", - 7: "июл.", - 8: "авг.", - 9: "сент.", - 10: "окт.", - 11: "нояб.", - 12: "дек.", - }, - "narrow": { - 1: "Я", - 2: "Ф", - 3: "М", - 4: "А", - 5: "М", - 6: "И", - 7: "И", - 8: "А", - 9: "С", - 10: "О", - 11: "Н", - 12: "Д", - }, - "wide": { - 1: "января", - 2: "февраля", - 3: "марта", - 4: "апреля", - 5: "мая", - 6: "июня", - 7: "июля", - 8: "августа", - 9: "сентября", - 10: "октября", - 11: "ноября", - 12: "декабря", - }, - }, - "units": { - "year": { - "one": "{0} год", - "few": "{0} года", - "many": "{0} лет", - "other": "{0} года", - }, - "month": { - "one": "{0} месяц", - "few": "{0} месяца", - "many": "{0} месяцев", - "other": "{0} месяца", - }, - "week": { - "one": "{0} неделя", - "few": "{0} недели", - "many": "{0} недель", - "other": "{0} недели", - }, - "day": { - "one": "{0} день", - "few": "{0} дня", - "many": "{0} дней", - "other": "{0} дня", - }, - "hour": { - "one": "{0} час", - "few": "{0} часа", - "many": "{0} часов", - "other": "{0} часа", - }, - "minute": { - "one": "{0} минута", - "few": "{0} минуты", - "many": "{0} минут", - "other": "{0} минуты", - }, - "second": { - "one": "{0} секунда", - "few": "{0} секунды", - "many": "{0} секунд", - "other": "{0} секунды", - }, - "microsecond": { - "one": "{0} микросекунда", - "few": "{0} микросекунды", - "many": "{0} микросекунд", - "other": "{0} микросекунды", - }, - }, - "relative": { - "year": { - "future": { - "other": "через {0} года", - "one": "через {0} год", - "few": "через {0} года", - "many": "через {0} лет", - }, - "past": { - "other": "{0} года назад", - "one": "{0} год назад", - "few": "{0} года назад", - "many": "{0} лет назад", - }, - }, - "month": { - "future": { - "other": "через {0} месяца", - "one": "через {0} месяц", - "few": "через {0} месяца", - "many": "через {0} месяцев", - }, - "past": { - "other": "{0} месяца назад", - "one": "{0} месяц назад", - "few": "{0} месяца назад", - "many": "{0} месяцев назад", - }, - }, - "week": { - "future": { - "other": "через {0} недели", - "one": "через {0} неделю", - "few": "через {0} недели", - "many": "через {0} недель", - }, - "past": { - "other": "{0} недели назад", - "one": "{0} неделю назад", - "few": "{0} недели назад", - "many": "{0} недель назад", - }, - }, - "day": { - "future": { - "other": "через {0} дня", - "one": "через {0} день", - "few": "через {0} дня", - "many": "через {0} дней", - }, - "past": { - "other": "{0} дня назад", - "one": "{0} день назад", - "few": "{0} дня назад", - "many": "{0} дней назад", - }, - }, - "hour": { - "future": { - "other": "через {0} часа", - "one": "через {0} час", - "few": "через {0} часа", - "many": "через {0} часов", - }, - "past": { - "other": "{0} часа назад", - "one": "{0} час назад", - "few": "{0} часа назад", - "many": "{0} часов назад", - }, - }, - "minute": { - "future": { - "other": "через {0} минуты", - "one": "через {0} минуту", - "few": "через {0} минуты", - "many": "через {0} минут", - }, - "past": { - "other": "{0} минуты назад", - "one": "{0} минуту назад", - "few": "{0} минуты назад", - "many": "{0} минут назад", - }, - }, - "second": { - "future": { - "other": "через {0} секунды", - "one": "через {0} секунду", - "few": "через {0} секунды", - "many": "через {0} секунд", - }, - "past": { - "other": "{0} секунды назад", - "one": "{0} секунду назад", - "few": "{0} секунды назад", - "many": "{0} секунд назад", - }, - }, - }, - "day_periods": { - "midnight": "полночь", - "am": "AM", - "noon": "полдень", - "pm": "PM", - "morning1": "утра", - "afternoon1": "дня", - "evening1": "вечера", - "night1": "ночи", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/sk/__init__.py b/pendulum/locales/sk/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/sk/custom.py b/pendulum/locales/sk/custom.py deleted file mode 100644 index 71afb15..0000000 --- a/pendulum/locales/sk/custom.py +++ /dev/null @@ -1,20 +0,0 @@ -""" -sk custom locale file. -""" - -translations = { - # Relative time - "ago": "pred {}", - "from_now": "o {}", - "after": "{0} po", - "before": "{0} pred", - # Date formats - "date_formats": { - "LTS": "HH:mm:ss", - "LT": "HH:mm", - "LLLL": "dddd, D. MMMM YYYY HH:mm", - "LLL": "D. MMMM YYYY HH:mm", - "LL": "D. MMMM YYYY", - "L": "DD.MM.YYYY", - }, -} diff --git a/pendulum/locales/sk/locale.py b/pendulum/locales/sk/locale.py deleted file mode 100644 index 8d3459f..0000000 --- a/pendulum/locales/sk/locale.py +++ /dev/null @@ -1,266 +0,0 @@ -from .custom import translations as custom_translations - - -""" -sk locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "few" - if ((n == n and (n >= 2 and n <= 4)) and (0 == 0 and (0 == 0))) - else "many" - if (not (0 == 0 and (0 == 0))) - else "one" - if ((n == n and (n == 1)) and (0 == 0 and (0 == 0))) - else "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "ne", - 1: "po", - 2: "ut", - 3: "st", - 4: "št", - 5: "pi", - 6: "so", - }, - "narrow": { - 0: "n", - 1: "p", - 2: "u", - 3: "s", - 4: "š", - 5: "p", - 6: "s", - }, - "short": { - 0: "ne", - 1: "po", - 2: "ut", - 3: "st", - 4: "št", - 5: "pi", - 6: "so", - }, - "wide": { - 0: "nedeľa", - 1: "pondelok", - 2: "utorok", - 3: "streda", - 4: "štvrtok", - 5: "piatok", - 6: "sobota", - }, - }, - "months": { - "abbreviated": { - 1: "jan", - 2: "feb", - 3: "mar", - 4: "apr", - 5: "máj", - 6: "jún", - 7: "júl", - 8: "aug", - 9: "sep", - 10: "okt", - 11: "nov", - 12: "dec", - }, - "narrow": { - 1: "j", - 2: "f", - 3: "m", - 4: "a", - 5: "m", - 6: "j", - 7: "j", - 8: "a", - 9: "s", - 10: "o", - 11: "n", - 12: "d", - }, - "wide": { - 1: "januára", - 2: "februára", - 3: "marca", - 4: "apríla", - 5: "mája", - 6: "júna", - 7: "júla", - 8: "augusta", - 9: "septembra", - 10: "októbra", - 11: "novembra", - 12: "decembra", - }, - }, - "units": { - "year": { - "one": "{0} rok", - "few": "{0} roky", - "many": "{0} roka", - "other": "{0} rokov", - }, - "month": { - "one": "{0} mesiac", - "few": "{0} mesiace", - "many": "{0} mesiaca", - "other": "{0} mesiacov", - }, - "week": { - "one": "{0} týždeň", - "few": "{0} týždne", - "many": "{0} týždňa", - "other": "{0} týždňov", - }, - "day": { - "one": "{0} deň", - "few": "{0} dni", - "many": "{0} dňa", - "other": "{0} dní", - }, - "hour": { - "one": "{0} hodina", - "few": "{0} hodiny", - "many": "{0} hodiny", - "other": "{0} hodín", - }, - "minute": { - "one": "{0} minúta", - "few": "{0} minúty", - "many": "{0} minúty", - "other": "{0} minút", - }, - "second": { - "one": "{0} sekunda", - "few": "{0} sekundy", - "many": "{0} sekundy", - "other": "{0} sekúnd", - }, - "microsecond": { - "one": "{0} mikrosekunda", - "few": "{0} mikrosekundy", - "many": "{0} mikrosekundy", - "other": "{0} mikrosekúnd", - }, - }, - "relative": { - "year": { - "future": { - "other": "o {0} rokov", - "one": "o {0} rok", - "few": "o {0} roky", - "many": "o {0} roka", - }, - "past": { - "other": "pred {0} rokmi", - "one": "pred {0} rokom", - "few": "pred {0} rokmi", - "many": "pred {0} roka", - }, - }, - "month": { - "future": { - "other": "o {0} mesiacov", - "one": "o {0} mesiac", - "few": "o {0} mesiace", - "many": "o {0} mesiaca", - }, - "past": { - "other": "pred {0} mesiacmi", - "one": "pred {0} mesiacom", - "few": "pred {0} mesiacmi", - "many": "pred {0} mesiaca", - }, - }, - "week": { - "future": { - "other": "o {0} týždňov", - "one": "o {0} týždeň", - "few": "o {0} týždne", - "many": "o {0} týždňa", - }, - "past": { - "other": "pred {0} týždňami", - "one": "pred {0} týždňom", - "few": "pred {0} týždňami", - "many": "pred {0} týždňa", - }, - }, - "day": { - "future": { - "other": "o {0} dní", - "one": "o {0} deň", - "few": "o {0} dni", - "many": "o {0} dňa", - }, - "past": { - "other": "pred {0} dňami", - "one": "pred {0} dňom", - "few": "pred {0} dňami", - "many": "pred {0} dňa", - }, - }, - "hour": { - "future": { - "other": "o {0} hodín", - "one": "o {0} hodinu", - "few": "o {0} hodiny", - "many": "o {0} hodiny", - }, - "past": { - "other": "pred {0} hodinami", - "one": "pred {0} hodinou", - "few": "pred {0} hodinami", - "many": "pred {0} hodinou", - }, - }, - "minute": { - "future": { - "other": "o {0} minút", - "one": "o {0} minútu", - "few": "o {0} minúty", - "many": "o {0} minúty", - }, - "past": { - "other": "pred {0} minútami", - "one": "pred {0} minútou", - "few": "pred {0} minútami", - "many": "pred {0} minúty", - }, - }, - "second": { - "future": { - "other": "o {0} sekúnd", - "one": "o {0} sekundu", - "few": "o {0} sekundy", - "many": "o {0} sekundy", - }, - "past": { - "other": "pred {0} sekundami", - "one": "pred {0} sekundou", - "few": "pred {0} sekundami", - "many": "pred {0} sekundy", - }, - }, - }, - "day_periods": { - "midnight": "o polnoci", - "am": "AM", - "noon": "napoludnie", - "pm": "PM", - "morning1": "ráno", - "morning2": "dopoludnia", - "afternoon1": "popoludní", - "evening1": "večer", - "night1": "v noci", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/sv/__init__.py b/pendulum/locales/sv/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/sv/custom.py b/pendulum/locales/sv/custom.py deleted file mode 100644 index 7158f4b..0000000 --- a/pendulum/locales/sv/custom.py +++ /dev/null @@ -1,20 +0,0 @@ -""" -sv custom locale file. -""" - -translations = { - # Relative time - "ago": "{} sedan", - "from_now": "från nu {}", - "after": "{0} efter", - "before": "{0} innan", - # Date formats - "date_formats": { - "LTS": "HH:mm:ss", - "LT": "HH:mm", - "L": "YYYY-MM-DD", - "LL": "D MMMM YYYY", - "LLL": "D MMMM YYYY, HH:mm", - "LLLL": "dddd, D MMMM YYYY, HH:mm", - }, -} diff --git a/pendulum/locales/sv/locale.py b/pendulum/locales/sv/locale.py deleted file mode 100644 index 5b74a6e..0000000 --- a/pendulum/locales/sv/locale.py +++ /dev/null @@ -1,222 +0,0 @@ -from .custom import translations as custom_translations - - -""" -sv locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "one" - if ((n == n and (n == 1)) and (0 == 0 and (0 == 0))) - else "other", - "ordinal": lambda n: "one" - if ( - ((n % 10) == (n % 10) and (((n % 10) == 1) or ((n % 10) == 2))) - and (not ((n % 100) == (n % 100) and (((n % 100) == 11) or ((n % 100) == 12)))) - ) - else "other", - "translations": { - "days": { - "abbreviated": { - 0: "sön", - 1: "mån", - 2: "tis", - 3: "ons", - 4: "tors", - 5: "fre", - 6: "lör", - }, - "narrow": { - 0: "S", - 1: "M", - 2: "T", - 3: "O", - 4: "T", - 5: "F", - 6: "L", - }, - "short": { - 0: "sö", - 1: "må", - 2: "ti", - 3: "on", - 4: "to", - 5: "fr", - 6: "lö", - }, - "wide": { - 0: "söndag", - 1: "måndag", - 2: "tisdag", - 3: "onsdag", - 4: "torsdag", - 5: "fredag", - 6: "lördag", - }, - }, - "months": { - "abbreviated": { - 1: "jan.", - 2: "feb.", - 3: "mars", - 4: "apr.", - 5: "maj", - 6: "juni", - 7: "juli", - 8: "aug.", - 9: "sep.", - 10: "okt.", - 11: "nov.", - 12: "dec.", - }, - "narrow": { - 1: "J", - 2: "F", - 3: "M", - 4: "A", - 5: "M", - 6: "J", - 7: "J", - 8: "A", - 9: "S", - 10: "O", - 11: "N", - 12: "D", - }, - "wide": { - 1: "januari", - 2: "februari", - 3: "mars", - 4: "april", - 5: "maj", - 6: "juni", - 7: "juli", - 8: "augusti", - 9: "september", - 10: "oktober", - 11: "november", - 12: "december", - }, - }, - "units": { - "year": { - "one": "{0} år", - "other": "{0} år", - }, - "month": { - "one": "{0} månad", - "other": "{0} månader", - }, - "week": { - "one": "{0} vecka", - "other": "{0} veckor", - }, - "day": { - "one": "{0} dygn", - "other": "{0} dygn", - }, - "hour": { - "one": "{0} timme", - "other": "{0} timmar", - }, - "minute": { - "one": "{0} minut", - "other": "{0} minuter", - }, - "second": { - "one": "{0} sekund", - "other": "{0} sekunder", - }, - "microsecond": { - "one": "{0} mikrosekund", - "other": "{0} mikrosekunder", - }, - }, - "relative": { - "year": { - "future": { - "other": "om {0} år", - "one": "om {0} år", - }, - "past": { - "other": "för {0} år sedan", - "one": "för {0} år sedan", - }, - }, - "month": { - "future": { - "other": "om {0} månader", - "one": "om {0} månad", - }, - "past": { - "other": "för {0} månader sedan", - "one": "för {0} månad sedan", - }, - }, - "week": { - "future": { - "other": "om {0} veckor", - "one": "om {0} vecka", - }, - "past": { - "other": "för {0} veckor sedan", - "one": "för {0} vecka sedan", - }, - }, - "day": { - "future": { - "other": "om {0} dagar", - "one": "om {0} dag", - }, - "past": { - "other": "för {0} dagar sedan", - "one": "för {0} dag sedan", - }, - }, - "hour": { - "future": { - "other": "om {0} timmar", - "one": "om {0} timme", - }, - "past": { - "other": "för {0} timmar sedan", - "one": "för {0} timme sedan", - }, - }, - "minute": { - "future": { - "other": "om {0} minuter", - "one": "om {0} minut", - }, - "past": { - "other": "för {0} minuter sedan", - "one": "för {0} minut sedan", - }, - }, - "second": { - "future": { - "other": "om {0} sekunder", - "one": "om {0} sekund", - }, - "past": { - "other": "för {0} sekunder sedan", - "one": "för {0} sekund sedan", - }, - }, - }, - "day_periods": { - "midnight": "midnatt", - "am": "fm", - "pm": "em", - "morning1": "på morgonen", - "morning2": "på förmiddagen", - "afternoon1": "på eftermiddagen", - "evening1": "på kvällen", - "night1": "på natten", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/locales/zh/__init__.py b/pendulum/locales/zh/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/locales/zh/custom.py b/pendulum/locales/zh/custom.py deleted file mode 100644 index 69bc4ca..0000000 --- a/pendulum/locales/zh/custom.py +++ /dev/null @@ -1,18 +0,0 @@ -""" -zh custom locale file. -""" - -translations = { - # Relative time - "after": "{time}后", - "before": "{time}前", - # Date formats - "date_formats": { - "LTS": "Ah点m分s秒", - "LT": "Ah点mm分", - "LLLL": "YYYY年MMMD日ddddAh点mm分", - "LLL": "YYYY年MMMD日Ah点mm分", - "LL": "YYYY年MMMD日", - "L": "YYYY-MM-DD", - }, -} diff --git a/pendulum/locales/zh/locale.py b/pendulum/locales/zh/locale.py deleted file mode 100644 index 2df477f..0000000 --- a/pendulum/locales/zh/locale.py +++ /dev/null @@ -1,113 +0,0 @@ -from .custom import translations as custom_translations - - -""" -zh locale file. - -It has been generated automatically and must not be modified directly. -""" - - -locale = { - "plural": lambda n: "other", - "ordinal": lambda n: "other", - "translations": { - "days": { - "abbreviated": { - 0: "周日", - 1: "周一", - 2: "周二", - 3: "周三", - 4: "周四", - 5: "周五", - 6: "周六", - }, - "narrow": {0: "日", 1: "一", 2: "二", 3: "三", 4: "四", 5: "五", 6: "六"}, - "short": {0: "周日", 1: "周一", 2: "周二", 3: "周三", 4: "周四", 5: "周五", 6: "周六"}, - "wide": { - 0: "星期日", - 1: "星期一", - 2: "星期二", - 3: "星期三", - 4: "星期四", - 5: "星期五", - 6: "星期六", - }, - }, - "months": { - "abbreviated": { - 1: "1月", - 2: "2月", - 3: "3月", - 4: "4月", - 5: "5月", - 6: "6月", - 7: "7月", - 8: "8月", - 9: "9月", - 10: "10月", - 11: "11月", - 12: "12月", - }, - "narrow": { - 1: "1", - 2: "2", - 3: "3", - 4: "4", - 5: "5", - 6: "6", - 7: "7", - 8: "8", - 9: "9", - 10: "10", - 11: "11", - 12: "12", - }, - "wide": { - 1: "一月", - 2: "二月", - 3: "三月", - 4: "四月", - 5: "五月", - 6: "六月", - 7: "七月", - 8: "八月", - 9: "九月", - 10: "十月", - 11: "十一月", - 12: "十二月", - }, - }, - "units": { - "year": {"other": "{0}年"}, - "month": {"other": "{0}个月"}, - "week": {"other": "{0}周"}, - "day": {"other": "{0}天"}, - "hour": {"other": "{0}小时"}, - "minute": {"other": "{0}分钟"}, - "second": {"other": "{0}秒钟"}, - "microsecond": {"other": "{0}微秒"}, - }, - "relative": { - "year": {"future": {"other": "{0}年后"}, "past": {"other": "{0}年前"}}, - "month": {"future": {"other": "{0}个月后"}, "past": {"other": "{0}个月前"}}, - "week": {"future": {"other": "{0}周后"}, "past": {"other": "{0}周前"}}, - "day": {"future": {"other": "{0}天后"}, "past": {"other": "{0}天前"}}, - "hour": {"future": {"other": "{0}小时后"}, "past": {"other": "{0}小时前"}}, - "minute": {"future": {"other": "{0}分钟后"}, "past": {"other": "{0}分钟前"}}, - "second": {"future": {"other": "{0}秒钟后"}, "past": {"other": "{0}秒钟前"}}, - }, - "day_periods": { - "midnight": "午夜", - "am": "上午", - "pm": "下午", - "morning1": "清晨", - "morning2": "上午", - "afternoon1": "下午", - "afternoon2": "下午", - "evening1": "晚上", - "night1": "凌晨", - }, - }, - "custom": custom_translations, -} diff --git a/pendulum/mixins/__init__.py b/pendulum/mixins/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pendulum/mixins/default.py b/pendulum/mixins/default.py deleted file mode 100644 index 59f985e..0000000 --- a/pendulum/mixins/default.py +++ /dev/null @@ -1,36 +0,0 @@ -from __future__ import annotations - -from pendulum.formatting import Formatter - -_formatter = Formatter() - - -class FormattableMixin: - _formatter: Formatter = _formatter - - def format(self, fmt: str, locale: str | None = None) -> str: - """ - Formats the instance using the given format. - - :param fmt: The format to use - :param locale: The locale to use - """ - return self._formatter.format(self, fmt, locale) - - def for_json(self) -> str: - """ - Methods for automatic json serialization by simplejson. - """ - return str(self) - - def __format__(self, format_spec: str) -> str: - if len(format_spec) > 0: - if "%" in format_spec: - return self.strftime(format_spec) - - return self.format(format_spec) - - return str(self) - - def __str__(self) -> str: - return self.isoformat() diff --git a/pendulum/parser.py b/pendulum/parser.py deleted file mode 100644 index 77900e2..0000000 --- a/pendulum/parser.py +++ /dev/null @@ -1,124 +0,0 @@ -from __future__ import annotations - -import datetime -import typing as t - -import pendulum - -from pendulum.parsing import _Interval -from pendulum.parsing import parse as base_parse -from pendulum.tz.timezone import UTC - -if t.TYPE_CHECKING: - from pendulum.date import Date - from pendulum.datetime import DateTime - from pendulum.duration import Duration - from pendulum.interval import Interval - from pendulum.time import Time - -try: - from pendulum.parsing._iso8601 import Duration as CDuration -except ImportError: - CDuration = None # type: ignore[misc, assignment] - - -def parse(text: str, **options: t.Any) -> Date | Time | DateTime | Duration: - # Use the mock now value if it exists - options["now"] = options.get("now") - - return _parse(text, **options) - - -def _parse(text: str, **options: t.Any) -> Date | DateTime | Time | Duration | Interval: - """ - Parses a string with the given options. - - :param text: The string to parse. - """ - # Handling special cases - if text == "now": - return pendulum.now() - - parsed = base_parse(text, **options) - - if isinstance(parsed, datetime.datetime): - return pendulum.datetime( - parsed.year, - parsed.month, - parsed.day, - parsed.hour, - parsed.minute, - parsed.second, - parsed.microsecond, - tz=parsed.tzinfo or options.get("tz", UTC), - ) - - if isinstance(parsed, datetime.date): - return pendulum.date(parsed.year, parsed.month, parsed.day) - - if isinstance(parsed, datetime.time): - return pendulum.time( - parsed.hour, parsed.minute, parsed.second, parsed.microsecond - ) - - if isinstance(parsed, _Interval): - if parsed.duration is not None: - duration = parsed.duration - - if parsed.start is not None: - dt = pendulum.instance(parsed.start, tz=options.get("tz", UTC)) - - return pendulum.interval( - dt, - dt.add( - years=duration.years, - months=duration.months, - weeks=duration.weeks, - days=duration.remaining_days, - hours=duration.hours, - minutes=duration.minutes, - seconds=duration.remaining_seconds, - microseconds=duration.microseconds, - ), - ) - - dt = pendulum.instance( - t.cast(datetime.datetime, parsed.end), tz=options.get("tz", UTC) - ) - - return pendulum.interval( - dt.subtract( - years=duration.years, - months=duration.months, - weeks=duration.weeks, - days=duration.remaining_days, - hours=duration.hours, - minutes=duration.minutes, - seconds=duration.remaining_seconds, - microseconds=duration.microseconds, - ), - dt, - ) - - return pendulum.interval( - pendulum.instance( - t.cast(datetime.datetime, parsed.start), tz=options.get("tz", UTC) - ), - pendulum.instance( - t.cast(datetime.datetime, parsed.end), tz=options.get("tz", UTC) - ), - ) - - if CDuration and isinstance(parsed, CDuration): - return pendulum.duration( - years=parsed.years, - months=parsed.months, - weeks=parsed.weeks, - days=parsed.days, - hours=parsed.hours, - minutes=parsed.minutes, - seconds=parsed.seconds, - microseconds=parsed.microseconds, - ) - - return parsed diff --git a/pendulum/parsing/__init__.py b/pendulum/parsing/__init__.py deleted file mode 100644 index 0e64065..0000000 --- a/pendulum/parsing/__init__.py +++ /dev/null @@ -1,233 +0,0 @@ -from __future__ import annotations - -import contextlib -import copy -import os -import re -import struct - -from datetime import date -from datetime import datetime -from datetime import time -from typing import Any -from typing import Optional -from typing import cast - -from dateutil import parser - -from pendulum.parsing.exceptions import ParserError - -with_extensions = os.getenv("PENDULUM_EXTENSIONS", "1") == "1" - -try: - if not with_extensions or struct.calcsize("P") == 4: - raise ImportError() - - from pendulum.parsing._iso8601 import Duration - from pendulum.parsing._iso8601 import parse_iso8601 -except ImportError: - from pendulum.duration import Duration # type: ignore[misc] - from pendulum.parsing.iso8601 import parse_iso8601 # type: ignore[misc] - -COMMON = re.compile( - # Date (optional) # noqa: E800 - "^" - "(?P" - " (?P" # Classic date (YYYY-MM-DD) - r" (?P\d{4})" # Year - " (?P" - r" (?P[/:])?(?P\d{2})" # Month (optional) - r" ((?P[/:])?(?P\d{2}))" # Day (optional) - " )?" - " )" - ")?" - # Time (optional) # noqa: E800 - "(?P