Showing preview only (767K chars total). Download the full file or copy to clipboard to get everything.
Repository: arrow-py/arrow
Branch: master
Commit: b423717da81a
Files: 50
Total size: 741.6 KB
Directory structure:
gitextract_jsvx0o33/
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── documentation.md
│ │ └── feature_request.md
│ ├── dependabot.yml
│ ├── pull_request_template.md
│ └── workflows/
│ ├── continuous_integration.yml
│ └── release.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .readthedocs.yaml
├── CHANGELOG.rst
├── LICENSE
├── Makefile
├── README.rst
├── arrow/
│ ├── __init__.py
│ ├── _version.py
│ ├── api.py
│ ├── arrow.py
│ ├── constants.py
│ ├── factory.py
│ ├── formatter.py
│ ├── locales.py
│ ├── parser.py
│ ├── py.typed
│ └── util.py
├── docs/
│ ├── Makefile
│ ├── api-guide.rst
│ ├── conf.py
│ ├── getting-started.rst
│ ├── guide.rst
│ ├── index.rst
│ ├── make.bat
│ └── releases.rst
├── pyproject.toml
├── requirements/
│ ├── requirements-docs.txt
│ ├── requirements-tests.txt
│ └── requirements.txt
├── setup.cfg
├── tests/
│ ├── __init__.py
│ ├── conftest.py
│ ├── test_api.py
│ ├── test_arrow.py
│ ├── test_factory.py
│ ├── test_formatter.py
│ ├── test_locales.py
│ ├── test_parser.py
│ ├── test_util.py
│ └── utils.py
└── tox.ini
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
open_collective: arrow
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: "🐞 Bug Report"
about: Find a bug? Create a report to help us improve.
title: ''
labels: 'bug'
assignees: ''
---
<!--
Thanks for taking the time to submit this bug report.
Please provide us with a detailed description of the bug and a bit of information about your system.
-->
## Issue Description
<!--
Replace this comment block with a description of the bug.
Be sure to include details such as the expected and actual outcomes.
-->
## System Info
- 🖥 **OS name and version**: <!-- Replace with OS name and version (e.g. macOS 10.15.7). -->
- 🐍 **Python version**: <!-- Replace with Python version (e.g. Python 3.8.5). -->
- 🏹 **Arrow version**: <!-- Replace with Arrow version. Run arrow.__version__ to find out! -->
================================================
FILE: .github/ISSUE_TEMPLATE/documentation.md
================================================
---
name: "📚 Documentation"
about: Find errors or problems in the docs (https://arrow.readthedocs.io)?
title: ''
labels: 'documentation'
assignees: ''
---
<!--
Thanks for taking the time to submit documentation feedback.
Please provide us with a detailed description of the documentation issue.
-->
## Issue Description
<!-- Replace this comment block with a description of the documentation issue. -->
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: "💡 Feature Request"
about: Have an idea for a new feature or improvement?
title: ''
labels: 'enhancement'
assignees: ''
---
<!--
Thanks for taking the time to submit this feature request.
Please provide us with a detailed description of the potential improvement.
-->
## Feature Request
<!-- Replace this comment block with a description of the potential improvement. -->
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
================================================
FILE: .github/pull_request_template.md
================================================
## Pull Request Checklist
Thank you for taking the time to improve Arrow! Before submitting your pull request, please check all *appropriate* boxes:
<!-- Check boxes by placing an x in the brackets like this: [x] -->
- [ ] 🧪 Added **tests** for changed code.
- [ ] 🛠️ All tests **pass** when run locally (run `tox` or `make test` to find out!).
- [ ] 🧹 All linting checks **pass** when run locally (run `tox -e lint` or `make lint` to find out!).
- [ ] 📚 Updated **documentation** for changed code.
- [ ] ⏩ Code is **up-to-date** with the `master` branch.
If you have *any* questions about your code changes or any of the points above, please submit your questions along with the pull request and we will try our best to help!
## Description of Changes
<!--
Replace this commented text block with a description of your code changes.
If your PR has an associated issue, insert the issue number (e.g. #703) or directly link to the GitHub issue (e.g. https://github.com/arrow-py/arrow/issues/703).
Pro-tip: writing "Closes: #703" in the PR body will automatically close issue #703 when the PR is merged.
-->
================================================
FILE: .github/workflows/continuous_integration.yml
================================================
name: tests
on:
pull_request: # Run on all pull requests
push: # Run only on pushes to master
branches:
- master
schedule: # Run monthly
- cron: "0 0 1 * *"
jobs:
unit-tests:
name: ${{ matrix.os }} (${{ matrix.python-version }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
python-version: ["pypy-3.11", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
os: [ubuntu-latest, macos-latest, windows-latest]
include:
- os: ubuntu-latest
path: ~/.cache/pip
- os: macos-latest
path: ~/Library/Caches/pip
- os: windows-latest
path: ~\AppData\Local\pip\Cache
steps:
- uses: actions/checkout@v6
- name: Cache pip
uses: actions/cache@v5
with:
path: ${{ matrix.path }}
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
restore-keys: ${{ runner.os }}-pip-
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install -U pip setuptools wheel
pip install -U tox tox-gh-actions
- name: Test with tox
run: tox
- name: Upload coverage to Codecov
if: ${{ success() }}
uses: codecov/codecov-action@v5
with:
files: coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
- name: Upload test results to Codecov
if: ${{ !cancelled() }}
uses: codecov/test-results-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
linting:
name: Linting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/cache@v5
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
restore-keys: ${{ runner.os }}-pip-
- uses: actions/cache@v5
with:
path: ~/.cache/pre-commit
key: ${{ runner.os }}-pre-commit-${{ hashFiles('**/.pre-commit-config.yaml') }}
restore-keys: ${{ runner.os }}-pre-commit-
- name: Set up Python ${{ runner.python-version }}
uses: actions/setup-python@v6
with:
python-version: "3.11"
- name: Install dependencies
run: |
pip install -U pip setuptools wheel
pip install -U tox
- name: Lint code
run: tox -e lint -- --show-diff-on-failure
- name: Lint docs
run: tox -e docs
================================================
FILE: .github/workflows/release.yml
================================================
name: release
on:
workflow_dispatch: # run manually
push: # run on matching tags
tags:
- '*.*.*'
jobs:
release-to-pypi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/cache@v5
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
restore-keys: ${{ runner.os }}-pip-
- uses: actions/setup-python@v6
with:
python-version: "3.14"
- name: Install dependencies
run: |
pip install -U pip setuptools wheel
pip install -U tox
- name: Publish package to PyPI
env:
FLIT_USERNAME: __token__
FLIT_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: tox -e publish
================================================
FILE: .gitignore
================================================
README.rst.new
# Small entry point file for debugging tasks
test.py
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
junit.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
local/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# Swap
[._]*.s[a-v][a-z]
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]
# Session
Session.vim
Sessionx.vim
# Temporary
.netrwhist
*~
# Auto-generated tag files
tags
# Persistent undo
[._]*.un~
.idea/
.vscode/
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# Claude Code configurations
CLAUDE*.md
.claude/
# Kiro
.kiro/**
================================================
FILE: .pre-commit-config.yaml
================================================
default_language_version:
python: python3
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-ast
- id: check-yaml
- id: check-case-conflict
- id: check-docstring-first
- id: check-merge-conflict
- id: check-builtin-literals
- id: debug-statements
- id: end-of-file-fixer
- id: requirements-txt-fixer
args: [requirements/requirements.txt, requirements/requirements-docs.txt, requirements/requirements-tests.txt]
- id: trailing-whitespace
- repo: https://github.com/timothycrosley/isort
rev: 7.0.0
hooks:
- id: isort
- repo: https://github.com/asottile/pyupgrade
rev: v3.21.2
hooks:
- id: pyupgrade
args: [--py36-plus]
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
hooks:
- id: python-no-eval
- id: python-check-blanket-noqa
- id: python-check-mock-methods
- id: python-use-type-annotations
- id: rst-backticks
- id: rst-directive-colons
- id: rst-inline-touching-normal
- id: text-unicode-replacement-char
- repo: https://github.com/psf/black
rev: 25.12.0
hooks:
- id: black
args: [--safe, --quiet, --target-version=py36]
- repo: https://github.com/pycqa/flake8
rev: 7.3.0
hooks:
- id: flake8
additional_dependencies: [flake8-bugbear,flake8-annotations]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.19.0
hooks:
- id: mypy
args: [--cache-fine-grained, --show-error-codes]
additional_dependencies: [types-python-dateutil]
================================================
FILE: .readthedocs.yaml
================================================
# Read the Docs configuration file for Sphinx projects
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
version: 2
build:
os: ubuntu-22.04
tools:
python: "3.11"
# Build documentation in the "docs/" directory with Sphinx
sphinx:
configuration: docs/conf.py
# You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs
# builder: "dirhtml"
# Fail on all warnings to avoid broken references
# fail_on_warning: true
# Optionally build your docs in additional formats such as PDF and ePub
# formats:
# - pdf
# - epub
# Optional but recommended, declare the Python requirements required
# to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- requirements: requirements/requirements-docs.txt
================================================
FILE: CHANGELOG.rst
================================================
Changelog
=========
1.4.0 (2025-10-18)
------------------
- [ADDED] Added ``week_start`` parameter to ``floor()`` and ``ceil()`` methods. `PR #1222 <https://github.com/arrow-py/arrow/pull/1222>`_
- [ADDED] Added ``FORMAT_RFC3339_STRICT`` with a T separator. `PR #1201 <https://github.com/arrow-py/arrow/pull/1201>`_
- [ADDED] Added Macedonian in Latin locale support. `PR #1200 <https://github.com/arrow-py/arrow/pull/1200>`_
- [ADDED] Added Persian/Farsi locale support. `PR #1190 <https://github.com/arrow-py/arrow/pull/1190>`_
- [ADDED] Added week and weeks to Thai locale timeframes. `PR #1218 <https://github.com/arrow-py/arrow/pull/1218>`_
- [ADDED] Added weeks to Catalan locale. `PR #1189 <https://github.com/arrow-py/arrow/pull/1189>`_
- [ADDED] Added Persian names of months, month-abbreviations and day-abbreviations in Gregorian calendar. `PR #1172 <https://github.com/arrow-py/arrow/pull/1172>`_
- [CHANGED] Migrated Arrow to use ZoneInfo for timezones instead of pytz. `PR #1217 <https://github.com/arrow-py/arrow/pull/1217>`_
- [FIXED] Fixed humanize month limits. `PR #1224 <https://github.com/arrow-py/arrow/pull/1224>`_
- [FIXED] Fixed type hint of ``Arrow.__getattr__``. `PR #1171 <https://github.com/arrow-py/arrow/pull/1171>`_
- [FIXED] Fixed spelling and removed poorly used expressions in Korean locale. `PR #1181 <https://github.com/arrow-py/arrow/pull/1181>`_
- [FIXED] Updated ``shift()`` method for issue #1145. `PR #1194 <https://github.com/arrow-py/arrow/pull/1194>`_
- [FIXED] Improved Greek locale translations (seconds, days, "ago", and month typo). `PR #1184 <https://github.com/arrow-py/arrow/pull/1184>`_, `PR #1186 <https://github.com/arrow-py/arrow/pull/1186>`_
- [FIXED] Addressed ``datetime.utcnow`` deprecation warning. `PR #1182 <https://github.com/arrow-py/arrow/pull/1182>`_
- [INTERNAL] Added codecov test results. `PR #1223 <https://github.com/arrow-py/arrow/pull/1223>`_
- [INTERNAL] Updated CI dependencies (actions/setup-python, actions/checkout, codecov/codecov-action, actions/cache).
- [INTERNAL] Added docstrings to parser.py. `PR #1010 <https://github.com/arrow-py/arrow/pull/1010>`_
- [INTERNAL] Updated Python versions support and bumped CI dependencies. `PR #1177 <https://github.com/arrow-py/arrow/pull/1177>`_
- [INTERNAL] Added dependabot for GitHub actions. `PR #1193 <https://github.com/arrow-py/arrow/pull/1193>`_
- [INTERNAL] Moved dateutil types to test requirements. `PR #1183 <https://github.com/arrow-py/arrow/pull/1183>`_
- [INTERNAL] Added documentation link for ``arrow.format``. `PR #1180 <https://github.com/arrow-py/arrow/pull/1180>`_
1.3.0 (2023-09-30)
------------------
- [ADDED] Added official support for Python 3.11 and 3.12.
- [ADDED] Added dependency on ``types-python-dateutil`` to improve Arrow mypy compatibility. `PR #1102 <https://github.com/arrow-py/arrow/pull/1102>`_
- [FIX] Updates to Italian, Romansh, Hungarian, Finish and Arabic locales.
- [FIX] Handling parsing of UTC prefix in timezone strings.
- [CHANGED] Update documentation to improve readability.
- [CHANGED] Dropped support for Python 3.6 and 3.7, which are end-of-life.
- [INTERNAL] Migrate from ``setup.py``/Twine to ``pyproject.toml``/Flit for packaging and distribution.
- [INTERNAL] Adopt ``.readthedocs.yaml`` configuration file for continued ReadTheDocs support.
1.2.3 (2022-06-25)
------------------
- [NEW] Added Amharic, Armenian, Georgian, Laotian and Uzbek locales.
- [FIX] Updated Danish locale and associated tests.
- [INTERNAL] Small fixes to CI.
1.2.2 (2022-01-19)
------------------
- [NEW] Added Kazakh locale.
- [FIX] The Belarusian, Bulgarian, Czech, Macedonian, Polish, Russian, Slovak and Ukrainian locales now support ``dehumanize``.
- [FIX] Minor bug fixes and improvements to ChineseCN, Indonesian, Norwegian, and Russian locales.
- [FIX] Expanded testing for multiple locales.
- [INTERNAL] Started using ``xelatex`` for pdf generation in documentation.
- [INTERNAL] Split requirements file into ``requirements.txt``, ``requirements-docs.txt`` and ``requirements-tests.txt``.
- [INTERNAL] Added ``flake8-annotations`` package for type linting in ``pre-commit``.
1.2.1 (2021-10-24)
------------------
- [NEW] Added quarter granularity to humanize, for example:
.. code-block:: python
>>> import arrow
>>> now = arrow.now()
>>> four_month_shift = now.shift(months=4)
>>> now.humanize(four_month_shift, granularity="quarter")
'a quarter ago'
>>> four_month_shift.humanize(now, granularity="quarter")
'in a quarter'
>>> thirteen_month_shift = now.shift(months=13)
>>> thirteen_month_shift.humanize(now, granularity="quarter")
'in 4 quarters'
>>> now.humanize(thirteen_month_shift, granularity="quarter")
'4 quarters ago'
- [NEW] Added Sinhala and Urdu locales.
- [NEW] Added official support for Python 3.10.
- [CHANGED] Updated Azerbaijani, Hebrew, and Serbian locales and added tests.
- [CHANGED] Passing an empty granularity list to ``humanize`` now raises a ``ValueError``.
1.2.0 (2021-09-12)
------------------
- [NEW] Added Albanian, Tamil and Zulu locales.
- [NEW] Added support for ``Decimal`` as input to ``arrow.get()``.
- [FIX] The Estonian, Finnish, Nepali and Zulu locales now support ``dehumanize``.
- [FIX] Improved validation checks when using parser tokens ``A`` and ``hh``.
- [FIX] Minor bug fixes to Catalan, Cantonese, Greek and Nepali locales.
1.1.1 (2021-06-24)
------------------
- [NEW] Added Odia, Maltese, Serbian, Sami, and Luxembourgish locales.
- [FIXED] All calls to ``arrow.get()`` should now properly pass the ``tzinfo`` argument to the Arrow constructor. See PR `#968 <https://github.com/arrow-py/arrow/pull/968/>`_ for more info.
- [FIXED] Humanize output is now properly truncated when a locale class overrides ``_format_timeframe()``.
- [CHANGED] Renamed ``requirements.txt`` to ``requirements-dev.txt`` to prevent confusion with the dependencies in ``setup.py``.
- [CHANGED] Updated Turkish locale and added tests.
1.1.0 (2021-04-26)
------------------
- [NEW] Implemented the ``dehumanize`` method for ``Arrow`` objects. This takes human readable input and uses it to perform relative time shifts, for example:
.. code-block:: python
>>> arw
<Arrow [2021-04-26T21:06:14.256803+00:00]>
>>> arw.dehumanize("8 hours ago")
<Arrow [2021-04-26T13:06:14.256803+00:00]>
>>> arw.dehumanize("in 4 days")
<Arrow [2021-04-30T21:06:14.256803+00:00]>
>>> arw.dehumanize("in an hour 34 minutes 10 seconds")
<Arrow [2021-04-26T22:40:24.256803+00:00]>
>>> arw.dehumanize("hace 2 años", locale="es")
<Arrow [2019-04-26T21:06:14.256803+00:00]>
- [NEW] Made the start of the week adjustable when using ``span("week")``, for example:
.. code-block:: python
>>> arw
<Arrow [2021-04-26T21:06:14.256803+00:00]>
>>> arw.isoweekday()
1 # Monday
>>> arw.span("week")
(<Arrow [2021-04-26T00:00:00+00:00]>, <Arrow [2021-05-02T23:59:59.999999+00:00]>)
>>> arw.span("week", week_start=4)
(<Arrow [2021-04-22T00:00:00+00:00]>, <Arrow [2021-04-28T23:59:59.999999+00:00]>)
- [NEW] Added Croatian, Latin, Latvian, Lithuanian and Malay locales.
- [FIX] Internally standardize locales and improve locale validation. Locales should now use the ISO notation of a dash (``"en-gb"``) rather than an underscore (``"en_gb"``) however this change is backward compatible.
- [FIX] Correct type checking for internal locale mapping by using ``_init_subclass``. This now allows subclassing of locales, for example:
.. code-block:: python
>>> from arrow.locales import EnglishLocale
>>> class Klingon(EnglishLocale):
... names = ["tlh"]
...
>>> from arrow import locales
>>> locales.get_locale("tlh")
<__main__.Klingon object at 0x7f7cd1effd30>
- [FIX] Correct type checking for ``arrow.get(2021, 3, 9)`` construction.
- [FIX] Audited all docstrings for style, typos and outdated info.
1.0.3 (2021-03-05)
------------------
- [FIX] Updated internals to avoid issues when running ``mypy --strict``.
- [FIX] Corrections to Swedish locale.
- [INTERNAL] Lowered required coverage limit until ``humanize`` month tests are fixed.
1.0.2 (2021-02-28)
------------------
- [FIXED] Fixed an ``OverflowError`` that could occur when running Arrow on a 32-bit OS.
1.0.1 (2021-02-27)
------------------
- [FIXED] A ``py.typed`` file is now bundled with the Arrow package to conform to PEP 561.
1.0.0 (2021-02-26)
------------------
After 8 years we're pleased to announce Arrow v1.0. Thanks to the entire Python community for helping make Arrow the amazing package it is today!
- [CHANGE] Arrow has **dropped support** for Python 2.7 and 3.5.
- [CHANGE] There are multiple **breaking changes** with this release, please see the `migration guide <https://github.com/arrow-py/arrow/issues/832>`_ for a complete overview.
- [CHANGE] Arrow is now following `semantic versioning <https://semver.org/>`_.
- [CHANGE] Made ``humanize`` granularity="auto" limits more accurate to reduce strange results.
- [NEW] Added support for Python 3.9.
- [NEW] Added a new keyword argument "exact" to ``span``, ``span_range`` and ``interval`` methods. This makes timespans begin at the start time given and not extend beyond the end time given, for example:
.. code-block:: python
>>> start = Arrow(2021, 2, 5, 12, 30)
>>> end = Arrow(2021, 2, 5, 17, 15)
>>> for r in arrow.Arrow.span_range('hour', start, end, exact=True):
... print(r)
...
(<Arrow [2021-02-05T12:30:00+00:00]>, <Arrow [2021-02-05T13:29:59.999999+00:00]>)
(<Arrow [2021-02-05T13:30:00+00:00]>, <Arrow [2021-02-05T14:29:59.999999+00:00]>)
(<Arrow [2021-02-05T14:30:00+00:00]>, <Arrow [2021-02-05T15:29:59.999999+00:00]>)
(<Arrow [2021-02-05T15:30:00+00:00]>, <Arrow [2021-02-05T16:29:59.999999+00:00]>)
(<Arrow [2021-02-05T16:30:00+00:00]>, <Arrow [2021-02-05T17:14:59.999999+00:00]>)
- [NEW] Arrow now natively supports PEP 484-style type annotations.
- [FIX] Fixed handling of maximum permitted timestamp on Windows systems.
- [FIX] Corrections to French, German, Japanese and Norwegian locales.
- [INTERNAL] Raise more appropriate errors when string parsing fails to match.
0.17.0 (2020-10-2)
-------------------
- [WARN] Arrow will **drop support** for Python 2.7 and 3.5 in the upcoming 1.0.0 release. This is the last major release to support Python 2.7 and Python 3.5.
- [NEW] Arrow now properly handles imaginary datetimes during DST shifts. For example:
.. code-block:: python
>>> just_before = arrow.get(2013, 3, 31, 1, 55, tzinfo="Europe/Paris")
>>> just_before.shift(minutes=+10)
<Arrow [2013-03-31T03:05:00+02:00]>
.. code-block:: python
>>> before = arrow.get("2018-03-10 23:00:00", "YYYY-MM-DD HH:mm:ss", tzinfo="US/Pacific")
>>> after = arrow.get("2018-03-11 04:00:00", "YYYY-MM-DD HH:mm:ss", tzinfo="US/Pacific")
>>> result=[(t, t.to("utc")) for t in arrow.Arrow.range("hour", before, after)]
>>> for r in result:
... print(r)
...
(<Arrow [2018-03-10T23:00:00-08:00]>, <Arrow [2018-03-11T07:00:00+00:00]>)
(<Arrow [2018-03-11T00:00:00-08:00]>, <Arrow [2018-03-11T08:00:00+00:00]>)
(<Arrow [2018-03-11T01:00:00-08:00]>, <Arrow [2018-03-11T09:00:00+00:00]>)
(<Arrow [2018-03-11T03:00:00-07:00]>, <Arrow [2018-03-11T10:00:00+00:00]>)
(<Arrow [2018-03-11T04:00:00-07:00]>, <Arrow [2018-03-11T11:00:00+00:00]>)
- [NEW] Added ``humanize`` week granularity translation for Tagalog.
- [CHANGE] Calls to the ``timestamp`` property now emit a ``DeprecationWarning``. In a future release, ``timestamp`` will be changed to a method to align with Python's datetime module. If you would like to continue using the property, please change your code to use the ``int_timestamp`` or ``float_timestamp`` properties instead.
- [CHANGE] Expanded and improved Catalan locale.
- [FIX] Fixed a bug that caused ``Arrow.range()`` to incorrectly cut off ranges in certain scenarios when using month, quarter, or year endings.
- [FIX] Fixed a bug that caused day of week token parsing to be case sensitive.
- [INTERNAL] A number of functions were reordered in arrow.py for better organization and grouping of related methods. This change will have no impact on usage.
- [INTERNAL] A minimum tox version is now enforced for compatibility reasons. Contributors must use tox >3.18.0 going forward.
0.16.0 (2020-08-23)
-------------------
- [WARN] Arrow will **drop support** for Python 2.7 and 3.5 in the upcoming 1.0.0 release. The 0.16.x and 0.17.x releases are the last to support Python 2.7 and 3.5.
- [NEW] Implemented `PEP 495 <https://www.python.org/dev/peps/pep-0495/>`_ to handle ambiguous datetimes. This is achieved by the addition of the ``fold`` attribute for Arrow objects. For example:
.. code-block:: python
>>> before = Arrow(2017, 10, 29, 2, 0, tzinfo='Europe/Stockholm')
<Arrow [2017-10-29T02:00:00+02:00]>
>>> before.fold
0
>>> before.ambiguous
True
>>> after = Arrow(2017, 10, 29, 2, 0, tzinfo='Europe/Stockholm', fold=1)
<Arrow [2017-10-29T02:00:00+01:00]>
>>> after = before.replace(fold=1)
<Arrow [2017-10-29T02:00:00+01:00]>
- [NEW] Added ``normalize_whitespace`` flag to ``arrow.get``. This is useful for parsing log files and/or any files that may contain inconsistent spacing. For example:
.. code-block:: python
>>> arrow.get("Jun 1 2005 1:33PM", "MMM D YYYY H:mmA", normalize_whitespace=True)
<Arrow [2005-06-01T13:33:00+00:00]>
>>> arrow.get("2013-036 \t 04:05:06Z", normalize_whitespace=True)
<Arrow [2013-02-05T04:05:06+00:00]>
0.15.8 (2020-07-23)
-------------------
- [WARN] Arrow will **drop support** for Python 2.7 and 3.5 in the upcoming 1.0.0 release. The 0.15.x, 0.16.x, and 0.17.x releases are the last to support Python 2.7 and 3.5.
- [NEW] Added ``humanize`` week granularity translation for Czech.
- [FIX] ``arrow.get`` will now pick sane defaults when weekdays are passed with particular token combinations, see `#446 <https://github.com/arrow-py/arrow/issues/446>`_.
- [INTERNAL] Moved arrow to an organization. The repo can now be found `here <https://github.com/arrow-py/arrow>`_.
- [INTERNAL] Started issuing deprecation warnings for Python 2.7 and 3.5.
- [INTERNAL] Added Python 3.9 to CI pipeline.
0.15.7 (2020-06-19)
-------------------
- [NEW] Added a number of built-in format strings. See the `docs <https://arrow.readthedocs.io/#built-in-formats>`_ for a complete list of supported formats. For example:
.. code-block:: python
>>> arw = arrow.utcnow()
>>> arw.format(arrow.FORMAT_COOKIE)
'Wednesday, 27-May-2020 10:30:35 UTC'
- [NEW] Arrow is now fully compatible with Python 3.9 and PyPy3.
- [NEW] Added Makefile, tox.ini, and requirements.txt files to the distribution bundle.
- [NEW] Added French Canadian and Swahili locales.
- [NEW] Added ``humanize`` week granularity translation for Hebrew, Greek, Macedonian, Swedish, Slovak.
- [FIX] ms and μs timestamps are now normalized in ``arrow.get()``, ``arrow.fromtimestamp()``, and ``arrow.utcfromtimestamp()``. For example:
.. code-block:: python
>>> ts = 1591161115194556
>>> arw = arrow.get(ts)
<Arrow [2020-06-03T05:11:55.194556+00:00]>
>>> arw.timestamp
1591161115
- [FIX] Refactored and updated Macedonian, Hebrew, Korean, and Portuguese locales.
0.15.6 (2020-04-29)
-------------------
- [NEW] Added support for parsing and formatting `ISO 8601 week dates <https://en.wikipedia.org/wiki/ISO_week_date>`_ via a new token ``W``, for example:
.. code-block:: python
>>> arrow.get("2013-W29-6", "W")
<Arrow [2013-07-20T00:00:00+00:00]>
>>> utc=arrow.utcnow()
>>> utc
<Arrow [2020-01-23T18:37:55.417624+00:00]>
>>> utc.format("W")
'2020-W04-4'
- [NEW] Formatting with ``x`` token (microseconds) is now possible, for example:
.. code-block:: python
>>> dt = arrow.utcnow()
>>> dt.format("x")
'1585669870688329'
>>> dt.format("X")
'1585669870'
- [NEW] Added ``humanize`` week granularity translation for German, Italian, Polish & Taiwanese locales.
- [FIX] Consolidated and simplified German locales.
- [INTERNAL] Moved testing suite from nosetest/Chai to pytest/pytest-mock.
- [INTERNAL] Converted xunit-style setup and teardown functions in tests to pytest fixtures.
- [INTERNAL] Setup GitHub Actions for CI alongside Travis.
- [INTERNAL] Help support Arrow's future development by donating to the project on `Open Collective <https://opencollective.com/arrow>`_.
0.15.5 (2020-01-03)
-------------------
- [WARN] Python 2 reached EOL on 2020-01-01. arrow will **drop support** for Python 2 in a future release to be decided (see `#739 <https://github.com/arrow-py/arrow/issues/739>`_).
- [NEW] Added bounds parameter to ``span_range``, ``interval`` and ``span`` methods. This allows you to include or exclude the start and end values.
- [NEW] ``arrow.get()`` can now create arrow objects from a timestamp with a timezone, for example:
.. code-block:: python
>>> arrow.get(1367900664, tzinfo=tz.gettz('US/Pacific'))
<Arrow [2013-05-06T21:24:24-07:00]>
- [NEW] ``humanize`` can now combine multiple levels of granularity, for example:
.. code-block:: python
>>> later140 = arrow.utcnow().shift(seconds=+8400)
>>> later140.humanize(granularity="minute")
'in 139 minutes'
>>> later140.humanize(granularity=["hour", "minute"])
'in 2 hours and 19 minutes'
- [NEW] Added Hong Kong locale (``zh_hk``).
- [NEW] Added ``humanize`` week granularity translation for Dutch.
- [NEW] Numbers are now displayed when using the seconds granularity in ``humanize``.
- [CHANGE] ``range`` now supports both the singular and plural forms of the ``frames`` argument (e.g. day and days).
- [FIX] Improved parsing of strings that contain punctuation.
- [FIX] Improved behaviour of ``humanize`` when singular seconds are involved.
0.15.4 (2019-11-02)
-------------------
- [FIX] Fixed an issue that caused package installs to fail on Conda Forge.
0.15.3 (2019-11-02)
-------------------
- [NEW] ``factory.get()`` can now create arrow objects from a ISO calendar tuple, for example:
.. code-block:: python
>>> arrow.get((2013, 18, 7))
<Arrow [2013-05-05T00:00:00+00:00]>
- [NEW] Added a new token ``x`` to allow parsing of integer timestamps with milliseconds and microseconds.
- [NEW] Formatting now supports escaping of characters using the same syntax as parsing, for example:
.. code-block:: python
>>> arw = arrow.now()
>>> fmt = "YYYY-MM-DD h [h] m"
>>> arw.format(fmt)
'2019-11-02 3 h 32'
- [NEW] Added ``humanize`` week granularity translations for Chinese, Spanish and Vietnamese.
- [CHANGE] Added ``ParserError`` to module exports.
- [FIX] Added support for midnight at end of day. See `#703 <https://github.com/arrow-py/arrow/issues/703>`_ for details.
- [INTERNAL] Created Travis build for macOS.
- [INTERNAL] Test parsing and formatting against full timezone database.
0.15.2 (2019-09-14)
-------------------
- [NEW] Added ``humanize`` week granularity translations for Portuguese and Brazilian Portuguese.
- [NEW] Embedded changelog within docs and added release dates to versions.
- [FIX] Fixed a bug that caused test failures on Windows only, see `#668 <https://github.com/arrow-py/arrow/issues/668>`_ for details.
0.15.1 (2019-09-10)
-------------------
- [NEW] Added ``humanize`` week granularity translations for Japanese.
- [FIX] Fixed a bug that caused Arrow to fail when passed a negative timestamp string.
- [FIX] Fixed a bug that caused Arrow to fail when passed a datetime object with ``tzinfo`` of type ``StaticTzInfo``.
0.15.0 (2019-09-08)
-------------------
- [NEW] Added support for DDD and DDDD ordinal date tokens. The following functionality is now possible: ``arrow.get("1998-045")``, ``arrow.get("1998-45", "YYYY-DDD")``, ``arrow.get("1998-045", "YYYY-DDDD")``.
- [NEW] ISO 8601 basic format for dates and times is now supported (e.g. ``YYYYMMDDTHHmmssZ``).
- [NEW] Added ``humanize`` week granularity translations for French, Russian and Swiss German locales.
- [CHANGE] Timestamps of type ``str`` are no longer supported **without a format string** in the ``arrow.get()`` method. This change was made to support the ISO 8601 basic format and to address bugs such as `#447 <https://github.com/arrow-py/arrow/issues/447>`_.
The following will NOT work in v0.15.0:
.. code-block:: python
>>> arrow.get("1565358758")
>>> arrow.get("1565358758.123413")
The following will work in v0.15.0:
.. code-block:: python
>>> arrow.get("1565358758", "X")
>>> arrow.get("1565358758.123413", "X")
>>> arrow.get(1565358758)
>>> arrow.get(1565358758.123413)
- [CHANGE] When a meridian token (a|A) is passed and no meridians are available for the specified locale (e.g. unsupported or untranslated) a ``ParserError`` is raised.
- [CHANGE] The timestamp token (``X``) will now match float timestamps of type ``str``: ``arrow.get(“1565358758.123415”, “X”)``.
- [CHANGE] Strings with leading and/or trailing whitespace will no longer be parsed without a format string. Please see `the docs <https://arrow.readthedocs.io/#regular-expressions>`_ for ways to handle this.
- [FIX] The timestamp token (``X``) will now only match on strings that **strictly contain integers and floats**, preventing incorrect matches.
- [FIX] Most instances of ``arrow.get()`` returning an incorrect ``Arrow`` object from a partial parsing match have been eliminated. The following issue have been addressed: `#91 <https://github.com/arrow-py/arrow/issues/91>`_, `#196 <https://github.com/arrow-py/arrow/issues/196>`_, `#396 <https://github.com/arrow-py/arrow/issues/396>`_, `#434 <https://github.com/arrow-py/arrow/issues/434>`_, `#447 <https://github.com/arrow-py/arrow/issues/447>`_, `#456 <https://github.com/arrow-py/arrow/issues/456>`_, `#519 <https://github.com/arrow-py/arrow/issues/519>`_, `#538 <https://github.com/arrow-py/arrow/issues/538>`_, `#560 <https://github.com/arrow-py/arrow/issues/560>`_.
0.14.7 (2019-09-04)
-------------------
- [CHANGE] ``ArrowParseWarning`` will no longer be printed on every call to ``arrow.get()`` with a datetime string. The purpose of the warning was to start a conversation about the upcoming 0.15.0 changes and we appreciate all the feedback that the community has given us!
0.14.6 (2019-08-28)
-------------------
- [NEW] Added support for ``week`` granularity in ``Arrow.humanize()``. For example, ``arrow.utcnow().shift(weeks=-1).humanize(granularity="week")`` outputs "a week ago". This change introduced two new untranslated words, ``week`` and ``weeks``, to all locale dictionaries, so locale contributions are welcome!
- [NEW] Fully translated the Brazilian Portuguese locale.
- [CHANGE] Updated the Macedonian locale to inherit from a Slavic base.
- [FIX] Fixed a bug that caused ``arrow.get()`` to ignore tzinfo arguments of type string (e.g. ``arrow.get(tzinfo="Europe/Paris")``).
- [FIX] Fixed a bug that occurred when ``arrow.Arrow()`` was instantiated with a ``pytz`` tzinfo object.
- [FIX] Fixed a bug that caused Arrow to fail when passed a sub-second token, that when rounded, had a value greater than 999999 (e.g. ``arrow.get("2015-01-12T01:13:15.9999995")``). Arrow should now accurately propagate the rounding for large sub-second tokens.
0.14.5 (2019-08-09)
-------------------
- [NEW] Added Afrikaans locale.
- [CHANGE] Removed deprecated ``replace`` shift functionality. Users looking to pass plural properties to the ``replace`` function to shift values should use ``shift`` instead.
- [FIX] Fixed bug that occurred when ``factory.get()`` was passed a locale kwarg.
0.14.4 (2019-07-30)
-------------------
- [FIX] Fixed a regression in 0.14.3 that prevented a tzinfo argument of type string to be passed to the ``get()`` function. Functionality such as ``arrow.get("2019072807", "YYYYMMDDHH", tzinfo="UTC")`` should work as normal again.
- [CHANGE] Moved ``backports.functools_lru_cache`` dependency from ``extra_requires`` to ``install_requires`` for ``Python 2.7`` installs to fix `#495 <https://github.com/arrow-py/arrow/issues/495>`_.
0.14.3 (2019-07-28)
-------------------
- [NEW] Added full support for Python 3.8.
- [CHANGE] Added warnings for upcoming factory.get() parsing changes in 0.15.0. Please see `#612 <https://github.com/arrow-py/arrow/issues/612>`_ for full details.
- [FIX] Extensive refactor and update of documentation.
- [FIX] factory.get() can now construct from kwargs.
- [FIX] Added meridians to Spanish Locale.
0.14.2 (2019-06-06)
-------------------
- [CHANGE] Travis CI builds now use tox to lint and run tests.
- [FIX] Fixed UnicodeDecodeError on certain locales (#600).
0.14.1 (2019-06-06)
-------------------
- [FIX] Fixed ``ImportError: No module named 'dateutil'`` (#598).
0.14.0 (2019-06-06)
-------------------
- [NEW] Added provisional support for Python 3.8.
- [CHANGE] Removed support for EOL Python 3.4.
- [FIX] Updated setup.py with modern Python standards.
- [FIX] Upgraded dependencies to latest versions.
- [FIX] Enabled flake8 and black on travis builds.
- [FIX] Formatted code using black and isort.
0.13.2 (2019-05-30)
-------------------
- [NEW] Add is_between method.
- [FIX] Improved humanize behaviour for near zero durations (#416).
- [FIX] Correct humanize behaviour with future days (#541).
- [FIX] Documentation updates.
- [FIX] Improvements to German Locale.
0.13.1 (2019-02-17)
-------------------
- [NEW] Add support for Python 3.7.
- [CHANGE] Remove deprecation decorators for Arrow.range(), Arrow.span_range() and Arrow.interval(), all now return generators, wrap with list() to get old behavior.
- [FIX] Documentation and docstring updates.
0.13.0 (2019-01-09)
-------------------
- [NEW] Added support for Python 3.6.
- [CHANGE] Drop support for Python 2.6/3.3.
- [CHANGE] Return generator instead of list for Arrow.range(), Arrow.span_range() and Arrow.interval().
- [FIX] Make arrow.get() work with str & tzinfo combo.
- [FIX] Make sure special RegEx characters are escaped in format string.
- [NEW] Added support for ZZZ when formatting.
- [FIX] Stop using datetime.utcnow() in internals, use datetime.now(UTC) instead.
- [FIX] Return NotImplemented instead of TypeError in arrow math internals.
- [NEW] Added Estonian Locale.
- [FIX] Small fixes to Greek locale.
- [FIX] TagalogLocale improvements.
- [FIX] Added test requirements to setup.
- [FIX] Improve docs for get, now and utcnow methods.
- [FIX] Correct typo in depreciation warning.
0.12.1
------
- [FIX] Allow universal wheels to be generated and reliably installed.
- [FIX] Make humanize respect only_distance when granularity argument is also given.
0.12.0
------
- [FIX] Compatibility fix for Python 2.x
0.11.0
------
- [FIX] Fix grammar of ArabicLocale
- [NEW] Add Nepali Locale
- [FIX] Fix month name + rename AustriaLocale -> AustrianLocale
- [FIX] Fix typo in Basque Locale
- [FIX] Fix grammar in PortugueseBrazilian locale
- [FIX] Remove pip --user-mirrors flag
- [NEW] Add Indonesian Locale
0.10.0
------
- [FIX] Fix getattr off by one for quarter
- [FIX] Fix negative offset for UTC
- [FIX] Update arrow.py
0.9.0
-----
- [NEW] Remove duplicate code
- [NEW] Support gnu date iso 8601
- [NEW] Add support for universal wheels
- [NEW] Slovenian locale
- [NEW] Slovak locale
- [NEW] Romanian locale
- [FIX] respect limit even if end is defined range
- [FIX] Separate replace & shift functions
- [NEW] Added tox
- [FIX] Fix supported Python versions in documentation
- [NEW] Azerbaijani locale added, locale issue fixed in Turkish.
- [FIX] Format ParserError's raise message
0.8.0
-----
- []
0.7.1
-----
- [NEW] Esperanto locale (batisteo)
0.7.0
-----
- [FIX] Parse localized strings #228 (swistakm)
- [FIX] Modify tzinfo parameter in ``get`` api #221 (bottleimp)
- [FIX] Fix Czech locale (PrehistoricTeam)
- [FIX] Raise TypeError when adding/subtracting non-dates (itsmeolivia)
- [FIX] Fix pytz conversion error (Kudo)
- [FIX] Fix overzealous time truncation in span_range (kdeldycke)
- [NEW] Humanize for time duration #232 (ybrs)
- [NEW] Add Thai locale (sipp11)
- [NEW] Adding Belarusian (be) locale (oire)
- [NEW] Search date in strings (beenje)
- [NEW] Note that arrow's tokens differ from strptime's. (offby1)
0.6.0
-----
- [FIX] Added support for Python 3
- [FIX] Avoid truncating oversized epoch timestamps. Fixes #216.
- [FIX] Fixed month abbreviations for Ukrainian
- [FIX] Fix typo timezone
- [FIX] A couple of dialect fixes and two new languages
- [FIX] Spanish locale: ``Miercoles`` should have acute accent
- [Fix] Fix Finnish grammar
- [FIX] Fix typo in 'Arrow.floor' docstring
- [FIX] Use read() utility to open README
- [FIX] span_range for week frame
- [NEW] Add minimal support for fractional seconds longer than six digits.
- [NEW] Adding locale support for Marathi (mr)
- [NEW] Add count argument to span method
- [NEW] Improved docs
0.5.1 - 0.5.4
-------------
- [FIX] test the behavior of simplejson instead of calling for_json directly (tonyseek)
- [FIX] Add Hebrew Locale (doodyparizada)
- [FIX] Update documentation location (andrewelkins)
- [FIX] Update setup.py Development Status level (andrewelkins)
- [FIX] Case insensitive month match (cshowe)
0.5.0
-----
- [NEW] struct_time addition. (mhworth)
- [NEW] Version grep (eirnym)
- [NEW] Default to ISO 8601 format (emonty)
- [NEW] Raise TypeError on comparison (sniekamp)
- [NEW] Adding Macedonian(mk) locale (krisfremen)
- [FIX] Fix for ISO seconds and fractional seconds (sdispater) (andrewelkins)
- [FIX] Use correct Dutch wording for "hours" (wbolster)
- [FIX] Complete the list of english locales (indorilftw)
- [FIX] Change README to reStructuredText (nyuszika7h)
- [FIX] Parse lower-cased 'h' (tamentis)
- [FIX] Slight modifications to Dutch locale (nvie)
0.4.4
-----
- [NEW] Include the docs in the released tarball
- [NEW] Czech localization Czech localization for Arrow
- [NEW] Add fa_ir to locales
- [FIX] Fixes parsing of time strings with a final Z
- [FIX] Fixes ISO parsing and formatting for fractional seconds
- [FIX] test_fromtimestamp sp
- [FIX] some typos fixed
- [FIX] removed an unused import statement
- [FIX] docs table fix
- [FIX] Issue with specify 'X' template and no template at all to arrow.get
- [FIX] Fix "import" typo in docs/index.rst
- [FIX] Fix unit tests for zero passed
- [FIX] Update layout.html
- [FIX] In Norwegian and new Norwegian months and weekdays should not be capitalized
- [FIX] Fixed discrepancy between specifying 'X' to arrow.get and specifying no template
0.4.3
-----
- [NEW] Turkish locale (Emre)
- [NEW] Arabic locale (Mosab Ahmad)
- [NEW] Danish locale (Holmars)
- [NEW] Icelandic locale (Holmars)
- [NEW] Hindi locale (Atmb4u)
- [NEW] Malayalam locale (Atmb4u)
- [NEW] Finnish locale (Stormpat)
- [NEW] Portuguese locale (Danielcorreia)
- [NEW] ``h`` and ``hh`` strings are now supported (Averyonghub)
- [FIX] An incorrect inflection in the Polish locale has been fixed (Avalanchy)
- [FIX] ``arrow.get`` now properly handles ``Date`` (Jaapz)
- [FIX] Tests are now declared in ``setup.py`` and the manifest (Pypingou)
- [FIX] ``__version__`` has been added to ``__init__.py`` (Sametmax)
- [FIX] ISO 8601 strings can be parsed without a separator (Ivandiguisto / Root)
- [FIX] Documentation is now more clear regarding some inputs on ``arrow.get`` (Eriktaubeneck)
- [FIX] Some documentation links have been fixed (Vrutsky)
- [FIX] Error messages for parse errors are now more descriptive (Maciej Albin)
- [FIX] The parser now correctly checks for separators in strings (Mschwager)
0.4.2
-----
- [NEW] Factory ``get`` method now accepts a single ``Arrow`` argument.
- [NEW] Tokens SSSS, SSSSS and SSSSSS are supported in parsing.
- [NEW] ``Arrow`` objects have a ``float_timestamp`` property.
- [NEW] Vietnamese locale (Iu1nguoi)
- [NEW] Factory ``get`` method now accepts a list of format strings (Dgilland)
- [NEW] A MANIFEST.in file has been added (Pypingou)
- [NEW] Tests can be run directly from ``setup.py`` (Pypingou)
- [FIX] Arrow docs now list 'day of week' format tokens correctly (Rudolphfroger)
- [FIX] Several issues with the Korean locale have been resolved (Yoloseem)
- [FIX] ``humanize`` now correctly returns unicode (Shvechikov)
- [FIX] ``Arrow`` objects now pickle / unpickle correctly (Yoloseem)
0.4.1
-----
- [NEW] Table / explanation of formatting & parsing tokens in docs
- [NEW] Brazilian locale (Augusto2112)
- [NEW] Dutch locale (OrangeTux)
- [NEW] Italian locale (Pertux)
- [NEW] Austrian locale (LeChewbacca)
- [NEW] Tagalog locale (Marksteve)
- [FIX] Corrected spelling and day numbers in German locale (LeChewbacca)
- [FIX] Factory ``get`` method should now handle unicode strings correctly (Bwells)
- [FIX] Midnight and noon should now parse and format correctly (Bwells)
0.4.0
-----
- [NEW] Format-free ISO 8601 parsing in factory ``get`` method
- [NEW] Support for 'week' / 'weeks' in ``span``, ``range``, ``span_range``, ``floor`` and ``ceil``
- [NEW] Support for 'weeks' in ``replace``
- [NEW] Norwegian locale (Martinp)
- [NEW] Japanese locale (CortYuming)
- [FIX] Timezones no longer show the wrong sign when formatted (Bean)
- [FIX] Microseconds are parsed correctly from strings (Bsidhom)
- [FIX] Locale day-of-week is no longer off by one (Cynddl)
- [FIX] Corrected plurals of Ukrainian and Russian nouns (Catchagain)
- [CHANGE] Old 0.1 ``arrow`` module method removed
- [CHANGE] Dropped timestamp support in ``range`` and ``span_range`` (never worked correctly)
- [CHANGE] Dropped parsing of single string as tz string in factory ``get`` method (replaced by ISO 8601)
0.3.5
-----
- [NEW] French locale (Cynddl)
- [NEW] Spanish locale (Slapresta)
- [FIX] Ranges handle multiple timezones correctly (Ftobia)
0.3.4
-----
- [FIX] Humanize no longer sometimes returns the wrong month delta
- [FIX] ``__format__`` works correctly with no format string
0.3.3
-----
- [NEW] Python 2.6 support
- [NEW] Initial support for locale-based parsing and formatting
- [NEW] ArrowFactory class, now proxied as the module API
- [NEW] ``factory`` api method to obtain a factory for a custom type
- [FIX] Python 3 support and tests completely ironed out
0.3.2
-----
- [NEW] Python 3+ support
0.3.1
-----
- [FIX] The old ``arrow`` module function handles timestamps correctly as it used to
0.3.0
-----
- [NEW] ``Arrow.replace`` method
- [NEW] Accept timestamps, datetimes and Arrows for datetime inputs, where reasonable
- [FIX] ``range`` and ``span_range`` respect end and limit parameters correctly
- [CHANGE] Arrow objects are no longer mutable
- [CHANGE] Plural attribute name semantics altered: single -> absolute, plural -> relative
- [CHANGE] Plural names no longer supported as properties (e.g. ``arrow.utcnow().years``)
0.2.1
-----
- [NEW] Support for localized humanization
- [NEW] English, Russian, Greek, Korean, Chinese locales
0.2.0
-----
- **REWRITE**
- [NEW] Date parsing
- [NEW] Date formatting
- [NEW] ``floor``, ``ceil`` and ``span`` methods
- [NEW] ``datetime`` interface implementation
- [NEW] ``clone`` method
- [NEW] ``get``, ``now`` and ``utcnow`` API methods
0.1.6
-----
- [NEW] Humanized time deltas
- [NEW] ``__eq__`` implemented
- [FIX] Issues with conversions related to daylight savings time resolved
- [CHANGE] ``__str__`` uses ISO formatting
0.1.5
-----
- **Started tracking changes**
- [NEW] Parsing of ISO-formatted time zone offsets (e.g. '+02:30', '-05:00')
- [NEW] Resolved some issues with timestamps and delta / Olson time zones
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2023 Chris Smith
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: Makefile
================================================
.PHONY: auto test docs clean
auto: build311
build38: PYTHON_VER = python3.8
build39: PYTHON_VER = python3.9
build310: PYTHON_VER = python3.10
build311: PYTHON_VER = python3.11
build312: PYTHON_VER = python3.12
build313: PYTHON_VER = python3.13
build314: PYTHON_VER = python3.14
build36 build37 build38 build39 build310 build311 build312 build313 build314: clean
$(PYTHON_VER) -m venv venv
. venv/bin/activate; \
pip install -U pip setuptools wheel; \
pip install -r requirements/requirements-tests.txt; \
pip install -r requirements/requirements-docs.txt; \
pre-commit install
test:
rm -f .coverage coverage.xml
. venv/bin/activate; \
pytest
lint:
. venv/bin/activate; \
pre-commit run --all-files --show-diff-on-failure
clean-docs:
rm -rf docs/_build
docs:
. venv/bin/activate; \
cd docs; \
make html
live-docs: clean-docs
. venv/bin/activate; \
sphinx-autobuild docs docs/_build/html
clean: clean-dist
rm -rf venv .pytest_cache ./**/__pycache__
rm -f .coverage coverage.xml ./**/*.pyc
clean-dist:
rm -rf dist build *.egg *.eggs *.egg-info
build-dist: clean-dist
. venv/bin/activate; \
pip install -U flit; \
flit build
================================================
FILE: README.rst
================================================
Arrow: Better dates & times for Python
======================================
.. start-inclusion-marker-do-not-remove
.. image:: https://github.com/arrow-py/arrow/workflows/tests/badge.svg?branch=master
:alt: Build Status
:target: https://github.com/arrow-py/arrow/actions?query=workflow%3Atests+branch%3Amaster
.. image:: https://codecov.io/gh/arrow-py/arrow/branch/master/graph/badge.svg
:alt: Coverage
:target: https://codecov.io/gh/arrow-py/arrow
.. image:: https://img.shields.io/pypi/v/arrow.svg
:alt: PyPI Version
:target: https://pypi.python.org/pypi/arrow
.. image:: https://img.shields.io/pypi/pyversions/arrow.svg
:alt: Supported Python Versions
:target: https://pypi.python.org/pypi/arrow
.. image:: https://img.shields.io/pypi/l/arrow.svg
:alt: License
:target: https://pypi.python.org/pypi/arrow
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
:alt: Code Style: Black
:target: https://github.com/psf/black
**Arrow** is a Python library that offers a sensible and human-friendly approach to creating, manipulating, formatting and converting dates, times and timestamps. It implements and updates the datetime type, plugging gaps in functionality and providing an intelligent module API that supports many common creation scenarios. Simply put, it helps you work with dates and times with fewer imports and a lot less code.
Arrow is named after the `arrow of time <https://en.wikipedia.org/wiki/Arrow_of_time>`_ and is heavily inspired by `moment.js <https://github.com/moment/moment>`_ and `requests <https://github.com/psf/requests>`_.
Why use Arrow over built-in modules?
------------------------------------
Python's standard library and some other low-level modules have near-complete date, time and timezone functionality, but don't work very well from a usability perspective:
- Too many modules: datetime, time, calendar, dateutil, pytz and more
- Too many types: date, time, datetime, tzinfo, timedelta, relativedelta, etc.
- Timezones and timestamp conversions are verbose and unpleasant
- Timezone naivety is the norm
- Gaps in functionality: ISO 8601 parsing, timespans, humanization
Features
--------
- Fully-implemented, drop-in replacement for datetime
- Support for Python 3.8+
- Timezone-aware and UTC by default
- Super-simple creation options for many common input scenarios
- ``shift`` method with support for relative offsets, including weeks
- Format and parse strings automatically
- Wide support for the `ISO 8601 <https://en.wikipedia.org/wiki/ISO_8601>`_ standard
- Timezone conversion
- Support for ``dateutil``, ``pytz``, and ``ZoneInfo`` tzinfo objects
- Generates time spans, ranges, floors and ceilings for time frames ranging from microsecond to year
- Humanize dates and times with a growing list of contributed locales
- Extensible for your own Arrow-derived types
- Full support for PEP 484-style type hints
Quick Start
-----------
Installation
~~~~~~~~~~~~
To install Arrow, use `pip <https://pip.pypa.io/en/stable/quickstart/>`_ or `pipenv <https://docs.pipenv.org>`_:
.. code-block:: console
$ pip install -U arrow
Example Usage
~~~~~~~~~~~~~
.. code-block:: python
>>> import arrow
>>> arrow.get('2013-05-11T21:23:58.970460+07:00')
<Arrow [2013-05-11T21:23:58.970460+07:00]>
>>> utc = arrow.utcnow()
>>> utc
<Arrow [2013-05-11T21:23:58.970460+00:00]>
>>> utc = utc.shift(hours=-1)
>>> utc
<Arrow [2013-05-11T20:23:58.970460+00:00]>
>>> local = utc.to('US/Pacific')
>>> local
<Arrow [2013-05-11T13:23:58.970460-07:00]>
>>> local.timestamp()
1368303838.970460
>>> local.format()
'2013-05-11 13:23:58 -07:00'
>>> local.format('YYYY-MM-DD HH:mm:ss ZZ')
'2013-05-11 13:23:58 -07:00'
>>> local.humanize()
'an hour ago'
>>> local.humanize(locale='ko-kr')
'한시간 전'
.. end-inclusion-marker-do-not-remove
Documentation
-------------
For full documentation, please visit `arrow.readthedocs.io <https://arrow.readthedocs.io>`_.
Contributing
------------
Contributions are welcome for both code and localizations (adding and updating locales). Begin by gaining familiarity with the Arrow library and its features. Then, jump into contributing:
#. Find an issue or feature to tackle on the `issue tracker <https://github.com/arrow-py/arrow/issues>`_. Issues marked with the `"good first issue" label <https://github.com/arrow-py/arrow/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22>`_ may be a great place to start!
#. Fork `this repository <https://github.com/arrow-py/arrow>`_ on GitHub and begin making changes in a branch.
#. Add a few tests to ensure that the bug was fixed or the feature works as expected.
#. Run the entire test suite and linting checks by running one of the following commands: ``tox && tox -e lint,docs`` (if you have `tox <https://tox.readthedocs.io>`_ installed) **OR** ``make build39 && make test && make lint`` (if you do not have Python 3.9 installed, replace ``build39`` with the latest Python version on your system).
#. Submit a pull request and await feedback 😃.
If you have any questions along the way, feel free to ask them `here <https://github.com/arrow-py/arrow/discussions>`_.
Support Arrow
-------------
`Open Collective <https://opencollective.com/>`_ is an online funding platform that provides tools to raise money and share your finances with full transparency. It is the platform of choice for individuals and companies to make one-time or recurring donations directly to the project. If you are interested in making a financial contribution, please visit the `Arrow collective <https://opencollective.com/arrow>`_.
================================================
FILE: arrow/__init__.py
================================================
from ._version import __version__
from .api import get, now, utcnow
from .arrow import Arrow
from .factory import ArrowFactory
from .formatter import (
FORMAT_ATOM,
FORMAT_COOKIE,
FORMAT_RFC822,
FORMAT_RFC850,
FORMAT_RFC1036,
FORMAT_RFC1123,
FORMAT_RFC2822,
FORMAT_RFC3339,
FORMAT_RFC3339_STRICT,
FORMAT_RSS,
FORMAT_W3C,
)
from .parser import ParserError
# https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-no-implicit-reexport
# Mypy with --strict or --no-implicit-reexport requires an explicit reexport.
__all__ = [
"__version__",
"get",
"now",
"utcnow",
"Arrow",
"ArrowFactory",
"FORMAT_ATOM",
"FORMAT_COOKIE",
"FORMAT_RFC822",
"FORMAT_RFC850",
"FORMAT_RFC1036",
"FORMAT_RFC1123",
"FORMAT_RFC2822",
"FORMAT_RFC3339",
"FORMAT_RFC3339_STRICT",
"FORMAT_RSS",
"FORMAT_W3C",
"ParserError",
]
================================================
FILE: arrow/_version.py
================================================
__version__ = "1.4.0"
================================================
FILE: arrow/api.py
================================================
"""
Provides the default implementation of :class:`ArrowFactory <arrow.factory.ArrowFactory>`
methods for use as a module API.
"""
from datetime import date, datetime
from datetime import tzinfo as dt_tzinfo
from time import struct_time
from typing import Any, List, Optional, Tuple, Type, Union, overload
from arrow.arrow import TZ_EXPR, Arrow
from arrow.constants import DEFAULT_LOCALE
from arrow.factory import ArrowFactory
# internal default factory.
_factory = ArrowFactory()
# TODO: Use Positional Only Argument (https://www.python.org/dev/peps/pep-0570/)
# after Python 3.7 deprecation
@overload
def get(
*,
locale: str = DEFAULT_LOCALE,
tzinfo: Optional[TZ_EXPR] = None,
normalize_whitespace: bool = False,
) -> Arrow: ... # pragma: no cover
@overload
def get(
*args: int,
locale: str = DEFAULT_LOCALE,
tzinfo: Optional[TZ_EXPR] = None,
normalize_whitespace: bool = False,
) -> Arrow: ... # pragma: no cover
@overload
def get(
__obj: Union[
Arrow,
datetime,
date,
struct_time,
dt_tzinfo,
int,
float,
str,
Tuple[int, int, int],
],
*,
locale: str = DEFAULT_LOCALE,
tzinfo: Optional[TZ_EXPR] = None,
normalize_whitespace: bool = False,
) -> Arrow: ... # pragma: no cover
@overload
def get(
__arg1: Union[datetime, date],
__arg2: TZ_EXPR,
*,
locale: str = DEFAULT_LOCALE,
tzinfo: Optional[TZ_EXPR] = None,
normalize_whitespace: bool = False,
) -> Arrow: ... # pragma: no cover
@overload
def get(
__arg1: str,
__arg2: Union[str, List[str]],
*,
locale: str = DEFAULT_LOCALE,
tzinfo: Optional[TZ_EXPR] = None,
normalize_whitespace: bool = False,
) -> Arrow: ... # pragma: no cover
def get(*args: Any, **kwargs: Any) -> Arrow:
"""Calls the default :class:`ArrowFactory <arrow.factory.ArrowFactory>` ``get`` method."""
return _factory.get(*args, **kwargs)
get.__doc__ = _factory.get.__doc__
def utcnow() -> Arrow:
"""Calls the default :class:`ArrowFactory <arrow.factory.ArrowFactory>` ``utcnow`` method."""
return _factory.utcnow()
utcnow.__doc__ = _factory.utcnow.__doc__
def now(tz: Optional[TZ_EXPR] = None) -> Arrow:
"""Calls the default :class:`ArrowFactory <arrow.factory.ArrowFactory>` ``now`` method."""
return _factory.now(tz)
now.__doc__ = _factory.now.__doc__
def factory(type: Type[Arrow]) -> ArrowFactory:
"""Returns an :class:`.ArrowFactory` for the specified :class:`Arrow <arrow.arrow.Arrow>`
or derived type.
:param type: the type, :class:`Arrow <arrow.arrow.Arrow>` or derived.
"""
return ArrowFactory(type)
__all__ = ["get", "utcnow", "now", "factory"]
================================================
FILE: arrow/arrow.py
================================================
"""
Provides the :class:`Arrow <arrow.arrow.Arrow>` class, an enhanced ``datetime``
replacement.
"""
import calendar
import re
import sys
from datetime import date as dt_date
from datetime import datetime as dt_datetime
from datetime import time as dt_time
from datetime import timedelta, timezone
from datetime import tzinfo as dt_tzinfo
from math import trunc
from time import struct_time
from typing import (
Any,
ClassVar,
Final,
Generator,
Iterable,
List,
Literal,
Mapping,
Optional,
Tuple,
Union,
cast,
overload,
)
from dateutil import tz as dateutil_tz
from dateutil.relativedelta import relativedelta
from arrow import formatter, locales, parser, util
from arrow.constants import DEFAULT_LOCALE, DEHUMANIZE_LOCALES
from arrow.locales import TimeFrameLiteral
TZ_EXPR = Union[dt_tzinfo, str]
_T_FRAMES = Literal[
"year",
"years",
"month",
"months",
"day",
"days",
"hour",
"hours",
"minute",
"minutes",
"second",
"seconds",
"microsecond",
"microseconds",
"week",
"weeks",
"quarter",
"quarters",
]
_BOUNDS = Literal["[)", "()", "(]", "[]"]
_GRANULARITY = Literal[
"auto",
"second",
"minute",
"hour",
"day",
"week",
"month",
"quarter",
"year",
]
class Arrow:
"""An :class:`Arrow <arrow.arrow.Arrow>` object.
Implements the ``datetime`` interface, behaving as an aware ``datetime`` while implementing
additional functionality.
:param year: the calendar year.
:param month: the calendar month.
:param day: the calendar day.
:param hour: (optional) the hour. Defaults to 0.
:param minute: (optional) the minute, Defaults to 0.
:param second: (optional) the second, Defaults to 0.
:param microsecond: (optional) the microsecond. Defaults to 0.
:param tzinfo: (optional) A timezone expression. Defaults to UTC.
:param fold: (optional) 0 or 1, used to disambiguate repeated wall times. Defaults to 0.
.. _tz-expr:
Recognized timezone expressions:
- A ``tzinfo`` object.
- A ``str`` describing a timezone, similar to 'US/Pacific', or 'Europe/Berlin'.
- A ``str`` in ISO 8601 style, as in '+07:00'.
- A ``str``, one of the following: 'local', 'utc', 'UTC'.
Usage::
>>> import arrow
>>> arrow.Arrow(2013, 5, 5, 12, 30, 45)
<Arrow [2013-05-05T12:30:45+00:00]>
"""
resolution: ClassVar[timedelta] = dt_datetime.resolution
min: ClassVar["Arrow"]
max: ClassVar["Arrow"]
_ATTRS: Final[List[str]] = [
"year",
"month",
"day",
"hour",
"minute",
"second",
"microsecond",
]
_ATTRS_PLURAL: Final[List[str]] = [f"{a}s" for a in _ATTRS]
_MONTHS_PER_QUARTER: Final[int] = 3
_MONTHS_PER_YEAR: Final[int] = 12
_SECS_PER_MINUTE: Final[int] = 60
_SECS_PER_HOUR: Final[int] = 60 * 60
_SECS_PER_DAY: Final[int] = 60 * 60 * 24
_SECS_PER_WEEK: Final[int] = 60 * 60 * 24 * 7
_SECS_PER_MONTH: Final[float] = 60 * 60 * 24 * 30.5
_SECS_PER_QUARTER: Final[float] = 60 * 60 * 24 * 30.5 * 3
_SECS_PER_YEAR: Final[int] = 60 * 60 * 24 * 365
_SECS_MAP: Final[Mapping[TimeFrameLiteral, float]] = {
"second": 1.0,
"minute": _SECS_PER_MINUTE,
"hour": _SECS_PER_HOUR,
"day": _SECS_PER_DAY,
"week": _SECS_PER_WEEK,
"month": _SECS_PER_MONTH,
"quarter": _SECS_PER_QUARTER,
"year": _SECS_PER_YEAR,
}
_datetime: dt_datetime
def __init__(
self,
year: int,
month: int,
day: int,
hour: int = 0,
minute: int = 0,
second: int = 0,
microsecond: int = 0,
tzinfo: Optional[TZ_EXPR] = None,
**kwargs: Any,
) -> None:
if tzinfo is None:
tzinfo = timezone.utc
# detect that tzinfo is a pytz object (issue #626)
elif (
isinstance(tzinfo, dt_tzinfo)
and hasattr(tzinfo, "localize")
and hasattr(tzinfo, "zone")
and tzinfo.zone
):
tzinfo = parser.TzinfoParser.parse(tzinfo.zone)
elif isinstance(tzinfo, str):
tzinfo = parser.TzinfoParser.parse(tzinfo)
fold = kwargs.get("fold", 0)
self._datetime = dt_datetime(
year, month, day, hour, minute, second, microsecond, tzinfo, fold=fold
)
# factories: single object, both original and from datetime.
@classmethod
def now(cls, tzinfo: Optional[dt_tzinfo] = None) -> "Arrow":
"""Constructs an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in the given
timezone.
:param tzinfo: (optional) a ``tzinfo`` object. Defaults to local time.
Usage::
>>> arrow.now('Asia/Baku')
<Arrow [2019-01-24T20:26:31.146412+04:00]>
"""
if tzinfo is None:
tzinfo = dt_datetime.now().astimezone().tzinfo
dt = dt_datetime.now(tzinfo)
return cls(
dt.year,
dt.month,
dt.day,
dt.hour,
dt.minute,
dt.second,
dt.microsecond,
dt.tzinfo,
fold=getattr(dt, "fold", 0),
)
@classmethod
def utcnow(cls) -> "Arrow":
"""Constructs an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in UTC
time.
Usage::
>>> arrow.utcnow()
<Arrow [2019-01-24T16:31:40.651108+00:00]>
"""
dt = dt_datetime.now(timezone.utc)
return cls(
dt.year,
dt.month,
dt.day,
dt.hour,
dt.minute,
dt.second,
dt.microsecond,
dt.tzinfo,
fold=getattr(dt, "fold", 0),
)
@classmethod
def fromtimestamp(
cls,
timestamp: Union[int, float, str],
tzinfo: Optional[TZ_EXPR] = None,
) -> "Arrow":
"""Constructs an :class:`Arrow <arrow.arrow.Arrow>` object from a timestamp, converted to
the given timezone.
:param timestamp: an ``int`` or ``float`` timestamp, or a ``str`` that converts to either.
:param tzinfo: (optional) a ``tzinfo`` object. Defaults to local time.
"""
if tzinfo is None:
tzinfo = dt_datetime.now().astimezone().tzinfo
elif isinstance(tzinfo, str):
tzinfo = parser.TzinfoParser.parse(tzinfo)
if not util.is_timestamp(timestamp):
raise ValueError(f"The provided timestamp {timestamp!r} is invalid.")
timestamp = util.normalize_timestamp(float(timestamp))
dt = dt_datetime.fromtimestamp(timestamp, tzinfo)
return cls(
dt.year,
dt.month,
dt.day,
dt.hour,
dt.minute,
dt.second,
dt.microsecond,
dt.tzinfo,
fold=getattr(dt, "fold", 0),
)
@classmethod
def utcfromtimestamp(cls, timestamp: Union[int, float, str]) -> "Arrow":
"""Constructs an :class:`Arrow <arrow.arrow.Arrow>` object from a timestamp, in UTC time.
:param timestamp: an ``int`` or ``float`` timestamp, or a ``str`` that converts to either.
"""
if not util.is_timestamp(timestamp):
raise ValueError(f"The provided timestamp {timestamp!r} is invalid.")
timestamp = util.normalize_timestamp(float(timestamp))
dt = dt_datetime.fromtimestamp(timestamp, timezone.utc)
return cls(
dt.year,
dt.month,
dt.day,
dt.hour,
dt.minute,
dt.second,
dt.microsecond,
timezone.utc,
fold=getattr(dt, "fold", 0),
)
@classmethod
def fromdatetime(cls, dt: dt_datetime, tzinfo: Optional[TZ_EXPR] = None) -> "Arrow":
"""Constructs an :class:`Arrow <arrow.arrow.Arrow>` object from a ``datetime`` and
optional replacement timezone.
:param dt: the ``datetime``
:param tzinfo: (optional) A :ref:`timezone expression <tz-expr>`. Defaults to ``dt``'s
timezone, or UTC if naive.
Usage::
>>> dt
datetime.datetime(2021, 4, 7, 13, 48, tzinfo=tzfile('/usr/share/zoneinfo/US/Pacific'))
>>> arrow.Arrow.fromdatetime(dt)
<Arrow [2021-04-07T13:48:00-07:00]>
"""
if tzinfo is None:
if dt.tzinfo is None:
tzinfo = timezone.utc
else:
tzinfo = dt.tzinfo
return cls(
dt.year,
dt.month,
dt.day,
dt.hour,
dt.minute,
dt.second,
dt.microsecond,
tzinfo,
fold=getattr(dt, "fold", 0),
)
@classmethod
def fromdate(cls, date: dt_date, tzinfo: Optional[TZ_EXPR] = None) -> "Arrow":
"""Constructs an :class:`Arrow <arrow.arrow.Arrow>` object from a ``date`` and optional
replacement timezone. All time values are set to 0.
:param date: the ``date``
:param tzinfo: (optional) A :ref:`timezone expression <tz-expr>`. Defaults to UTC.
"""
if tzinfo is None:
tzinfo = timezone.utc
return cls(date.year, date.month, date.day, tzinfo=tzinfo)
@classmethod
def strptime(
cls, date_str: str, fmt: str, tzinfo: Optional[TZ_EXPR] = None
) -> "Arrow":
"""Constructs an :class:`Arrow <arrow.arrow.Arrow>` object from a date string and format,
in the style of ``datetime.strptime``. Optionally replaces the parsed timezone.
:param date_str: the date string.
:param fmt: the format string using datetime format codes.
:param tzinfo: (optional) A :ref:`timezone expression <tz-expr>`. Defaults to the parsed
timezone if ``fmt`` contains a timezone directive, otherwise UTC.
Usage::
>>> arrow.Arrow.strptime('20-01-2019 15:49:10', '%d-%m-%Y %H:%M:%S')
<Arrow [2019-01-20T15:49:10+00:00]>
"""
dt = dt_datetime.strptime(date_str, fmt)
if tzinfo is None:
tzinfo = dt.tzinfo
return cls(
dt.year,
dt.month,
dt.day,
dt.hour,
dt.minute,
dt.second,
dt.microsecond,
tzinfo,
fold=getattr(dt, "fold", 0),
)
@classmethod
def fromordinal(cls, ordinal: int) -> "Arrow":
"""Constructs an :class:`Arrow <arrow.arrow.Arrow>` object corresponding
to the Gregorian Ordinal.
:param ordinal: an ``int`` corresponding to a Gregorian Ordinal.
Usage::
>>> arrow.fromordinal(737741)
<Arrow [2020-11-12T00:00:00+00:00]>
"""
util.validate_ordinal(ordinal)
dt = dt_datetime.fromordinal(ordinal)
return cls(
dt.year,
dt.month,
dt.day,
dt.hour,
dt.minute,
dt.second,
dt.microsecond,
dt.tzinfo,
fold=getattr(dt, "fold", 0),
)
# factories: ranges and spans
@classmethod
def range(
cls,
frame: _T_FRAMES,
start: Union["Arrow", dt_datetime],
end: Union["Arrow", dt_datetime, None] = None,
tz: Optional[TZ_EXPR] = None,
limit: Optional[int] = None,
) -> Generator["Arrow", None, None]:
"""Returns an iterator of :class:`Arrow <arrow.arrow.Arrow>` objects, representing
points in time between two inputs.
:param frame: The timeframe. Can be any ``datetime`` property (day, hour, minute...).
:param start: A datetime expression, the start of the range.
:param end: (optional) A datetime expression, the end of the range.
:param tz: (optional) A :ref:`timezone expression <tz-expr>`. Defaults to
``start``'s timezone, or UTC if ``start`` is naive.
:param limit: (optional) A maximum number of tuples to return.
**NOTE**: The ``end`` or ``limit`` must be provided. Call with ``end`` alone to
return the entire range. Call with ``limit`` alone to return a maximum # of results from
the start. Call with both to cap a range at a maximum # of results.
**NOTE**: ``tz`` internally **replaces** the timezones of both ``start`` and ``end`` before
iterating. As such, either call with naive objects and ``tz``, or aware objects from the
same timezone and no ``tz``.
Supported frame values: year, quarter, month, week, day, hour, minute, second, microsecond.
Recognized datetime expressions:
- An :class:`Arrow <arrow.arrow.Arrow>` object.
- A ``datetime`` object.
Usage::
>>> start = datetime(2013, 5, 5, 12, 30)
>>> end = datetime(2013, 5, 5, 17, 15)
>>> for r in arrow.Arrow.range('hour', start, end):
... print(repr(r))
...
<Arrow [2013-05-05T12:30:00+00:00]>
<Arrow [2013-05-05T13:30:00+00:00]>
<Arrow [2013-05-05T14:30:00+00:00]>
<Arrow [2013-05-05T15:30:00+00:00]>
<Arrow [2013-05-05T16:30:00+00:00]>
**NOTE**: Unlike Python's ``range``, ``end`` *may* be included in the returned iterator::
>>> start = datetime(2013, 5, 5, 12, 30)
>>> end = datetime(2013, 5, 5, 13, 30)
>>> for r in arrow.Arrow.range('hour', start, end):
... print(repr(r))
...
<Arrow [2013-05-05T12:30:00+00:00]>
<Arrow [2013-05-05T13:30:00+00:00]>
"""
_, frame_relative, relative_steps = cls._get_frames(frame)
tzinfo = cls._get_tzinfo(start.tzinfo if tz is None else tz)
start = cls._get_datetime(start).replace(tzinfo=tzinfo)
end, limit = cls._get_iteration_params(end, limit)
end = cls._get_datetime(end).replace(tzinfo=tzinfo)
current = cls.fromdatetime(start)
original_day = start.day
day_is_clipped = False
i = 0
while current <= end and i < limit:
i += 1
yield current
values = [getattr(current, f) for f in cls._ATTRS]
current = cls(*values, tzinfo=tzinfo).shift( # type: ignore[misc]
check_imaginary=True, **{frame_relative: relative_steps}
)
if frame in ["month", "quarter", "year"] and current.day < original_day:
day_is_clipped = True
if day_is_clipped and not cls._is_last_day_of_month(current):
current = current.replace(day=original_day)
def span(
self,
frame: _T_FRAMES,
count: int = 1,
bounds: _BOUNDS = "[)",
exact: bool = False,
week_start: int = 1,
) -> Tuple["Arrow", "Arrow"]:
"""Returns a tuple of two new :class:`Arrow <arrow.arrow.Arrow>` objects, representing the timespan
of the :class:`Arrow <arrow.arrow.Arrow>` object in a given timeframe.
:param frame: the timeframe. Can be any ``datetime`` property (day, hour, minute...).
:param count: (optional) the number of frames to span.
:param bounds: (optional) a ``str`` of either '()', '(]', '[)', or '[]' that specifies
whether to include or exclude the start and end values in the span. '(' excludes
the start, '[' includes the start, ')' excludes the end, and ']' includes the end.
If the bounds are not specified, the default bound '[)' is used.
:param exact: (optional) whether to have the start of the timespan begin exactly
at the time specified by ``start`` and the end of the timespan truncated
so as not to extend beyond ``end``.
:param week_start: (optional) only used in combination with the week timeframe. Follows isoweekday() where
Monday is 1 and Sunday is 7.
Supported frame values: year, quarter, month, week, day, hour, minute, second.
Usage::
>>> arrow.utcnow()
<Arrow [2013-05-09T03:32:36.186203+00:00]>
>>> arrow.utcnow().span('hour')
(<Arrow [2013-05-09T03:00:00+00:00]>, <Arrow [2013-05-09T03:59:59.999999+00:00]>)
>>> arrow.utcnow().span('day')
(<Arrow [2013-05-09T00:00:00+00:00]>, <Arrow [2013-05-09T23:59:59.999999+00:00]>)
>>> arrow.utcnow().span('day', count=2)
(<Arrow [2013-05-09T00:00:00+00:00]>, <Arrow [2013-05-10T23:59:59.999999+00:00]>)
>>> arrow.utcnow().span('day', bounds='[]')
(<Arrow [2013-05-09T00:00:00+00:00]>, <Arrow [2013-05-10T00:00:00+00:00]>)
>>> arrow.utcnow().span('week')
(<Arrow [2021-02-22T00:00:00+00:00]>, <Arrow [2021-02-28T23:59:59.999999+00:00]>)
>>> arrow.utcnow().span('week', week_start=6)
(<Arrow [2021-02-20T00:00:00+00:00]>, <Arrow [2021-02-26T23:59:59.999999+00:00]>)
"""
util.validate_bounds(bounds)
frame_absolute, frame_relative, relative_steps = self._get_frames(frame)
if frame_absolute == "week":
if not 1 <= week_start <= 7:
raise ValueError("week_start argument must be between 1 and 7.")
attr = "day"
elif frame_absolute == "quarter":
attr = "month"
else:
attr = frame_absolute
floor = self
if not exact:
index = self._ATTRS.index(attr)
frames = self._ATTRS[: index + 1]
values = [getattr(self, f) for f in frames]
for _ in range(3 - len(values)):
values.append(1)
floor = self.__class__(*values, tzinfo=self.tzinfo) # type: ignore[misc]
if frame_absolute == "week":
# if week_start is greater than self.isoweekday() go back one week by setting delta = 7
delta = 7 if week_start > self.isoweekday() else 0
floor = floor.shift(days=-(self.isoweekday() - week_start) - delta)
elif frame_absolute == "quarter":
floor = floor.shift(months=-((self.month - 1) % 3))
ceil = floor.shift(
check_imaginary=True, **{frame_relative: count * relative_steps}
)
if bounds[0] == "(":
floor = floor.shift(microseconds=+1)
if bounds[1] == ")":
ceil = ceil.shift(microseconds=-1)
return floor, ceil
def floor(self, frame: _T_FRAMES, **kwargs: Any) -> "Arrow":
"""Returns a new :class:`Arrow <arrow.arrow.Arrow>` object, representing the "floor"
of the timespan of the :class:`Arrow <arrow.arrow.Arrow>` object in a given timeframe.
Equivalent to the first element in the 2-tuple returned by
:func:`span <arrow.arrow.Arrow.span>`.
:param frame: the timeframe. Can be any ``datetime`` property (day, hour, minute...).
:param week_start: (optional) only used in combination with the week timeframe. Follows isoweekday() where
Monday is 1 and Sunday is 7.
Usage::
>>> arrow.utcnow().floor('hour')
<Arrow [2013-05-09T03:00:00+00:00]>
>>> arrow.utcnow().floor('week', week_start=7)
<Arrow [2021-02-21T00:00:00+00:00]>
"""
return self.span(frame, **kwargs)[0]
def ceil(self, frame: _T_FRAMES, **kwargs: Any) -> "Arrow":
"""Returns a new :class:`Arrow <arrow.arrow.Arrow>` object, representing the "ceiling"
of the timespan of the :class:`Arrow <arrow.arrow.Arrow>` object in a given timeframe.
Equivalent to the second element in the 2-tuple returned by
:func:`span <arrow.arrow.Arrow.span>`.
:param frame: the timeframe. Can be any ``datetime`` property (day, hour, minute...).
:param week_start: (optional) only used in combination with the week timeframe. Follows isoweekday() where
Monday is 1 and Sunday is 7.
Usage::
>>> arrow.utcnow().ceil('hour')
<Arrow [2013-05-09T03:59:59.999999+00:00]>
>>> arrow.utcnow().ceil('week', week_start=7)
<Arrow [2021-02-27T23:59:59.999999+00:00]>
"""
return self.span(frame, **kwargs)[1]
@classmethod
def span_range(
cls,
frame: _T_FRAMES,
start: dt_datetime,
end: dt_datetime,
tz: Optional[TZ_EXPR] = None,
limit: Optional[int] = None,
bounds: _BOUNDS = "[)",
exact: bool = False,
) -> Iterable[Tuple["Arrow", "Arrow"]]:
"""Returns an iterator of tuples, each :class:`Arrow <arrow.arrow.Arrow>` objects,
representing a series of timespans between two inputs.
:param frame: The timeframe. Can be any ``datetime`` property (day, hour, minute...).
:param start: A datetime expression, the start of the range.
:param end: (optional) A datetime expression, the end of the range.
:param tz: (optional) A :ref:`timezone expression <tz-expr>`. Defaults to
``start``'s timezone, or UTC if ``start`` is naive.
:param limit: (optional) A maximum number of tuples to return.
:param bounds: (optional) a ``str`` of either '()', '(]', '[)', or '[]' that specifies
whether to include or exclude the start and end values in each span in the range. '(' excludes
the start, '[' includes the start, ')' excludes the end, and ']' includes the end.
If the bounds are not specified, the default bound '[)' is used.
:param exact: (optional) whether to have the first timespan start exactly
at the time specified by ``start`` and the final span truncated
so as not to extend beyond ``end``.
**NOTE**: The ``end`` or ``limit`` must be provided. Call with ``end`` alone to
return the entire range. Call with ``limit`` alone to return a maximum # of results from
the start. Call with both to cap a range at a maximum # of results.
**NOTE**: ``tz`` internally **replaces** the timezones of both ``start`` and ``end`` before
iterating. As such, either call with naive objects and ``tz``, or aware objects from the
same timezone and no ``tz``.
Supported frame values: year, quarter, month, week, day, hour, minute, second, microsecond.
Recognized datetime expressions:
- An :class:`Arrow <arrow.arrow.Arrow>` object.
- A ``datetime`` object.
**NOTE**: Unlike Python's ``range``, ``end`` will *always* be included in the returned
iterator of timespans.
Usage:
>>> start = datetime(2013, 5, 5, 12, 30)
>>> end = datetime(2013, 5, 5, 17, 15)
>>> for r in arrow.Arrow.span_range('hour', start, end):
... print(r)
...
(<Arrow [2013-05-05T12:00:00+00:00]>, <Arrow [2013-05-05T12:59:59.999999+00:00]>)
(<Arrow [2013-05-05T13:00:00+00:00]>, <Arrow [2013-05-05T13:59:59.999999+00:00]>)
(<Arrow [2013-05-05T14:00:00+00:00]>, <Arrow [2013-05-05T14:59:59.999999+00:00]>)
(<Arrow [2013-05-05T15:00:00+00:00]>, <Arrow [2013-05-05T15:59:59.999999+00:00]>)
(<Arrow [2013-05-05T16:00:00+00:00]>, <Arrow [2013-05-05T16:59:59.999999+00:00]>)
(<Arrow [2013-05-05T17:00:00+00:00]>, <Arrow [2013-05-05T17:59:59.999999+00:00]>)
"""
tzinfo = cls._get_tzinfo(start.tzinfo if tz is None else tz)
start = cls.fromdatetime(start, tzinfo).span(frame, exact=exact)[0]
end = cls.fromdatetime(end, tzinfo)
_range = cls.range(frame, start, end, tz, limit)
if not exact:
for r in _range:
yield r.span(frame, bounds=bounds, exact=exact)
for r in _range:
floor, ceil = r.span(frame, bounds=bounds, exact=exact)
if ceil > end:
ceil = end
if bounds[1] == ")":
ceil += relativedelta(microseconds=-1)
if floor == end:
break
elif floor + relativedelta(microseconds=-1) == end:
break
yield floor, ceil
@classmethod
def interval(
cls,
frame: _T_FRAMES,
start: dt_datetime,
end: dt_datetime,
interval: int = 1,
tz: Optional[TZ_EXPR] = None,
bounds: _BOUNDS = "[)",
exact: bool = False,
) -> Iterable[Tuple["Arrow", "Arrow"]]:
"""Returns an iterator of tuples, each :class:`Arrow <arrow.arrow.Arrow>` objects,
representing a series of intervals between two inputs.
:param frame: The timeframe. Can be any ``datetime`` property (day, hour, minute...).
:param start: A datetime expression, the start of the range.
:param end: (optional) A datetime expression, the end of the range.
:param interval: (optional) Time interval for the given time frame.
:param tz: (optional) A timezone expression. Defaults to UTC.
:param bounds: (optional) a ``str`` of either '()', '(]', '[)', or '[]' that specifies
whether to include or exclude the start and end values in the intervals. '(' excludes
the start, '[' includes the start, ')' excludes the end, and ']' includes the end.
If the bounds are not specified, the default bound '[)' is used.
:param exact: (optional) whether to have the first timespan start exactly
at the time specified by ``start`` and the final interval truncated
so as not to extend beyond ``end``.
Supported frame values: year, quarter, month, week, day, hour, minute, second
Recognized datetime expressions:
- An :class:`Arrow <arrow.arrow.Arrow>` object.
- A ``datetime`` object.
Recognized timezone expressions:
- A ``tzinfo`` object.
- A ``str`` describing a timezone, similar to 'US/Pacific', or 'Europe/Berlin'.
- A ``str`` in ISO 8601 style, as in '+07:00'.
- A ``str``, one of the following: 'local', 'utc', 'UTC'.
Usage:
>>> start = datetime(2013, 5, 5, 12, 30)
>>> end = datetime(2013, 5, 5, 17, 15)
>>> for r in arrow.Arrow.interval('hour', start, end, 2):
... print(r)
...
(<Arrow [2013-05-05T12:00:00+00:00]>, <Arrow [2013-05-05T13:59:59.999999+00:00]>)
(<Arrow [2013-05-05T14:00:00+00:00]>, <Arrow [2013-05-05T15:59:59.999999+00:00]>)
(<Arrow [2013-05-05T16:00:00+00:00]>, <Arrow [2013-05-05T17:59:59.999999+00:0]>)
"""
if interval < 1:
raise ValueError("interval has to be a positive integer")
spanRange = iter(
cls.span_range(frame, start, end, tz, bounds=bounds, exact=exact)
)
while True:
try:
intvlStart, intvlEnd = next(spanRange)
for _ in range(interval - 1):
try:
_, intvlEnd = next(spanRange)
except StopIteration:
continue
yield intvlStart, intvlEnd
except StopIteration:
return
# representations
def __repr__(self) -> str:
return f"<{self.__class__.__name__} [{self.__str__()}]>"
def __str__(self) -> str:
return self._datetime.isoformat()
def __format__(self, formatstr: str) -> str:
if len(formatstr) > 0:
return self.format(formatstr)
return str(self)
def __hash__(self) -> int:
return self._datetime.__hash__()
# attributes and properties
def __getattr__(self, name: str) -> Any:
if name == "week":
return self.isocalendar()[1]
if name == "quarter":
return int((self.month - 1) / self._MONTHS_PER_QUARTER) + 1
if not name.startswith("_"):
value: Optional[Any] = getattr(self._datetime, name, None)
if value is not None:
return value
return cast(int, object.__getattribute__(self, name))
@property
def tzinfo(self) -> dt_tzinfo:
"""Gets the ``tzinfo`` of the :class:`Arrow <arrow.arrow.Arrow>` object.
Usage::
>>> arw=arrow.utcnow()
>>> arw.tzinfo
tzutc()
"""
# In Arrow, `_datetime` cannot be naive.
return cast(dt_tzinfo, self._datetime.tzinfo)
@property
def datetime(self) -> dt_datetime:
"""Returns a datetime representation of the :class:`Arrow <arrow.arrow.Arrow>` object.
Usage::
>>> arw=arrow.utcnow()
>>> arw.datetime
datetime.datetime(2019, 1, 24, 16, 35, 27, 276649, tzinfo=tzutc())
"""
return self._datetime
@property
def naive(self) -> dt_datetime:
"""Returns a naive datetime representation of the :class:`Arrow <arrow.arrow.Arrow>`
object.
Usage::
>>> nairobi = arrow.now('Africa/Nairobi')
>>> nairobi
<Arrow [2019-01-23T19:27:12.297999+03:00]>
>>> nairobi.naive
datetime.datetime(2019, 1, 23, 19, 27, 12, 297999)
"""
return self._datetime.replace(tzinfo=None)
def timestamp(self) -> float:
"""Returns a timestamp representation of the :class:`Arrow <arrow.arrow.Arrow>` object, in
UTC time.
Usage::
>>> arrow.utcnow().timestamp()
1616882340.256501
"""
return self._datetime.timestamp()
@property
def int_timestamp(self) -> int:
"""Returns an integer timestamp representation of the :class:`Arrow <arrow.arrow.Arrow>` object, in
UTC time.
Usage::
>>> arrow.utcnow().int_timestamp
1548260567
"""
return int(self.timestamp())
@property
def float_timestamp(self) -> float:
"""Returns a floating-point timestamp representation of the :class:`Arrow <arrow.arrow.Arrow>`
object, in UTC time.
Usage::
>>> arrow.utcnow().float_timestamp
1548260516.830896
"""
return self.timestamp()
@property
def fold(self) -> int:
"""Returns the ``fold`` value of the :class:`Arrow <arrow.arrow.Arrow>` object."""
return self._datetime.fold
@property
def ambiguous(self) -> bool:
"""Indicates whether the :class:`Arrow <arrow.arrow.Arrow>` object is a repeated wall time in the current
timezone.
"""
return dateutil_tz.datetime_ambiguous(self._datetime)
@property
def imaginary(self) -> bool:
"""Indicates whether the :class: `Arrow <arrow.arrow.Arrow>` object exists in the current timezone."""
return not dateutil_tz.datetime_exists(self._datetime)
# mutation and duplication.
def clone(self) -> "Arrow":
"""Returns a new :class:`Arrow <arrow.arrow.Arrow>` object, cloned from the current one.
Usage:
>>> arw = arrow.utcnow()
>>> cloned = arw.clone()
"""
return self.fromdatetime(self._datetime)
def replace(self, **kwargs: Any) -> "Arrow":
"""Returns a new :class:`Arrow <arrow.arrow.Arrow>` object with attributes updated
according to inputs.
Use property names to set their value absolutely::
>>> import arrow
>>> arw = arrow.utcnow()
>>> arw
<Arrow [2013-05-11T22:27:34.787885+00:00]>
>>> arw.replace(year=2014, month=6)
<Arrow [2014-06-11T22:27:34.787885+00:00]>
You can also replace the timezone without conversion, using a
:ref:`timezone expression <tz-expr>`::
>>> arw.replace(tzinfo=tz.tzlocal())
<Arrow [2013-05-11T22:27:34.787885-07:00]>
"""
absolute_kwargs = {}
for key, value in kwargs.items():
if key in self._ATTRS:
absolute_kwargs[key] = value
elif key in ["week", "quarter"]:
raise ValueError(f"Setting absolute {key} is not supported.")
elif key not in ["tzinfo", "fold"]:
raise ValueError(f"Unknown attribute: {key!r}.")
current = self._datetime.replace(**absolute_kwargs)
tzinfo = kwargs.get("tzinfo")
if tzinfo is not None:
tzinfo = self._get_tzinfo(tzinfo)
current = current.replace(tzinfo=tzinfo)
fold = kwargs.get("fold")
if fold is not None:
current = current.replace(fold=fold)
return self.fromdatetime(current)
def shift(self, check_imaginary: bool = True, **kwargs: Any) -> "Arrow":
"""Returns a new :class:`Arrow <arrow.arrow.Arrow>` object with attributes updated
according to inputs.
Parameters:
check_imaginary (bool): If True (default), will check for and resolve
imaginary times (like during DST transitions). If False, skips this check.
Use pluralized property names to relatively shift their current value:
>>> import arrow
>>> arw = arrow.utcnow()
>>> arw
<Arrow [2013-05-11T22:27:34.787885+00:00]>
>>> arw.shift(years=1, months=-1)
<Arrow [2014-04-11T22:27:34.787885+00:00]>
Day-of-the-week relative shifting can use either Python's weekday numbers
(Monday = 0, Tuesday = 1 .. Sunday = 6) or using dateutil.relativedelta's
day instances (MO, TU .. SU). When using weekday numbers, the returned
date will always be greater than or equal to the starting date.
Using the above code (which is a Saturday) and asking it to shift to Saturday:
>>> arw.shift(weekday=5)
<Arrow [2013-05-11T22:27:34.787885+00:00]>
While asking for a Monday:
>>> arw.shift(weekday=0)
<Arrow [2013-05-13T22:27:34.787885+00:00]>
"""
relative_kwargs = {}
additional_attrs = ["weeks", "quarters", "weekday"]
for key, value in kwargs.items():
if key in self._ATTRS_PLURAL or key in additional_attrs:
relative_kwargs[key] = value
else:
supported_attr = ", ".join(self._ATTRS_PLURAL + additional_attrs)
raise ValueError(
f"Invalid shift time frame. Please select one of the following: {supported_attr}."
)
# core datetime does not support quarters, translate to months.
relative_kwargs.setdefault("months", 0)
relative_kwargs["months"] += (
relative_kwargs.pop("quarters", 0) * self._MONTHS_PER_QUARTER
)
current = self._datetime + relativedelta(**relative_kwargs)
# If check_imaginary is True, perform the check for imaginary times (DST transitions)
if check_imaginary and not dateutil_tz.datetime_exists(current):
current = dateutil_tz.resolve_imaginary(current)
return self.fromdatetime(current)
def to(self, tz: TZ_EXPR) -> "Arrow":
"""Returns a new :class:`Arrow <arrow.arrow.Arrow>` object, converted
to the target timezone.
:param tz: A :ref:`timezone expression <tz-expr>`.
Usage::
>>> utc = arrow.utcnow()
>>> utc
<Arrow [2013-05-09T03:49:12.311072+00:00]>
>>> utc.to('US/Pacific')
<Arrow [2013-05-08T20:49:12.311072-07:00]>
>>> utc.to(tz.tzlocal())
<Arrow [2013-05-08T20:49:12.311072-07:00]>
>>> utc.to('-07:00')
<Arrow [2013-05-08T20:49:12.311072-07:00]>
>>> utc.to('local')
<Arrow [2013-05-08T20:49:12.311072-07:00]>
>>> utc.to('local').to('utc')
<Arrow [2013-05-09T03:49:12.311072+00:00]>
"""
if not isinstance(tz, dt_tzinfo):
tz = parser.TzinfoParser.parse(tz)
dt = self._datetime.astimezone(tz)
return self.__class__(
dt.year,
dt.month,
dt.day,
dt.hour,
dt.minute,
dt.second,
dt.microsecond,
dt.tzinfo,
fold=getattr(dt, "fold", 0),
)
# string output and formatting
def format(
self, fmt: str = "YYYY-MM-DD HH:mm:ssZZ", locale: str = DEFAULT_LOCALE
) -> str:
"""Returns a string representation of the :class:`Arrow <arrow.arrow.Arrow>` object,
formatted according to the provided format string. For a list of formatting values,
see :ref:`supported-tokens`
:param fmt: the format string.
:param locale: the locale to format.
Usage::
>>> arrow.utcnow().format('YYYY-MM-DD HH:mm:ss ZZ')
'2013-05-09 03:56:47 -00:00'
>>> arrow.utcnow().format('X')
'1368071882'
>>> arrow.utcnow().format('MMMM DD, YYYY')
'May 09, 2013'
>>> arrow.utcnow().format()
'2013-05-09 03:56:47 -00:00'
"""
return formatter.DateTimeFormatter(locale).format(self._datetime, fmt)
def humanize(
self,
other: Union["Arrow", dt_datetime, None] = None,
locale: str = DEFAULT_LOCALE,
only_distance: bool = False,
granularity: Union[_GRANULARITY, List[_GRANULARITY]] = "auto",
) -> str:
"""Returns a localized, humanized representation of a relative difference in time.
:param other: (optional) an :class:`Arrow <arrow.arrow.Arrow>` or ``datetime`` object.
Defaults to now in the current :class:`Arrow <arrow.arrow.Arrow>` object's timezone.
:param locale: (optional) a ``str`` specifying a locale. Defaults to 'en-us'.
:param only_distance: (optional) returns only time difference eg: "11 seconds" without "in" or "ago" part.
:param granularity: (optional) defines the precision of the output. Set it to strings 'second', 'minute',
'hour', 'day', 'week', 'month' or 'year' or a list of any combination of these strings
Usage::
>>> earlier = arrow.utcnow().shift(hours=-2)
>>> earlier.humanize()
'2 hours ago'
>>> later = earlier.shift(hours=4)
>>> later.humanize(earlier)
'in 4 hours'
"""
locale_name = locale
locale = locales.get_locale(locale)
if other is None:
utc = dt_datetime.now(timezone.utc).replace(tzinfo=timezone.utc)
dt = utc.astimezone(self._datetime.tzinfo)
elif isinstance(other, Arrow):
dt = other._datetime
elif isinstance(other, dt_datetime):
if other.tzinfo is None:
dt = other.replace(tzinfo=self._datetime.tzinfo)
else:
dt = other.astimezone(self._datetime.tzinfo)
else:
raise TypeError(
f"Invalid 'other' argument of type {type(other).__name__!r}. "
"Argument must be of type None, Arrow, or datetime."
)
if isinstance(granularity, list) and len(granularity) == 1:
granularity = granularity[0]
_delta = int(round((self._datetime - dt).total_seconds()))
sign = -1 if _delta < 0 else 1
delta_second = diff = abs(_delta)
try:
if granularity == "auto":
if diff < 10:
return locale.describe("now", only_distance=only_distance)
if diff < self._SECS_PER_MINUTE:
seconds = sign * delta_second
return locale.describe(
"seconds", seconds, only_distance=only_distance
)
elif diff < self._SECS_PER_MINUTE * 2:
return locale.describe("minute", sign, only_distance=only_distance)
elif diff < self._SECS_PER_HOUR:
minutes = sign * max(delta_second // self._SECS_PER_MINUTE, 2)
return locale.describe(
"minutes", minutes, only_distance=only_distance
)
elif diff < self._SECS_PER_HOUR * 2:
return locale.describe("hour", sign, only_distance=only_distance)
elif diff < self._SECS_PER_DAY:
hours = sign * max(delta_second // self._SECS_PER_HOUR, 2)
return locale.describe("hours", hours, only_distance=only_distance)
calendar_diff = (
relativedelta(dt, self._datetime)
if self._datetime < dt
else relativedelta(self._datetime, dt)
)
calendar_months = (
calendar_diff.years * self._MONTHS_PER_YEAR + calendar_diff.months
)
# Round up partial months when already at least one
# calendar month has elapsed and the remaining days
# are more than halfway through another month.
if calendar_months >= 1 and calendar_diff.days > 14:
calendar_months += 1
calendar_months = min(calendar_months, self._MONTHS_PER_YEAR)
if diff < self._SECS_PER_DAY * 2:
return locale.describe("day", sign, only_distance=only_distance)
elif diff < self._SECS_PER_WEEK:
days = sign * max(delta_second // self._SECS_PER_DAY, 2)
return locale.describe("days", days, only_distance=only_distance)
elif diff < self._SECS_PER_WEEK * 2 and calendar_months < 1:
return locale.describe("week", sign, only_distance=only_distance)
elif calendar_months < 1 and diff < self._SECS_PER_MONTH:
weeks = sign * max(delta_second // self._SECS_PER_WEEK, 2)
return locale.describe("weeks", weeks, only_distance=only_distance)
elif calendar_months >= 1 and diff < self._SECS_PER_YEAR:
if calendar_months == 1:
return locale.describe(
"month", sign, only_distance=only_distance
)
else:
months = sign * calendar_months
return locale.describe(
"months", months, only_distance=only_distance
)
elif diff < self._SECS_PER_YEAR * 2:
return locale.describe("year", sign, only_distance=only_distance)
else:
years = sign * max(delta_second // self._SECS_PER_YEAR, 2)
return locale.describe("years", years, only_distance=only_distance)
elif isinstance(granularity, str):
granularity = cast(TimeFrameLiteral, granularity) # type: ignore[assignment]
if granularity == "second":
delta = sign * float(delta_second)
if abs(delta) < 2:
return locale.describe("now", only_distance=only_distance)
elif granularity == "minute":
delta = sign * delta_second / self._SECS_PER_MINUTE
elif granularity == "hour":
delta = sign * delta_second / self._SECS_PER_HOUR
elif granularity == "day":
delta = sign * delta_second / self._SECS_PER_DAY
elif granularity == "week":
delta = sign * delta_second / self._SECS_PER_WEEK
elif granularity == "month":
delta = sign * delta_second / self._SECS_PER_MONTH
elif granularity == "quarter":
delta = sign * delta_second / self._SECS_PER_QUARTER
elif granularity == "year":
delta = sign * delta_second / self._SECS_PER_YEAR
else:
raise ValueError(
"Invalid level of granularity. "
"Please select between 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter' or 'year'."
)
if trunc(abs(delta)) != 1:
granularity += "s" # type: ignore[assignment]
return locale.describe(granularity, delta, only_distance=only_distance)
else:
if not granularity:
raise ValueError(
"Empty granularity list provided. "
"Please select one or more from 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'."
)
timeframes: List[Tuple[TimeFrameLiteral, float]] = []
def gather_timeframes(_delta: float, _frame: TimeFrameLiteral) -> float:
if _frame in granularity:
value = sign * _delta / self._SECS_MAP[_frame]
_delta %= self._SECS_MAP[_frame]
if trunc(abs(value)) != 1:
timeframes.append(
(cast(TimeFrameLiteral, _frame + "s"), value)
)
else:
timeframes.append((_frame, value))
return _delta
delta = float(delta_second)
frames: Tuple[TimeFrameLiteral, ...] = (
"year",
"quarter",
"month",
"week",
"day",
"hour",
"minute",
"second",
)
for frame in frames:
delta = gather_timeframes(delta, frame)
if len(timeframes) < len(granularity):
raise ValueError(
"Invalid level of granularity. "
"Please select between 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter' or 'year'."
)
return locale.describe_multi(timeframes, only_distance=only_distance)
except KeyError as e:
raise ValueError(
f"Humanization of the {e} granularity is not currently translated in the {locale_name!r} locale. "
"Please consider making a contribution to this locale."
)
def dehumanize(self, input_string: str, locale: str = "en_us") -> "Arrow":
"""Returns a new :class:`Arrow <arrow.arrow.Arrow>` object, that represents
the time difference relative to the attributes of the
:class:`Arrow <arrow.arrow.Arrow>` object.
:param timestring: a ``str`` representing a humanized relative time.
:param locale: (optional) a ``str`` specifying a locale. Defaults to 'en-us'.
Usage::
>>> arw = arrow.utcnow()
>>> arw
<Arrow [2021-04-20T22:27:34.787885+00:00]>
>>> earlier = arw.dehumanize("2 days ago")
>>> earlier
<Arrow [2021-04-18T22:27:34.787885+00:00]>
>>> arw = arrow.utcnow()
>>> arw
<Arrow [2021-04-20T22:27:34.787885+00:00]>
>>> later = arw.dehumanize("in a month")
>>> later
<Arrow [2021-05-18T22:27:34.787885+00:00]>
"""
# Create a locale object based off given local
locale_obj = locales.get_locale(locale)
# Check to see if locale is supported
normalized_locale_name = locale.lower().replace("_", "-")
if normalized_locale_name not in DEHUMANIZE_LOCALES:
raise ValueError(
f"Dehumanize does not currently support the {locale} locale, please consider making a contribution to add support for this locale."
)
current_time = self.fromdatetime(self._datetime)
# Create an object containing the relative time info
time_object_info = dict.fromkeys(
["seconds", "minutes", "hours", "days", "weeks", "months", "years"], 0
)
# Create an object representing if unit has been seen
unit_visited = dict.fromkeys(
["now", "seconds", "minutes", "hours", "days", "weeks", "months", "years"],
False,
)
# Create a regex pattern object for numbers
num_pattern = re.compile(r"\d+")
# Search input string for each time unit within locale
for unit, unit_object in locale_obj.timeframes.items():
# Need to check the type of unit_object to create the correct dictionary
if isinstance(unit_object, Mapping):
strings_to_search = unit_object
else:
strings_to_search = {unit: str(unit_object)}
# Search for any matches that exist for that locale's unit.
# Needs to cycle all through strings as some locales have strings that
# could overlap in a regex match, since input validation isn't being performed.
for time_delta, time_string in strings_to_search.items():
# Replace {0} with regex \d representing digits
search_string = str(time_string)
search_string = search_string.format(r"\d+")
# Create search pattern and find within string
pattern = re.compile(rf"(^|\b|\d){search_string}")
match = pattern.search(input_string)
# If there is no match continue to next iteration
if not match:
continue
match_string = match.group()
num_match = num_pattern.search(match_string)
# If no number matches
# Need for absolute value as some locales have signs included in their objects
if not num_match:
change_value = (
1 if not time_delta.isnumeric() else abs(int(time_delta))
)
else:
change_value = int(num_match.group())
# No time to update if now is the unit
if unit == "now":
unit_visited[unit] = True
continue
# Add change value to the correct unit (incorporates the plurality that exists within timeframe i.e second v.s seconds)
time_unit_to_change = str(unit)
time_unit_to_change += (
"s" if (str(time_unit_to_change)[-1] != "s") else ""
)
time_object_info[time_unit_to_change] = change_value
unit_visited[time_unit_to_change] = True
# Assert error if string does not modify any units
if not any([True for k, v in unit_visited.items() if v]):
raise ValueError(
"Input string not valid. Note: Some locales do not support the week granularity in Arrow. "
"If you are attempting to use the week granularity on an unsupported locale, this could be the cause of this error."
)
# Sign logic
future_string = locale_obj.future
future_string = future_string.format(".*")
future_pattern = re.compile(rf"^{future_string}$")
future_pattern_match = future_pattern.findall(input_string)
past_string = locale_obj.past
past_string = past_string.format(".*")
past_pattern = re.compile(rf"^{past_string}$")
past_pattern_match = past_pattern.findall(input_string)
# If a string contains the now unit, there will be no relative units, hence the need to check if the now unit
# was visited before raising a ValueError
if past_pattern_match:
sign_val = -1
elif future_pattern_match:
sign_val = 1
elif unit_visited["now"]:
sign_val = 0
else:
raise ValueError(
"Invalid input String. String does not contain any relative time information. "
"String should either represent a time in the future or a time in the past. "
"Ex: 'in 5 seconds' or '5 seconds ago'."
)
time_changes = {k: sign_val * v for k, v in time_object_info.items()}
return current_time.shift(check_imaginary=True, **time_changes)
# query functions
def is_between(
self,
start: "Arrow",
end: "Arrow",
bounds: _BOUNDS = "()",
) -> bool:
"""Returns a boolean denoting whether the :class:`Arrow <arrow.arrow.Arrow>` object is between
the start and end limits.
:param start: an :class:`Arrow <arrow.arrow.Arrow>` object.
:param end: an :class:`Arrow <arrow.arrow.Arrow>` object.
:param bounds: (optional) a ``str`` of either '()', '(]', '[)', or '[]' that specifies
whether to include or exclude the start and end values in the range. '(' excludes
the start, '[' includes the start, ')' excludes the end, and ']' includes the end.
If the bounds are not specified, the default bound '()' is used.
Usage::
>>> start = arrow.get(datetime(2013, 5, 5, 12, 30, 10))
>>> end = arrow.get(datetime(2013, 5, 5, 12, 30, 36))
>>> arrow.get(datetime(2013, 5, 5, 12, 30, 27)).is_between(start, end)
True
>>> start = arrow.get(datetime(2013, 5, 5))
>>> end = arrow.get(datetime(2013, 5, 8))
>>> arrow.get(datetime(2013, 5, 8)).is_between(start, end, '[]')
True
>>> start = arrow.get(datetime(2013, 5, 5))
>>> end = arrow.get(datetime(2013, 5, 8))
>>> arrow.get(datetime(2013, 5, 8)).is_between(start, end, '[)')
False
"""
util.validate_bounds(bounds)
if not isinstance(start, Arrow):
raise TypeError(
f"Cannot parse start date argument type of {type(start)!r}."
)
if not isinstance(end, Arrow):
raise TypeError(f"Cannot parse end date argument type of {type(start)!r}.")
include_start = bounds[0] == "["
include_end = bounds[1] == "]"
target_ts = self.float_timestamp
start_ts = start.float_timestamp
end_ts = end.float_timestamp
return (
(start_ts <= target_ts <= end_ts)
and (include_start or start_ts < target_ts)
and (include_end or target_ts < end_ts)
)
# datetime methods
def date(self) -> dt_date:
"""Returns a ``date`` object with the same year, month and day.
Usage::
>>> arrow.utcnow().date()
datetime.date(2019, 1, 23)
"""
return self._datetime.date()
def time(self) -> dt_time:
"""Returns a ``time`` object with the same hour, minute, second, microsecond.
Usage::
>>> arrow.utcnow().time()
datetime.time(12, 15, 34, 68352)
"""
return self._datetime.time()
def timetz(self) -> dt_time:
"""Returns a ``time`` object with the same hour, minute, second, microsecond and
tzinfo.
Usage::
>>> arrow.utcnow().timetz()
datetime.time(12, 5, 18, 298893, tzinfo=tzutc())
"""
return self._datetime.timetz()
def astimezone(self, tz: Optional[dt_tzinfo]) -> dt_datetime:
"""Returns a ``datetime`` object, converted to the specified timezone.
:param tz: a ``tzinfo`` object.
Usage::
>>> pacific=arrow.now('US/Pacific')
>>> nyc=arrow.now('America/New_York').tzinfo
>>> pacific.astimezone(nyc)
datetime.datetime(2019, 1, 20, 10, 24, 22, 328172, tzinfo=tzfile('/usr/share/zoneinfo/America/New_York'))
"""
return self._datetime.astimezone(tz)
def utcoffset(self) -> Optional[timedelta]:
"""Returns a ``timedelta`` object representing the whole number of minutes difference from
UTC time.
Usage::
>>> arrow.now('US/Pacific').utcoffset()
datetime.timedelta(-1, 57600)
"""
return self._datetime.utcoffset()
def dst(self) -> Optional[timedelta]:
"""Returns the daylight savings time adjustment.
Usage::
>>> arrow.utcnow().dst()
datetime.timedelta(0)
"""
return self._datetime.dst()
def timetuple(self) -> struct_time:
"""Returns a ``time.struct_time``, in the current timezone.
Usage::
>>> arrow.utcnow().timetuple()
time.struct_time(tm_year=2019, tm_mon=1, tm_mday=20, tm_hour=15, tm_min=17, tm_sec=8, tm_wday=6, tm_yday=20, tm_isdst=0)
"""
return self._datetime.timetuple()
def utctimetuple(self) -> struct_time:
"""Returns a ``time.struct_time``, in UTC time.
Usage::
>>> arrow.utcnow().utctimetuple()
time.struct_time(tm_year=2019, tm_mon=1, tm_mday=19, tm_hour=21, tm_min=41, tm_sec=7, tm_wday=5, tm_yday=19, tm_isdst=0)
"""
return self._datetime.utctimetuple()
def toordinal(self) -> int:
"""Returns the proleptic Gregorian ordinal of the date.
Usage::
>>> arrow.utcnow().toordinal()
737078
"""
return self._datetime.toordinal()
def weekday(self) -> int:
"""Returns the day of the week as an integer (0-6).
Usage::
>>> arrow.utcnow().weekday()
5
"""
return self._datetime.weekday()
def isoweekday(self) -> int:
"""Returns the ISO day of the week as an integer (1-7).
Usage::
>>> arrow.utcnow().isoweekday()
6
"""
return self._datetime.isoweekday()
def isocalendar(self) -> Tuple[int, int, int]:
"""Returns a 3-tuple, (ISO year, ISO week number, ISO weekday).
Usage::
>>> arrow.utcnow().isocalendar()
(2019, 3, 6)
"""
return self._datetime.isocalendar()
def isoformat(self, sep: str = "T", timespec: str = "auto") -> str:
"""Returns an ISO 8601 formatted representation of the date and time.
Usage::
>>> arrow.utcnow().isoformat()
'2019-01-19T18:30:52.442118+00:00'
"""
return self._datetime.isoformat(sep, timespec)
def ctime(self) -> str:
"""Returns a ctime formatted representation of the date and time.
Usage::
>>> arrow.utcnow().ctime()
'Sat Jan 19 18:26:50 2019'
"""
return self._datetime.ctime()
def strftime(self, format: str) -> str:
"""Formats in the style of ``datetime.strftime``.
:param format: the format string.
Usage::
>>> arrow.utcnow().strftime('%d-%m-%Y %H:%M:%S')
'23-01-2019 12:28:17'
"""
return self._datetime.strftime(format)
def for_json(self) -> str:
"""Serializes for the ``for_json`` protocol of simplejson.
Usage::
>>> arrow.utcnow().for_json()
'2019-01-19T18:25:36.760079+00:00'
"""
return self.isoformat()
# math
def __add__(self, other: Any) -> "Arrow":
if isinstance(other, (timedelta, relativedelta)):
return self.fromdatetime(self._datetime + other, self._datetime.tzinfo)
return NotImplemented
def __radd__(self, other: Union[timedelta, relativedelta]) -> "Arrow":
return self.__add__(other)
@overload
def __sub__(self, other: Union[timedelta, relativedelta]) -> "Arrow":
pass # pragma: no cover
@overload
def __sub__(self, other: Union[dt_datetime, "Arrow"]) -> timedelta:
pass # pragma: no cover
def __sub__(self, other: Any) -> Union[timedelta, "Arrow"]:
if isinstance(other, (timedelta, relativedelta)):
return self.fromdatetime(self._datetime - other, self._datetime.tzinfo)
elif isinstance(other, dt_datetime):
return self._datetime - other
elif isinstance(other, Arrow):
return self._datetime - other._datetime
return NotImplemented
def __rsub__(self, other: Any) -> timedelta:
if isinstance(other, dt_datetime):
return other - self._datetime
return NotImplemented
# comparisons
def __eq__(self, other: Any) -> bool:
if not isinstance(other, (Arrow, dt_datetime)):
return False
return self._datetime == self._get_datetime(other)
def __ne__(self, other: Any) -> bool:
if not isinstance(other, (Arrow, dt_datetime)):
return True
return not self.__eq__(other)
def __gt__(self, other: Any) -> bool:
if not isinstance(other, (Arrow, dt_datetime)):
return NotImplemented
return self._datetime > self._get_datetime(other)
def __ge__(self, other: Any) -> bool:
if not isinstance(other, (Arrow, dt_datetime)):
return NotImplemented
return self._datetime >= self._get_datetime(other)
def __lt__(self, other: Any) -> bool:
if not isinstance(other, (Arrow, dt_datetime)):
return NotImplemented
return self._datetime < self._get_datetime(other)
def __le__(self, other: Any) -> bool:
if not isinstance(other, (Arrow, dt_datetime)):
return NotImplemented
return self._datetime <= self._get_datetime(other)
# internal methods
@staticmethod
def _get_tzinfo(tz_expr: Optional[TZ_EXPR]) -> dt_tzinfo:
"""Get normalized tzinfo object from various inputs."""
if tz_expr is None:
return timezone.utc
if isinstance(tz_expr, dt_tzinfo):
return tz_expr
else:
try:
return parser.TzinfoParser.parse(tz_expr)
except parser.ParserError:
raise ValueError(f"{tz_expr!r} not recognized as a timezone.")
@classmethod
def _get_datetime(
cls, expr: Union["Arrow", dt_datetime, int, float, str]
) -> dt_datetime:
"""Get datetime object from a specified expression."""
if isinstance(expr, Arrow):
return expr.datetime
elif isinstance(expr, dt_datetime):
return expr
elif util.is_timestamp(expr):
timestamp = float(expr)
return cls.utcfromtimestamp(timestamp).datetime
else:
raise ValueError(f"{expr!r} not recognized as a datetime or timestamp.")
@classmethod
def _get_frames(cls, name: _T_FRAMES) -> Tuple[str, str, int]:
"""Finds relevant timeframe and steps for use in range and span methods.
Returns a 3 element tuple in the form (frame, plural frame, step), for example ("day", "days", 1)
"""
if name in cls._ATTRS:
return name, f"{name}s", 1
elif name[-1] == "s" and name[:-1] in cls._ATTRS:
return name[:-1], name, 1
elif name in ["week", "weeks"]:
return "week", "weeks", 1
elif name in ["quarter", "quarters"]:
return "quarter", "months", 3
else:
supported = ", ".join(
[
"year(s)",
"month(s)",
"day(s)",
"hour(s)",
"minute(s)",
"second(s)",
"microsecond(s)",
"week(s)",
"quarter(s)",
]
)
raise ValueError(
f"Range or span over frame {name} not supported. Supported frames: {supported}."
)
@classmethod
def _get_iteration_params(cls, end: Any, limit: Optional[int]) -> Tuple[Any, int]:
"""Sets default end and limit values for range method."""
if end is None:
if limit is None:
raise ValueError("One of 'end' or 'limit' is required.")
return cls.max, limit
else:
if limit is None:
return end, sys.maxsize
return end, limit
@staticmethod
def _is_last_day_of_month(date: "Arrow") -> bool:
"""Returns a boolean indicating whether the datetime is the last day of the month."""
return cast(int, date.day) == calendar.monthrange(date.year, date.month)[1]
Arrow.min = Arrow.fromdatetime(dt_datetime.min)
Arrow.max = Arrow.fromdatetime(dt_datetime.max)
================================================
FILE: arrow/constants.py
================================================
"""Constants used internally in arrow."""
import sys
from datetime import datetime
from typing import Final
# datetime.max.timestamp() errors on Windows, so we must hardcode
# the highest possible datetime value that can output a timestamp.
# tl;dr platform-independent max timestamps are hard to form
# See: https://stackoverflow.com/q/46133223
try:
# Get max timestamp. Works on POSIX-based systems like Linux and macOS,
# but will trigger an OverflowError, ValueError, or OSError on Windows
_MAX_TIMESTAMP = datetime.max.timestamp()
except (OverflowError, ValueError, OSError): # pragma: no cover
# Fallback for Windows and 32-bit systems if initial max timestamp call fails
# Must get max value of ctime on Windows based on architecture (x32 vs x64)
# https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/ctime-ctime32-ctime64-wctime-wctime32-wctime64
# Note: this may occur on both 32-bit Linux systems (issue #930) along with Windows systems
is_64bits = sys.maxsize > 2**32
_MAX_TIMESTAMP = (
datetime(3000, 1, 1, 23, 59, 59, 999999).timestamp()
if is_64bits
else datetime(2038, 1, 1, 23, 59, 59, 999999).timestamp()
)
MAX_TIMESTAMP: Final[float] = _MAX_TIMESTAMP
MAX_TIMESTAMP_MS: Final[float] = MAX_TIMESTAMP * 1000
MAX_TIMESTAMP_US: Final[float] = MAX_TIMESTAMP * 1_000_000
MAX_ORDINAL: Final[int] = datetime.max.toordinal()
MIN_ORDINAL: Final[int] = 1
DEFAULT_LOCALE: Final[str] = "en-us"
# Supported dehumanize locales
DEHUMANIZE_LOCALES = {
"en",
"en-us",
"en-gb",
"en-au",
"en-be",
"en-jp",
"en-za",
"en-ca",
"en-ph",
"fr",
"fr-fr",
"fr-ca",
"it",
"it-it",
"es",
"es-es",
"el",
"el-gr",
"ja",
"ja-jp",
"se",
"se-fi",
"se-no",
"se-se",
"sv",
"sv-se",
"fi",
"fi-fi",
"zh",
"zh-cn",
"zh-tw",
"zh-hk",
"nl",
"nl-nl",
"be",
"be-by",
"pl",
"pl-pl",
"ru",
"ru-ru",
"af",
"bg",
"bg-bg",
"ua",
"uk",
"uk-ua",
"mk",
"mk-mk",
"de",
"de-de",
"de-ch",
"de-at",
"nb",
"nb-no",
"nn",
"nn-no",
"pt",
"pt-pt",
"pt-br",
"tl",
"tl-ph",
"vi",
"vi-vn",
"tr",
"tr-tr",
"az",
"az-az",
"da",
"da-dk",
"ml",
"hi",
"cs",
"cs-cz",
"sk",
"sk-sk",
"fa",
"fa-ir",
"mr",
"ca",
"ca-es",
"ca-ad",
"ca-fr",
"ca-it",
"eo",
"eo-xx",
"bn",
"bn-bd",
"bn-in",
"rm",
"rm-ch",
"ro",
"ro-ro",
"sl",
"sl-si",
"id",
"id-id",
"ne",
"ne-np",
"ee",
"et",
"sw",
"sw-ke",
"sw-tz",
"la",
"la-va",
"lt",
"lt-lt",
"ms",
"ms-my",
"ms-bn",
"or",
"or-in",
"lb",
"lb-lu",
"zu",
"zu-za",
"sq",
"sq-al",
"ta",
"ta-in",
"ta-lk",
"ur",
"ur-pk",
"ka",
"ka-ge",
"kk",
"kk-kz",
# "lo",
# "lo-la",
"am",
"am-et",
"hy-am",
"hy",
"uz",
"uz-uz",
}
================================================
FILE: arrow/factory.py
================================================
"""
Implements the :class:`ArrowFactory <arrow.factory.ArrowFactory>` class,
providing factory methods for common :class:`Arrow <arrow.arrow.Arrow>`
construction scenarios.
"""
import calendar
from datetime import date, datetime, timezone
from datetime import tzinfo as dt_tzinfo
from decimal import Decimal
from time import struct_time
from typing import Any, List, Optional, Tuple, Type, Union, overload
from arrow import parser
from arrow.arrow import TZ_EXPR, Arrow
from arrow.constants import DEFAULT_LOCALE
from arrow.util import is_timestamp, iso_to_gregorian
class ArrowFactory:
"""A factory for generating :class:`Arrow <arrow.arrow.Arrow>` objects.
:param type: (optional) the :class:`Arrow <arrow.arrow.Arrow>`-based class to construct from.
Defaults to :class:`Arrow <arrow.arrow.Arrow>`.
"""
type: Type[Arrow]
def __init__(self, type: Type[Arrow] = Arrow) -> None:
self.type = type
@overload
def get(
self,
*,
locale: str = DEFAULT_LOCALE,
tzinfo: Optional[TZ_EXPR] = None,
normalize_whitespace: bool = False,
) -> Arrow: ... # pragma: no cover
@overload
def get(
self,
__obj: Union[
Arrow,
datetime,
date,
struct_time,
dt_tzinfo,
int,
float,
str,
Tuple[int, int, int],
],
*,
locale: str = DEFAULT_LOCALE,
tzinfo: Optional[TZ_EXPR] = None,
normalize_whitespace: bool = False,
) -> Arrow: ... # pragma: no cover
@overload
def get(
self,
__arg1: Union[datetime, date],
__arg2: TZ_EXPR,
*,
locale: str = DEFAULT_LOCALE,
tzinfo: Optional[TZ_EXPR] = None,
normalize_whitespace: bool = False,
) -> Arrow: ... # pragma: no cover
@overload
def get(
self,
__arg1: str,
__arg2: Union[str, List[str]],
*,
locale: str = DEFAULT_LOCALE,
tzinfo: Optional[TZ_EXPR] = None,
normalize_whitespace: bool = False,
) -> Arrow: ... # pragma: no cover
def get(self, *args: Any, **kwargs: Any) -> Arrow:
"""Returns an :class:`Arrow <arrow.arrow.Arrow>` object based on flexible inputs.
:param locale: (optional) a ``str`` specifying a locale for the parser. Defaults to 'en-us'.
:param tzinfo: (optional) a :ref:`timezone expression <tz-expr>` or tzinfo object.
Replaces the timezone unless using an input form that is explicitly UTC or specifies
the timezone in a positional argument. Defaults to UTC.
:param normalize_whitespace: (optional) a ``bool`` specifying whether or not to normalize
redundant whitespace (spaces, tabs, and newlines) in a datetime string before parsing.
Defaults to false.
Usage::
>>> import arrow
**No inputs** to get current UTC time::
>>> arrow.get()
<Arrow [2013-05-08T05:51:43.316458+00:00]>
**One** :class:`Arrow <arrow.arrow.Arrow>` object, to get a copy.
>>> arw = arrow.utcnow()
>>> arrow.get(arw)
<Arrow [2013-10-23T15:21:54.354846+00:00]>
**One** ``float`` or ``int``, convertible to a floating-point timestamp, to get
that timestamp in UTC::
>>> arrow.get(1367992474.293378)
<Arrow [2013-05-08T05:54:34.293378+00:00]>
>>> arrow.get(1367992474)
<Arrow [2013-05-08T05:54:34+00:00]>
**One** ISO 8601-formatted ``str``, to parse it::
>>> arrow.get('2013-09-29T01:26:43.830580')
<Arrow [2013-09-29T01:26:43.830580+00:00]>
**One** ISO 8601-formatted ``str``, in basic format, to parse it::
>>> arrow.get('20160413T133656.456289')
<Arrow [2016-04-13T13:36:56.456289+00:00]>
**One** ``tzinfo``, to get the current time **converted** to that timezone::
>>> arrow.get(tz.tzlocal())
<Arrow [2013-05-07T22:57:28.484717-07:00]>
**One** naive ``datetime``, to get that datetime in UTC::
>>> arrow.get(datetime(2013, 5, 5))
<Arrow [2013-05-05T00:00:00+00:00]>
**One** aware ``datetime``, to get that datetime::
>>> arrow.get(datetime(2013, 5, 5, tzinfo=tz.tzlocal()))
<Arrow [2013-05-05T00:00:00-07:00]>
**One** naive ``date``, to get that date in UTC::
>>> arrow.get(date(2013, 5, 5))
<Arrow [2013-05-05T00:00:00+00:00]>
**One** time.struct time::
>>> arrow.get(gmtime(0))
<Arrow [1970-01-01T00:00:00+00:00]>
**One** iso calendar ``tuple``, to get that week date in UTC::
>>> arrow.get((2013, 18, 7))
<Arrow [2013-05-05T00:00:00+00:00]>
**Two** arguments, a naive or aware ``datetime``, and a replacement
:ref:`timezone expression <tz-expr>`::
>>> arrow.get(datetime(2013, 5, 5), 'US/Pacific')
<Arrow [2013-05-05T00:00:00-07:00]>
**Two** arguments, a naive ``date``, and a replacement
:ref:`timezone expression <tz-expr>`::
>>> arrow.get(date(2013, 5, 5), 'US/Pacific')
<Arrow [2013-05-05T00:00:00-07:00]>
**Two** arguments, both ``str``, to parse the first according to the format of the second::
>>> arrow.get('2013-05-05 12:30:45 America/Chicago', 'YYYY-MM-DD HH:mm:ss ZZZ')
<Arrow [2013-05-05T12:30:45-05:00]>
**Two** arguments, first a ``str`` to parse and second a ``list`` of formats to try::
>>> arrow.get('2013-05-05 12:30:45', ['MM/DD/YYYY', 'YYYY-MM-DD HH:mm:ss'])
<Arrow [2013-05-05T12:30:45+00:00]>
**Three or more** arguments, as for the direct constructor of an ``Arrow`` object::
>>> arrow.get(2013, 5, 5, 12, 30, 45)
<Arrow [2013-05-05T12:30:45+00:00]>
"""
arg_count = len(args)
locale = kwargs.pop("locale", DEFAULT_LOCALE)
tz = kwargs.get("tzinfo", None)
normalize_whitespace = kwargs.pop("normalize_whitespace", False)
# if kwargs given, send to constructor unless only tzinfo provided
if len(kwargs) > 1:
arg_count = 3
# tzinfo kwarg is not provided
if len(kwargs) == 1 and tz is None:
arg_count = 3
# () -> now, @ tzinfo or utc
if arg_count == 0:
if isinstance(tz, str):
tz = parser.TzinfoParser.parse(tz)
return self.type.now(tzinfo=tz)
if isinstance(tz, dt_tzinfo):
return self.type.now(tzinfo=tz)
return self.type.utcnow()
if arg_count == 1:
arg = args[0]
if isinstance(arg, Decimal):
arg = float(arg)
# (None) -> raises an exception
if arg is None:
raise TypeError("Cannot parse argument of type None.")
# try (int, float) -> from timestamp @ tzinfo
elif not isinstance(arg, str) and is_timestamp(arg):
if tz is None:
# set to UTC by default
tz = timezone.utc
return self.type.fromtimestamp(arg, tzinfo=tz)
# (Arrow) -> from the object's datetime @ tzinfo
elif isinstance(arg, Arrow):
return self.type.fromdatetime(arg.datetime, tzinfo=tz)
# (datetime) -> from datetime @ tzinfo
elif isinstance(arg, datetime):
return self.type.fromdatetime(arg, tzinfo=tz)
# (date) -> from date @ tzinfo
elif isinstance(arg, date):
return self.type.fromdate(arg, tzinfo=tz)
# (tzinfo) -> now @ tzinfo
elif isinstance(arg, dt_tzinfo):
return self.type.now(tzinfo=arg)
# (str) -> parse @ tzinfo
elif isinstance(arg, str):
dt = parser.DateTimeParser(locale).parse_iso(arg, normalize_whitespace)
return self.type.fromdatetime(dt, tzinfo=tz)
# (struct_time) -> from struct_time
elif isinstance(arg, struct_time):
return self.type.utcfromtimestamp(calendar.timegm(arg))
# (iso calendar) -> convert then from date @ tzinfo
elif isinstance(arg, tuple) and len(arg) == 3:
d = iso_to_gregorian(*arg)
return self.type.fromdate(d, tzinfo=tz)
else:
raise TypeError(f"Cannot parse single argument of type {type(arg)!r}.")
elif arg_count == 2:
arg_1, arg_2 = args[0], args[1]
if isinstance(arg_1, datetime):
# (datetime, tzinfo/str) -> fromdatetime @ tzinfo
if isinstance(arg_2, (dt_tzinfo, str)):
return self.type.fromdatetime(arg_1, tzinfo=arg_2)
else:
raise TypeError(
f"Cannot parse two arguments of types 'datetime', {type(arg_2)!r}."
)
elif isinstance(arg_1, date):
# (date, tzinfo/str) -> fromdate @ tzinfo
if isinstance(arg_2, (dt_tzinfo, str)):
return self.type.fromdate(arg_1, tzinfo=arg_2)
else:
raise TypeError(
f"Cannot parse two arguments of types 'date', {type(arg_2)!r}."
)
# (str, format) -> parse @ tzinfo
elif isinstance(arg_1, str) and isinstance(arg_2, (str, list)):
dt = parser.DateTimeParser(locale).parse(
args[0], args[1], normalize_whitespace
)
return self.type.fromdatetime(dt, tzinfo=tz)
else:
raise TypeError(
f"Cannot parse two arguments of types {type(arg_1)!r} and {type(arg_2)!r}."
)
# 3+ args -> datetime-like via constructor
else:
return self.type(*args, **kwargs)
def utcnow(self) -> Arrow:
"""Returns an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in UTC time.
Usage::
>>> import arrow
>>> arrow.utcnow()
<Arrow [2013-05-08T05:19:07.018993+00:00]>
"""
return self.type.utcnow()
def now(self, tz: Optional[TZ_EXPR] = None) -> Arrow:
"""Returns an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in the given
timezone.
:param tz: (optional) A :ref:`timezone expression <tz-expr>`. Defaults to local time.
Usage::
>>> import arrow
>>> arrow.now()
<Arrow [2013-05-07T22:19:11.363410-07:00]>
>>> arrow.now('US/Pacific')
<Arrow [2013-05-07T22:19:15.251821-07:00]>
>>> arrow.now('+02:00')
<Arrow [2013-05-08T07:19:25.618646+02:00]>
>>> arrow.now('local')
<Arrow [2013-05-07T22:19:39.130059-07:00]>
"""
if tz is None:
tz = datetime.now().astimezone().tzinfo
elif not isinstance(tz, dt_tzinfo):
tz = parser.TzinfoParser.parse(tz)
return self.type.now(tz)
================================================
FILE: arrow/formatter.py
================================================
"""Provides the :class:`Arrow <arrow.formatter.DateTimeFormatter>` class, an improved formatter for datetimes."""
import re
from datetime import datetime, timedelta, timezone
from typing import Final, Optional, Pattern, cast
from arrow import locales
from arrow.constants import DEFAULT_LOCALE
FORMAT_ATOM: Final[str] = "YYYY-MM-DD HH:mm:ssZZ"
FORMAT_COOKIE: Final[str] = "dddd, DD-MMM-YYYY HH:mm:ss ZZZ"
FORMAT_RFC822: Final[str] = "ddd, DD MMM YY HH:mm:ss Z"
FORMAT_RFC850: Final[str] = "dddd, DD-MMM-YY HH:mm:ss ZZZ"
FORMAT_RFC1036: Final[str] = "ddd, DD MMM YY HH:mm:ss Z"
FORMAT_RFC1123: Final[str] = "ddd, DD MMM YYYY HH:mm:ss Z"
FORMAT_RFC2822: Final[str] = "ddd, DD MMM YYYY HH:mm:ss Z"
FORMAT_RFC3339: Final[str] = "YYYY-MM-DD HH:mm:ssZZ"
FORMAT_RFC3339_STRICT: Final[str] = "YYYY-MM-DDTHH:mm:ssZZ"
FORMAT_RSS: Final[str] = "ddd, DD MMM YYYY HH:mm:ss Z"
FORMAT_W3C: Final[str] = "YYYY-MM-DD HH:mm:ssZZ"
class DateTimeFormatter:
# This pattern matches characters enclosed in square brackets are matched as
# an atomic group. For more info on atomic groups and how to they are
# emulated in Python's re library, see https://stackoverflow.com/a/13577411/2701578
_FORMAT_RE: Final[Pattern[str]] = re.compile(
r"(\[(?:(?=(?P<literal>[^]]))(?P=literal))*\]|YYY?Y?|MM?M?M?|Do|DD?D?D?|d?dd?d?|HH?|hh?|mm?|ss?|SS?S?S?S?S?|ZZ?Z?|a|A|X|x|W)"
)
locale: locales.Locale
def __init__(self, locale: str = DEFAULT_LOCALE) -> None:
self.locale = locales.get_locale(locale)
def format(cls, dt: datetime, fmt: str) -> str:
# FIXME: _format_token() is nullable
return cls._FORMAT_RE.sub(
lambda m: cast(str, cls._format_token(dt, m.group(0))), fmt
)
def _format_token(self, dt: datetime, token: Optional[str]) -> Optional[str]:
if token and token.startswith("[") and token.endswith("]"):
return token[1:-1]
if token == "YYYY":
return self.locale.year_full(dt.year)
if token == "YY":
return self.locale.year_abbreviation(dt.year)
if token == "MMMM":
return self.locale.month_name(dt.month)
if token == "MMM":
return self.locale.month_abbreviation(dt.month)
if token == "MM":
return f"{dt.month:02d}"
if token == "M":
return f"{dt.month}"
if token == "DDDD":
return f"{dt.timetuple().tm_yday:03d}"
if token == "DDD":
return f"{dt.timetuple().tm_yday}"
if token == "DD":
return f"{dt.day:02d}"
if token == "D":
return f"{dt.day}"
if token == "Do":
return self.locale.ordinal_number(dt.day)
if token == "dddd":
return self.locale.day_name(dt.isoweekday())
if token == "ddd":
return self.locale.day_abbreviation(dt.isoweekday())
if token == "d":
return f"{dt.isoweekday()}"
if token == "HH":
return f"{dt.hour:02d}"
if token == "H":
return f"{dt.hour}"
if token == "hh":
return f"{dt.hour if 0 < dt.hour < 13 else abs(dt.hour - 12):02d}"
if token == "h":
return f"{dt.hour if 0 < dt.hour < 13 else abs(dt.hour - 12)}"
if token == "mm":
return f"{dt.minute:02d}"
if token == "m":
return f"{dt.minute}"
if token == "ss":
return f"{dt.second:02d}"
if token == "s":
return f"{dt.second}"
if token == "SSSSSS":
return f"{dt.microsecond:06d}"
if token == "SSSSS":
return f"{dt.microsecond // 10:05d}"
if token == "SSSS":
return f"{dt.microsecond // 100:04d}"
if token == "SSS":
return f"{dt.microsecond // 1000:03d}"
if token == "SS":
return f"{dt.microsecond // 10000:02d}"
if token == "S":
return f"{dt.microsecond // 100000}"
if token == "X":
return f"{dt.timestamp()}"
if token == "x":
return f"{dt.timestamp() * 1_000_000:.0f}"
if token == "ZZZ":
return dt.tzname()
if token in ["ZZ", "Z"]:
separator = ":" if token == "ZZ" else ""
tz = timezone.utc if dt.tzinfo is None else dt.tzinfo
# `dt` must be aware object. Otherwise, this line will raise AttributeError
# https://github.com/arrow-py/arrow/pull/883#discussion_r529866834
# datetime awareness: https://docs.python.org/3/library/datetime.html#aware-and-naive-objects
total_minutes = int(cast(timedelta, tz.utcoffset(dt)).total_seconds() / 60)
sign = "+" if total_minutes >= 0 else "-"
total_minutes = abs(total_minutes)
hour, minute = divmod(total_minutes, 60)
return f"{sign}{hour:02d}{separator}{minute:02d}"
if token in ("a", "A"):
return self.locale.meridian(dt.hour, token)
if token == "W":
year, week, day = dt.isocalendar()
return f"{year}-W{week:02d}-{day}"
================================================
FILE: arrow/locales.py
================================================
"""Provides internationalization for arrow in over 60 languages and dialects."""
from math import trunc
from typing import (
Any,
ClassVar,
Dict,
List,
Literal,
Mapping,
Optional,
Sequence,
Tuple,
Type,
Union,
cast,
)
TimeFrameLiteral = Literal[
"now",
"second",
"seconds",
"minute",
"minutes",
"hour",
"hours",
"day",
"days",
"week",
"weeks",
"month",
"months",
"quarter",
"quarters",
"year",
"years",
]
_TimeFrameElements = Union[
str, Sequence[str], Mapping[str, str], Mapping[str, Sequence[str]]
]
_locale_map: Dict[str, Type["Locale"]] = {}
def get_locale(name: str) -> "Locale":
"""Returns an appropriate :class:`Locale <arrow.locales.Locale>`
corresponding to an input locale name.
:param name: the name of the locale.
"""
normalized_locale_name = name.lower().replace("_", "-")
locale_cls = _locale_map.get(normalized_locale_name)
if locale_cls is None:
raise ValueError(f"Unsupported locale {normalized_locale_name!r}.")
return locale_cls()
def get_locale_by_class_name(name: str) -> "Locale":
"""Returns an appropriate :class:`Locale <arrow.locales.Locale>`
corresponding to an locale class name.
:param name: the name of the locale class.
"""
locale_cls: Optional[Type[Locale]] = globals().get(name)
if locale_cls is None:
raise ValueError(f"Unsupported locale {name!r}.")
return locale_cls()
class Locale:
"""Represents locale-specific data and functionality."""
names: ClassVar[List[str]] = []
timeframes: ClassVar[Mapping[TimeFrameLiteral, _TimeFrameElements]] = {
"now": "",
"second": "",
"seconds": "",
"minute": "",
"minutes": "",
"hour": "",
"hours": "",
"day": "",
"days": "",
"week": "",
"weeks": "",
"month": "",
"months": "",
"quarter": "",
"quarters": "",
"year": "",
"years": "",
}
meridians: ClassVar[Dict[str, str]] = {"am": "", "pm": "", "AM": "", "PM": ""}
past: ClassVar[str]
future: ClassVar[str]
and_word: ClassVar[Optional[str]] = None
month_names: ClassVar[List[str]] = []
month_abbreviations: ClassVar[List[str]] = []
day_names: ClassVar[List[str]] = []
day_abbreviations: ClassVar[List[str]] = []
ordinal_day_re: ClassVar[str] = r"(\d+)"
_month_name_to_ordinal: Optional[Dict[str, int]]
def __init_subclass__(cls, **kwargs: Any) -> None:
for locale_name in cls.names:
if locale_name in _locale_map:
raise LookupError(f"Duplicated locale name: {locale_name}")
_locale_map[locale_name.lower().replace("_", "-")] = cls
def __init__(self) -> None:
self._month_name_to_ordinal = None
def describe(
self,
timeframe: TimeFrameLiteral,
delta: Union[float, int] = 0,
only_distance: bool = False,
) -> str:
"""Describes a delta within a timeframe in plain language.
:param timeframe: a string representing a timeframe.
:param delta: a quantity representing a delta in a timeframe.
:param only_distance: return only distance eg: "11 seconds" without "in" or "ago" keywords
"""
humanized = self._format_timeframe(timeframe, trunc(delta))
if not only_distance:
humanized = self._format_relative(humanized, timeframe, delta)
return humanized
def describe_multi(
self,
timeframes: Sequence[Tuple[TimeFrameLiteral, Union[int, float]]],
only_distance: bool = False,
) -> str:
"""Describes a delta within multiple timeframes in plain language.
:param timeframes: a list of string, quantity pairs each representing a timeframe and delta.
:param only_distance: return only distance eg: "2 hours and 11 seconds" without "in" or "ago" keywords
"""
parts = [
self._format_timeframe(timeframe, trunc(delta))
for timeframe, delta in timeframes
]
if self.and_word:
parts.insert(-1, self.and_word)
humanized = " ".join(parts)
if not only_distance:
# Needed to determine the correct relative string to use
timeframe_value = 0
for _, unit_value in timeframes:
if trunc(unit_value) != 0:
timeframe_value = trunc(unit_value)
break
# Note it doesn't matter the timeframe unit we use on the call, only the value
humanized = self._format_relative(humanized, "seconds", timeframe_value)
return humanized
def day_name(self, day: int) -> str:
"""Returns the day name for a specified day of the week.
:param day: the ``int`` day of the week (1-7).
"""
return self.day_names[day]
def day_abbreviation(self, day: int) -> str:
"""Returns the day abbreviation for a specified day of the week.
:param day: the ``int`` day of the week (1-7).
"""
return self.day_abbreviations[day]
def month_name(self, month: int) -> str:
"""Returns the month name for a specified month of the year.
:param month: the ``int`` month of the year (1-12).
"""
return self.month_names[month]
def month_abbreviation(self, month: int) -> str:
"""Returns the month abbreviation for a specified month of the year.
:param month: the ``int`` month of the year (1-12).
"""
return self.month_abbreviations[month]
def month_number(self, name: str) -> Optional[int]:
"""Returns the month number for a month specified by name or abbreviation.
:param name: the month name or abbreviation.
"""
if self._month_name_to_ordinal is None:
self._month_name_to_ordinal = self._name_to_ordinal(self.month_names)
self._month_name_to_ordinal.update(
self._name_to_ordinal(self.month_abbreviations)
)
return self._month_name_to_ordinal.get(name)
def year_full(self, year: int) -> str:
"""Returns the year for specific locale if available
:param year: the ``int`` year (4-digit)
"""
return f"{year:04d}"
def year_abbreviation(self, year: int) -> str:
"""Returns the year for specific locale if available
:param year: the ``int`` year (4-digit)
"""
return f"{year:04d}"[2:]
def meridian(self, hour: int, token: Any) -> Optional[str]:
"""Returns the meridian indicator for a specified hour and format token.
:param hour: the ``int`` hour of the day.
:param token: the format token.
"""
if token == "a":
return self.meridians["am"] if hour < 12 else self.meridians["pm"]
if token == "A":
return self.meridians["AM"] if hour < 12 else self.meridians["PM"]
return None
def ordinal_number(self, n: int) -> str:
"""Returns the ordinal format of a given integer
:param n: an integer
"""
return self._ordinal_number(n)
def _ordinal_number(self, n: int) -> str:
return f"{n}"
def _name_to_ordinal(self, lst: Sequence[str]) -> Dict[str, int]:
return {elem.lower(): i for i, elem in enumerate(lst[1:], 1)}
def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
# TODO: remove cast
return cast(str, self.timeframes[timeframe]).format(trunc(abs(delta)))
def _format_relative(
self,
humanized: str,
timeframe: TimeFrameLiteral,
delta: Union[float, int],
) -> str:
if timeframe == "now":
return humanized
direction = self.past if delta < 0 else self.future
return direction.format(humanized)
class EnglishLocale(Locale):
names = [
"en",
"en-us",
"en-gb",
"en-au",
"en-be",
"en-jp",
"en-za",
"en-ca",
"en-ph",
]
past = "{0} ago"
future = "in {0}"
and_word = "and"
timeframes = {
"now": "just now",
"second": "a second",
"seconds": "{0} seconds",
"minute": "a minute",
"minutes": "{0} minutes",
"hour": "an hour",
"hours": "{0} hours",
"day": "a day",
"days": "{0} days",
"week": "a week",
"weeks": "{0} weeks",
"month": "a month",
"months": "{0} months",
"quarter": "a quarter",
"quarters": "{0} quarters",
"year": "a year",
"years": "{0} years",
}
meridians = {"am": "am", "pm": "pm", "AM": "AM", "PM": "PM"}
month_names = [
"",
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
]
month_abbreviations = [
"",
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
]
day_names = [
"",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday",
]
day_abbreviations = ["", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
ordinal_day_re = r"((?P<value>[2-3]?1(?=st)|[2-3]?2(?=nd)|[2-3]?3(?=rd)|[1-3]?[04-9](?=th)|1[1-3](?=th))(st|nd|rd|th))"
def _ordinal_number(self, n: int) -> str:
if n % 100 not in (11, 12, 13):
remainder = abs(n) % 10
if remainder == 1:
return f"{n}st"
elif remainder == 2:
return f"{n}nd"
elif remainder == 3:
return f"{n}rd"
return f"{n}th"
def describe(
self,
timeframe: TimeFrameLiteral,
delta: Union[int, float] = 0,
only_distance: bool = False,
) -> str:
"""Describes a delta within a timeframe in plain language.
:param timeframe: a string representing a timeframe.
:param delta: a quantity representing a delta in a timeframe.
:param only_distance: return only distance eg: "11 seconds" without "in" or "ago" keywords
"""
humanized = super().describe(timeframe, delta, only_distance)
if only_distance and timeframe == "now":
humanized = "instantly"
return humanized
class ItalianLocale(Locale):
names = ["it", "it-it"]
past = "{0} fa"
future = "tra {0}"
and_word = "e"
timeframes = {
"now": "adesso",
"second": "un secondo",
"seconds": "{0} qualche secondo",
"minute": "un minuto",
"minutes": "{0} minuti",
"hour": "un'ora",
"hours": "{0} ore",
"day": "un giorno",
"days": "{0} giorni",
"week": "una settimana",
"weeks": "{0} settimane",
"month": "un mese",
"months": "{0} mesi",
"year": "un anno",
"years": "{0} anni",
}
month_names = [
"",
"gennaio",
"febbraio",
"marzo",
"aprile",
"maggio",
"giugno",
"luglio",
"agosto",
"settembre",
"ottobre",
"novembre",
"dicembre",
]
month_abbreviations = [
"",
"gen",
"feb",
"mar",
"apr",
"mag",
"giu",
"lug",
"ago",
"set",
"ott",
"nov",
"dic",
]
day_names = [
"",
"lunedì",
"martedì",
"mercoledì",
"giovedì",
"venerdì",
"sabato",
"domenica",
]
day_abbreviations = ["", "lun", "mar", "mer", "gio", "ven", "sab", "dom"]
ordinal_day_re = r"((?P<value>[1-3]?[0-9](?=[ºª]))[ºª])"
def _ordinal_number(self, n: int) -> str:
return f"{n}º"
class SpanishLocale(Locale):
names = ["es", "es-es"]
past = "hace {0}"
future = "en {0}"
and_word = "y"
timeframes = {
"now": "ahora",
"second": "un segundo",
"seconds": "{0} segundos",
"minute": "un minuto",
"minutes": "{0} minutos",
"hour": "una hora",
"hours": "{0} horas",
"day": "un día",
"days": "{0} días",
"week": "una semana",
"weeks": "{0} semanas",
"month": "un mes",
"months": "{0} meses",
"year": "un año",
"years": "{0} años",
}
meridians = {"am": "am", "pm": "pm", "AM": "AM", "PM": "PM"}
month_names = [
"",
"enero",
"febrero",
"marzo",
"abril",
"mayo",
"junio",
"julio",
"agosto",
"septiembre",
"octubre",
"noviembre",
"diciembre",
]
month_abbreviations = [
"",
"ene",
"feb",
"mar",
"abr",
"may",
"jun",
"jul",
"ago",
"sep",
"oct",
"nov",
"dic",
]
day_names = [
"",
"lunes",
"martes",
"miércoles",
"jueves",
"viernes",
"sábado",
"domingo",
]
day_abbreviations = ["", "lun", "mar", "mie", "jue", "vie", "sab", "dom"]
ordinal_day_re = r"((?P<value>[1-3]?[0-9](?=[ºª]))[ºª])"
def _ordinal_number(self, n: int) -> str:
return f"{n}º"
class FrenchBaseLocale(Locale):
past = "il y a {0}"
future = "dans {0}"
and_word = "et"
timeframes = {
"now": "maintenant",
"second": "une seconde",
"seconds": "{0} secondes",
"minute": "une minute",
"minutes": "{0} minutes",
"hour": "une heure",
"hours": "{0} heures",
"day": "un jour",
"days": "{0} jours",
"week": "une semaine",
"weeks": "{0} semaines",
"month": "un mois",
"months": "{0} mois",
"year": "un an",
"years": "{0} ans",
}
month_names = [
"",
"janvier",
"février",
"mars",
"avril",
"mai",
"juin",
"juillet",
"août",
"septembre",
"octobre",
"novembre",
"décembre",
]
day_names = [
"",
"lundi",
"mardi",
"mercredi",
"jeudi",
"vendredi",
"samedi",
"dimanche",
]
day_abbreviations = ["", "lun", "mar", "mer", "jeu", "ven", "sam", "dim"]
ordinal_day_re = (
r"((?P<value>\b1(?=er\b)|[1-3]?[02-9](?=e\b)|[1-3]1(?=e\b))(er|e)\b)"
)
def _ordinal_number(self, n: int) -> str:
if abs(n) == 1:
return f"{n}er"
return f"{n}e"
class FrenchLocale(FrenchBaseLocale, Locale):
names = ["fr", "fr-fr"]
month_abbreviations = [
"",
"janv",
"févr",
"mars",
"avr",
"mai",
"juin",
"juil",
"août",
"sept",
"oct",
"nov",
"déc",
]
class FrenchCanadianLocale(FrenchBaseLocale, Locale):
names = ["fr-ca"]
month_abbreviations = [
"",
"janv",
"févr",
"mars",
"avr",
"mai",
"juin",
"juill",
"août",
"sept",
"oct",
"nov",
"déc",
]
class GreekLocale(Locale):
names = ["el", "el-gr"]
past = "πριν από {0}"
future = "σε {0}"
and_word = "και"
timeframes = {
"now": "τώρα",
"second": "ένα δευτερόλεπτο",
"seconds": "{0} δευτερόλεπτα",
"minute": "ένα λεπτό",
"minutes": "{0} λεπτά",
"hour": "μία ώρα",
"hours": "{0} ώρες",
"day": "μία ημέρα",
"days": "{0} ημέρες",
"week": "μία εβδομάδα",
"weeks": "{0} εβδομάδες",
"month": "ένα μήνα",
"months": "{0} μήνες",
"year": "ένα χρόνο",
"years": "{0} χρόνια",
}
month_names = [
"",
"Ιανουαρίου",
"Φεβρουαρίου",
"Μαρτίου",
"Απριλίου",
"Μαΐου",
"Ιουνίου",
"Ιουλίου",
"Αυγούστου",
"Σεπτεμβρίου",
"Οκτωβρίου",
"Νοεμβρίου",
"Δεκεμβρίου",
]
month_abbreviations = [
"",
"Ιαν",
"Φεβ",
"Μαρ",
"Απρ",
"Μαΐ",
"Ιον",
"Ιολ",
"Αυγ",
"Σεπ",
"Οκτ",
"Νοε",
"Δεκ",
]
day_names = [
"",
"Δευτέρα",
"Τρίτη",
"Τετάρτη",
"Πέμπτη",
"Παρασκευή",
"Σάββατο",
"Κυριακή",
]
day_abbreviations = ["", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ", "Κυρ"]
class JapaneseLocale(Locale):
names = ["ja", "ja-jp"]
past = "{0}前"
future = "{0}後"
and_word = ""
timeframes = {
"now": "現在",
"second": "1秒",
"seconds": "{0}秒",
"minute": "1分",
"minutes": "{0}分",
"hour": "1時間",
"hours": "{0}時間",
"day": "1日",
"days": "{0}日",
"week": "1週間",
"weeks": "{0}週間",
"month": "1ヶ月",
"months": "{0}ヶ月",
"year": "1年",
"years": "{0}年",
}
month_names = [
"",
"1月",
"2月",
"3月",
"4月",
"5月",
"6月",
"7月",
"8月",
"9月",
"10月",
"11月",
"12月",
]
month_abbreviations = [
"",
" 1",
" 2",
" 3",
" 4",
" 5",
" 6",
" 7",
" 8",
" 9",
"10",
"11",
"12",
]
day_names = [
"",
"月曜日",
"火曜日",
"水曜日",
"木曜日",
"金曜日",
"土曜日",
"日曜日",
]
day_abbreviations = ["", "月", "火", "水", "木", "金", "土", "日"]
class SwedishLocale(Locale):
names = ["sv", "sv-se"]
past = "för {0} sen"
future = "om {0}"
and_word = "och"
timeframes = {
"now": "just nu",
"second": "en sekund",
"seconds": "{0} sekunder",
"minute": "en minut",
"minutes": "{0} minuter",
"hour": "en timme",
"hours": "{0} timmar",
"day": "en dag",
"days": "{0} dagar",
"week": "en vecka",
"weeks": "{0} veckor",
"month": "en månad",
"months": "{0} månader",
"year": "ett år",
"years": "{0} år",
}
month_names = [
"",
"januari",
"februari",
"mars",
"april",
"maj",
"juni",
"juli",
"augusti",
"september",
"oktober",
"november",
"december",
]
month_abbreviations = [
"",
"jan",
"feb",
"mar",
"apr",
"maj",
"jun",
"jul",
"aug",
"sep",
"okt",
"nov",
"dec",
]
day_names = [
"",
"måndag",
"tisdag",
"onsdag",
"torsdag",
"fredag",
"lördag",
"söndag",
]
day_abbreviations = ["", "mån", "tis", "ons", "tor", "fre", "lör", "sön"]
class FinnishLocale(Locale):
names = ["fi", "fi-fi"]
# The finnish grammar is very complex, and its hard to convert
# 1-to-1 to something like English.
past = "{0} sitten"
future = "{0} kuluttua"
timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
"now": "juuri nyt",
"second": {"past": "sekunti", "future": "sekunnin"},
"seconds": {"past": "{0} sekuntia", "future": "{0} sekunnin"},
"minute": {"past": "minuutti", "future": "minuutin"},
"minutes": {"past": "{0} minuuttia", "future": "{0} minuutin"},
"hour": {"past": "tunti", "future": "tunnin"},
"hours": {"past": "{0} tuntia", "future": "{0} tunnin"},
"day": {"past": "päivä", "future": "päivän"},
"days": {"past": "{0} päivää", "future": "{0} päivän"},
"week": {"past": "viikko", "future": "viikon"},
"weeks": {"past": "{0} viikkoa", "future": "{0} viikon"},
"month": {"past": "kuukausi", "future": "kuukauden"},
"months": {"past": "{0} kuukautta", "future": "{0} kuukauden"},
"year": {"past": "vuosi", "future": "vuoden"},
"years": {"past": "{0} vuotta", "future": "{0} vuoden"},
}
# Months and days are lowercase in Finnish
month_names = [
"",
"tammikuu",
"helmikuu",
"maaliskuu",
"huhtikuu",
"toukokuu",
"kesäkuu",
"heinäkuu",
"elokuu",
"syyskuu",
"lokakuu",
"marraskuu",
"joulukuu",
]
month_abbreviations = [
"",
"tammi",
"helmi",
"maalis",
"huhti",
"touko",
"kesä",
"heinä",
"elo",
"syys",
"loka",
"marras",
"joulu",
]
day_names = [
"",
"maanantai",
"tiistai",
"keskiviikko",
"torstai",
"perjantai",
"lauantai",
"sunnuntai",
]
day_abbreviations = ["", "ma", "ti", "ke", "to", "pe", "la", "su"]
def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
form = self.timeframes[timeframe]
if isinstance(form, Mapping):
if delta < 0:
form = form["past"]
else:
form = form["future"]
return form.format(abs(delta))
def _ordinal_number(self, n: int) -> str:
return f"{n}."
class ChineseCNLocale(Locale):
names = ["zh", "zh-cn"]
past = "{0}前"
future = "{0}后"
timeframes = {
"now": "刚才",
"second": "1秒",
"seconds": "{0}秒",
"minute": "1分钟",
"minutes": "{0}分钟",
"hour": "1小时",
"hours": "{0}小时",
"day": "1天",
"days": "{0}天",
"week": "1周",
"weeks": "{0}周",
"month": "1个月",
"months": "{0}个月",
"year": "1年",
"years": "{0}年",
}
month_names = [
"",
"一月",
"二月",
"三月",
"四月",
"五月",
"六月",
"七月",
"八月",
"九月",
"十月",
"十一月",
"十二月",
]
month_abbreviations = [
"",
" 1",
" 2",
" 3",
" 4",
" 5",
" 6",
" 7",
" 8",
" 9",
"10",
"11",
"12",
]
day_names = [
"",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
"星期日",
]
day_abbreviations = ["", "一", "二", "三", "四", "五", "六", "日"]
class ChineseTWLocale(Locale):
names = ["zh-tw"]
past = "{0}前"
future = "{0}後"
and_word = "和"
timeframes = {
"now": "剛才",
"second": "1秒",
"seconds": "{0}秒",
"minute": "1分鐘",
"minutes": "{0}分鐘",
"hour": "1小時",
"hours": "{0}小時",
"day": "1天",
"days": "{0}天",
"week": "1週",
"weeks": "{0}週",
"month": "1個月",
"months": "{0}個月",
"year": "1年",
"years": "{0}年",
}
month_names = [
"",
"1月",
"2月",
"3月",
"4月",
"5月",
"6月",
"7月",
"8月",
"9月",
"10月",
"11月",
"12月",
]
month_abbreviations = [
"",
" 1",
" 2",
" 3",
" 4",
" 5",
" 6",
" 7",
" 8",
" 9",
"10",
"11",
"12",
]
day_names = ["", "週一", "週二", "週三", "週四", "週五", "週六", "週日"]
day_abbreviations = ["", "一", "二", "三", "四", "五", "六", "日"]
class HongKongLocale(Locale):
names = ["zh-hk"]
past = "{0}前"
future = "{0}後"
timeframes = {
"now": "剛才",
"second": "1秒",
"seconds": "{0}秒",
"minute": "1分鐘",
"minutes": "{0}分鐘",
"hour": "1小時",
"hours": "{0}小時",
"day": "1天",
"days": "{0}天",
"week": "1星期",
"weeks": "{0}星期",
"month": "1個月",
"months": "{0}個月",
"year": "1年",
"years": "{0}年",
}
month_names = [
"",
"1月",
"2月",
"3月",
"4月",
"5月",
"6月",
"7月",
"8月",
"9月",
"10月",
"11月",
"12月",
]
month_abbreviations = [
"",
" 1",
" 2",
" 3",
" 4",
" 5",
" 6",
" 7",
" 8",
" 9",
"10",
"11",
"12",
]
day_names = [
"",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
"星期日",
]
day_abbreviations = ["", "一", "二", "三", "四", "五", "六", "日"]
class KoreanLocale(Locale):
names = ["ko", "ko-kr"]
past = "{0} 전"
future = "{0} 후"
timeframes = {
"now": "지금",
"second": "1초",
"seconds": "{0}초",
"minute": "1분",
"minutes": "{0}분",
"hour": "한시간",
"hours": "{0}시간",
"day": "하루",
"days": "{0}일",
"week": "1주",
"weeks": "{0}주",
"month": "한달",
"months": "{0}개월",
"year": "1년",
"years": "{0}년",
}
special_dayframes = {
-2: "그제",
-1: "어제",
1: "내일",
2: "모레",
3: "글피",
4: "그글피",
}
special_yearframes = {-2: "재작년", -1: "작년", 1: "내년", 2: "내후년"}
month_names = [
"",
"1월",
"2월",
"3월",
"4월",
"5월",
"6월",
"7월",
"8월",
"9월",
"10월",
"11월",
"12월",
]
month_abbreviations = [
"",
" 1",
" 2",
" 3",
" 4",
" 5",
" 6",
" 7",
" 8",
" 9",
"10",
"11",
"12",
]
day_names = [
"",
"월요일",
"화요일",
"수요일",
"목요일",
"금요일",
"토요일",
"일요일",
]
day_abbreviations = ["", "월", "화", "수", "목", "금", "토", "일"]
def _ordinal_number(self, n: int) -> str:
ordinals = [
"0",
"첫",
"두",
"세",
"네",
"다섯",
"여섯",
"일곱",
"여덟",
"아홉",
"열",
]
if n < len(ordinals):
return f"{ordinals[n]}번째"
return f"{n}번째"
def _format_relative(
self,
humanized: str,
timeframe: TimeFrameLiteral,
delta: Union[float, int],
) -> str:
if timeframe in ("day", "days"):
special = self.special_dayframes.get(int(delta))
if special:
return special
elif timeframe in ("year", "years"):
special = self.special_yearframes.get(int(delta))
if special:
return special
return super()._format_relative(humanized, timeframe, delta)
# derived locale types & implementations.
class DutchLocale(Locale):
names = ["nl", "nl-nl"]
past = "{0} geleden"
future = "over {0}"
timeframes = {
"now": "nu",
"second": "een seconde",
"seconds": "{0} seconden",
"minute": "een minuut",
"minutes": "{0} minuten",
"hour": "een uur",
"hours": "{0} uur",
"day": "een dag",
"days": "{0} dagen",
"week": "een week",
"weeks": "{0} weken",
"month": "een maand",
"months": "{0} maanden",
"year": "een jaar",
"years": "{0} jaar",
}
# In Dutch names of months and days are not starting with a capital letter
# like in the English language.
month_names = [
"",
"januari",
"februari",
"maart",
"april",
"mei",
"juni",
"juli",
"augustus",
"september",
"oktober",
"november",
"december",
]
month_abbreviations = [
"",
"jan",
"feb",
"mrt",
"apr",
"mei",
"jun",
"jul",
"aug",
"sep",
"okt",
"nov",
"dec",
]
day_names = [
"",
"maandag",
"dinsdag",
"woensdag",
"donderdag",
"vrijdag",
"zaterdag",
"zondag",
]
day_abbreviations = ["", "ma", "di", "wo", "do", "vr", "za", "zo"]
class SlavicBaseLocale(Locale):
timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]]
def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -> str:
form = self.timeframes[timeframe]
delta = abs(delta)
if isinstance(form, Mapping):
if delta % 10 == 1 and delta % 100 != 11:
form = form["singular"]
elif 2 <= delta % 10 <= 4 and (delta % 100 < 10 or delta % 100 >= 20):
form = form["dual"]
else:
form = form["plural"]
return form.format(delta)
class BelarusianLocale(SlavicBaseLocale):
names = ["be", "be-by"]
past = "{0} таму"
future = "праз {0}"
timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
"now": "зараз",
"second": "секунду",
"seconds": "{0} некалькі секунд",
"minute": "хвіліну",
"minutes": {
"singular": "{0} хвіліну",
"dual": "{0} хвіліны",
"plural": "{0} хвілін",
},
"hour": "гадзіну",
"hours": {
"singular": "{0} гадзіну",
"dual": "{0} гадзіны",
"plural": "{0} гадзін",
},
"day": "дзень",
"days": {"singular": "{0} дзень", "dual": "{0} дні", "plural": "{0} дзён"},
"month": "месяц",
"months": {
"singular": "{0} месяц",
"dual": "{0} месяцы",
"plural": "{0} месяцаў",
},
"year": "год",
"years": {"singular": "{0} год", "dual": "{0} гады", "plural": "{0} гадоў"},
}
month_names = [
"",
"студзеня",
"лютага",
"сакавіка",
"красавіка",
"траўня",
"чэрвеня",
"ліпеня",
"жніўня",
"верасня",
"кастрычніка",
"лістапада",
"снежня",
]
month_abbreviations = [
"",
"студ",
"лют",
"сак",
"крас",
"трав",
"чэрв",
"ліп",
"жнів",
"вер",
"каст",
"ліст",
"снеж",
]
day_names = [
"",
"панядзелак",
"аўторак",
"серада",
"чацвер",
"пятніца",
"субота",
"нядзеля",
]
day_abbreviations = ["", "пн", "ат", "ср", "чц", "пт", "сб", "нд"]
class PolishLocale(SlavicBaseLocale):
names = ["pl", "pl-pl"]
past = "{0} temu"
future = "za {0}"
# The nouns should be in genitive case (Polish: "dopełniacz")
# in order to correctly form `past` & `future` expressions.
timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
"now": "teraz",
"second": "sekundę",
"seconds": {
"singular": "{0} sekund",
"dual": "{0} sekundy",
"plural": "{0} sekund",
},
"minute": "minutę",
"minutes": {
"singular": "{0} minut",
"dual": "{0} minuty",
"plural": "{0} minut",
},
"hour": "godzinę",
"hours": {
"singular": "{0} godzin",
"dual": "{0} godziny",
"plural": "{0} godzin",
},
"day": "dzień",
"days": "{0} dni",
"week": "tydzień",
"weeks": {
"singular": "{0} tygodni",
"dual": "{0} tygodnie",
"plural": "{0} tygodni",
},
"month": "miesiąc",
"months": {
"singular": "{0} miesięcy",
"dual": "{0} miesiące",
"plural": "{0} miesięcy",
},
"year": "rok",
"years": {"singular": "{0} lat", "dual": "{0} lata", "plural": "{0} lat"},
}
month_names = [
"",
"styczeń",
"luty",
"marzec",
"kwiecień",
"maj",
"czerwiec",
"lipiec",
"sierpień",
"wrzesień",
"październik",
"listopad",
"grudzień",
]
month_abbreviations = [
"",
"sty",
"lut",
"mar",
"kwi",
"maj",
"cze",
"lip",
"sie",
"wrz",
"paź",
"lis",
"gru",
]
day_names = [
"",
"poniedziałek",
"wtorek",
"środa",
"czwartek",
"piątek",
"sobota",
"niedziela",
]
day_abbreviations = ["", "Pn", "Wt", "Śr", "Czw", "Pt", "So", "Nd"]
class RussianLocale(SlavicBaseLocale):
names = ["ru", "ru-ru"]
past = "{0} назад"
future = "через {0}"
timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
"now": "сейчас",
"second": "секунда",
"seconds": {
"singular": "{0} секунду",
"dual": "{0} секунды",
"plural": "{0} секунд",
},
"minute": "минуту",
"minutes": {
"singular": "{0} минуту",
"dual": "{0} минуты",
"plural": "{0} минут",
},
"hour": "час",
"hours": {"singular": "{0} час", "dual": "{0} часа", "plural": "{0} часов"},
"day": "день",
"days": {"singular": "{0} день", "dual": "{0} дня", "plural": "{0} дней"},
"week": "неделю",
"weeks": {
"singular": "{0} неделю",
"dual": "{0} недели",
"plural": "{0} недель",
},
"month": "месяц",
"months": {
"singular": "{0} месяц",
"dual": "{0} месяца",
"plural": "{0} месяцев",
},
"quarter": "квартал",
"quarters": {
"singular": "{0} квартал",
"dual": "{0} квартала",
"plural": "{0} кварталов",
},
"year": "год",
"years": {"singular": "{0} год", "dual": "{0} года", "plural": "{0} лет"},
}
month_names = [
"",
"января",
"февраля",
"марта",
"апреля",
"мая",
"июня",
"июля",
"августа",
"сентября",
"октября",
"ноября",
"декабря",
]
month_abbreviations = [
"",
"янв",
"фев",
"мар",
"апр",
"май",
"июн",
"июл",
"авг",
"сен",
"окт",
"ноя",
"дек",
]
day_names = [
"",
"понедельник",
"вторник",
"среда",
"четверг",
"пятница",
"суббота",
"воскресенье",
]
day_abbreviations = ["", "пн", "вт", "ср", "чт", "пт", "сб", "вс"]
class AfrikaansLocale(Locale):
names = ["af", "af-nl"]
past = "{0} gelede"
future = "in {0}"
timeframes = {
"now": "nou",
"second": "n sekonde",
"seconds": "{0} sekondes",
"minute": "minuut",
"minutes": "{0} minute",
"hour": "uur",
"hours": "{0} ure",
"day": "een dag",
"days": "{0} dae",
"week": "een week",
"weeks": "{0} weke",
"month": "een maand",
"months": "{0} maande",
"year": "een jaar",
"years": "{0} jaar",
}
month_names = [
"",
"Januarie",
"Februarie",
"Maart",
"April",
"Mei",
"Junie",
"Julie",
"Augustus",
"September",
"Oktober",
"November",
"Desember",
]
month_abbreviations = [
"",
"Jan",
"Feb",
"Mrt",
"Apr",
"Mei",
"Jun",
"Jul",
"Aug",
"Sep",
"Okt",
"Nov",
"Des",
]
day_names = [
"",
"Maandag",
"Dinsdag",
"Woensdag",
"Donderdag",
"Vrydag",
"Saterdag",
"Sondag",
]
day_abbreviations = ["", "Ma", "Di", "Wo", "Do", "Vr", "Za", "So"]
class BulgarianLocale(SlavicBaseLocale):
names = ["bg", "bg-bg"]
past = "{0} назад"
future = "напред {0}"
timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
"now": "сега",
"second": "секунда",
"seconds": "{0} няколко секунди",
"minute": "минута",
"minutes": {
"singular": "{0} минута",
"dual": "{0} минути",
"plural": "{0} минути",
},
"hour": "час",
"hours": {"singular": "{0} час", "dual": "{0} часа", "plural": "{0} часа"},
"day": "ден",
"days": {"singular": "{0} ден", "dual": "{0} дни", "plural": "{0} дни"},
"month": "месец",
"months": {
"singular": "{0} месец",
"dual": "{0} месеца",
"plural": "{0} месеца",
},
"year": "година",
"years": {
"singular": "{0} година",
"dual": "{0} години",
"plural": "{0} години",
},
}
month_names = [
"",
"януари",
"февруари",
"март",
"април",
"май",
"юни",
"юли",
"август",
"септември",
"октомври",
"ноември",
"декември",
]
month_abbreviations = [
"",
"ян",
"февр",
"март",
"апр",
"май",
"юни",
"юли",
"авг",
"септ",
"окт",
"ноем",
"дек",
]
day_names = [
"",
"понеделник",
"вторник",
"сряда",
"четвъртък",
"петък",
"събота",
"неделя",
]
day_abbreviations = ["", "пон", "вт", "ср", "четв", "пет", "съб", "нед"]
class UkrainianLocale(SlavicBaseLocale):
names = ["ua", "uk", "uk-ua"]
past = "{0} тому"
future = "за {0}"
timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
"now": "зараз",
"second": "секунда",
"seconds": "{0} кілька секунд",
"minute": "хвилину",
"minutes": {
"singular": "{0} хвилину",
"dual": "{0} хвилини",
"plural": "{0} хвилин",
},
"hour": "годину",
"hours": {
"singular": "{0} годину",
"dual": "{0} години",
"plural": "{0} годин",
},
"day": "день",
"days": {"singular": "{0} день", "dual": "{0} дні", "plural": "{0} днів"},
"month": "місяць",
"months": {
"singular": "{0} місяць",
"dual": "{0} місяці",
"plural": "{0} місяців",
},
"year": "рік",
"years": {"singular": "{0} рік", "dual": "{0} роки", "plural": "{0} років"},
}
month_names = [
"",
"січня",
"лютого",
"березня",
"квітня",
"травня",
"червня",
"липня",
"серпня",
"вересня",
"жовтня",
"листопада",
"грудня",
]
month_abbreviations = [
"",
"січ",
"лют",
"бер",
"квіт",
"трав",
"черв",
"лип",
"серп",
"вер",
"жовт",
"лист",
"груд",
]
day_names = [
"",
"понеділок",
"вівторок",
"середа",
"четвер",
"п’ятниця",
"субота",
"неділя",
]
day_abbreviations = ["", "пн", "вт", "ср", "чт", "пт", "сб", "нд"]
class MacedonianLocale(SlavicBaseLocale):
names = ["mk", "mk-mk"]
past = "пред {0}"
future = "за {0}"
timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
"now": "сега",
"second": "една секунда",
"seconds": {
"singular": "{0} секунда",
"dual": "{0} секунди",
"plural": "{0} секунди",
},
"minute": "една минута",
"minutes": {
"singular": "{0} минута",
"dual": "{0} минути",
"plural": "{0} минути",
},
"hour": "еден саат",
"hours": {"singular": "{0} саат", "dual": "{0} саати", "plural": "{0} саати"},
"day": "еден ден",
"days": {"singular": "{0} ден", "dual": "{0} дена", "plural": "{0} дена"},
"week": "една недела",
"weeks": {
"singular": "{0} недела",
"dual": "{0} недели",
"plural": "{0} недели",
},
"month": "еден месец",
"months": {
"singular": "{0} месец",
"dual": "{0} месеци",
"plural": "{0} месеци",
},
"year": "една година",
"years": {
"singular": "{0} година",
"dual": "{0} години",
"plural": "{0} години",
},
}
meridians = {"am": "дп", "pm": "пп", "AM": "претпладне", "PM": "попладне"}
month_names = [
"",
"Јануари",
"Февруари",
"Март",
"Април",
"Мај",
"Јуни",
"Јули",
"Август",
"Септември",
"Октомври",
"Ноември",
"Декември",
]
month_abbreviations = [
"",
"Јан",
"Фев",
"Мар",
"Апр",
"Мај",
"Јун",
"Јул",
"Авг",
"Септ",
"Окт",
"Ноем",
"Декем",
]
day_names = [
"",
"Понеделник",
"Вторник",
"Среда",
"Четврток",
"Петок",
"Сабота",
"Недела",
]
day_abbreviations = [
"",
"Пон",
"Вт",
"Сре",
"Чет",
"Пет",
"Саб",
"Нед",
]
class MacedonianLatinLocale(SlavicBaseLocale):
names = ["mk-latn", "mk-mk-latn"]
past = "pred {0}"
future = "za {0}"
timeframes: ClassVar[Mapping[TimeFrameLiteral, Union[str, Mapping[str, str]]]] = {
"now": "sega",
"second": "edna sekunda",
"seconds": {
"singular": "{0} sekunda",
"dual": "{0} sekundi",
"plural": "{0} sekundi",
},
"minute": "edna minuta",
"minutes": {
"singular": "{0} minuta",
"dual": "{0} minuti",
"plural": "{0} minuti",
},
"hour": "eden saat",
"hours": {"singular": "{0} saat", "dual": "{0} saati", "plural": "{0} saati"},
"day": "eden den",
"days": {"singular": "{0} den", "dual": "{0} dena", "plural": "{0} dena"},
"week": "edna nedela",
"weeks"
gitextract_jsvx0o33/ ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ ├── documentation.md │ │ └── feature_request.md │ ├── dependabot.yml │ ├── pull_request_template.md │ └── workflows/ │ ├── continuous_integration.yml │ └── release.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .readthedocs.yaml ├── CHANGELOG.rst ├── LICENSE ├── Makefile ├── README.rst ├── arrow/ │ ├── __init__.py │ ├── _version.py │ ├── api.py │ ├── arrow.py │ ├── constants.py │ ├── factory.py │ ├── formatter.py │ ├── locales.py │ ├── parser.py │ ├── py.typed │ └── util.py ├── docs/ │ ├── Makefile │ ├── api-guide.rst │ ├── conf.py │ ├── getting-started.rst │ ├── guide.rst │ ├── index.rst │ ├── make.bat │ └── releases.rst ├── pyproject.toml ├── requirements/ │ ├── requirements-docs.txt │ ├── requirements-tests.txt │ └── requirements.txt ├── setup.cfg ├── tests/ │ ├── __init__.py │ ├── conftest.py │ ├── test_api.py │ ├── test_arrow.py │ ├── test_factory.py │ ├── test_formatter.py │ ├── test_locales.py │ ├── test_parser.py │ ├── test_util.py │ └── utils.py └── tox.ini
SYMBOL INDEX (1115 symbols across 16 files)
FILE: arrow/api.py
function get (line 24) | def get(
function get (line 33) | def get(
function get (line 42) | def get(
function get (line 62) | def get(
function get (line 73) | def get(
function get (line 83) | def get(*args: Any, **kwargs: Any) -> Arrow:
function utcnow (line 92) | def utcnow() -> Arrow:
function now (line 101) | def now(tz: Optional[TZ_EXPR] = None) -> Arrow:
function factory (line 110) | def factory(type: Type[Arrow]) -> ArrowFactory:
FILE: arrow/arrow.py
class Arrow (line 78) | class Arrow:
method __init__ (line 148) | def __init__(
method now (line 182) | def now(cls, tzinfo: Optional[dt_tzinfo] = None) -> "Arrow":
method utcnow (line 213) | def utcnow(cls) -> "Arrow":
method fromtimestamp (line 239) | def fromtimestamp(
method utcfromtimestamp (line 276) | def utcfromtimestamp(cls, timestamp: Union[int, float, str]) -> "Arrow":
method fromdatetime (line 302) | def fromdatetime(cls, dt: dt_datetime, tzinfo: Optional[TZ_EXPR] = Non...
method fromdate (line 338) | def fromdate(cls, date: dt_date, tzinfo: Optional[TZ_EXPR] = None) -> ...
method strptime (line 353) | def strptime(
method fromordinal (line 388) | def fromordinal(cls, ordinal: int) -> "Arrow":
method range (line 418) | def range(
method span (line 504) | def span(
method floor (line 598) | def floor(self, frame: _T_FRAMES, **kwargs: Any) -> "Arrow":
method ceil (line 620) | def ceil(self, frame: _T_FRAMES, **kwargs: Any) -> "Arrow":
method span_range (line 643) | def span_range(
method interval (line 725) | def interval(
method __repr__ (line 796) | def __repr__(self) -> str:
method __str__ (line 799) | def __str__(self) -> str:
method __format__ (line 802) | def __format__(self, formatstr: str) -> str:
method __hash__ (line 808) | def __hash__(self) -> int:
method __getattr__ (line 813) | def __getattr__(self, name: str) -> Any:
method tzinfo (line 829) | def tzinfo(self) -> dt_tzinfo:
method datetime (line 844) | def datetime(self) -> dt_datetime:
method naive (line 858) | def naive(self) -> dt_datetime:
method timestamp (line 874) | def timestamp(self) -> float:
method int_timestamp (line 888) | def int_timestamp(self) -> int:
method float_timestamp (line 902) | def float_timestamp(self) -> float:
method fold (line 916) | def fold(self) -> int:
method ambiguous (line 922) | def ambiguous(self) -> bool:
method imaginary (line 931) | def imaginary(self) -> bool:
method clone (line 938) | def clone(self) -> "Arrow":
method replace (line 950) | def replace(self, **kwargs: Any) -> "Arrow":
method shift (line 996) | def shift(self, check_imaginary: bool = True, **kwargs: Any) -> "Arrow":
method to (line 1057) | def to(self, tz: TZ_EXPR) -> "Arrow":
method format (line 1105) | def format(
method humanize (line 1133) | def humanize(
method dehumanize (line 1346) | def dehumanize(self, input_string: str, locale: str = "en_us") -> "Arr...
method is_between (line 1487) | def is_between(
method date (line 1547) | def date(self) -> dt_date:
method time (line 1559) | def time(self) -> dt_time:
method timetz (line 1571) | def timetz(self) -> dt_time:
method astimezone (line 1584) | def astimezone(self, tz: Optional[dt_tzinfo]) -> dt_datetime:
method utcoffset (line 1600) | def utcoffset(self) -> Optional[timedelta]:
method dst (line 1613) | def dst(self) -> Optional[timedelta]:
method timetuple (line 1625) | def timetuple(self) -> struct_time:
method utctimetuple (line 1637) | def utctimetuple(self) -> struct_time:
method toordinal (line 1649) | def toordinal(self) -> int:
method weekday (line 1661) | def weekday(self) -> int:
method isoweekday (line 1673) | def isoweekday(self) -> int:
method isocalendar (line 1685) | def isocalendar(self) -> Tuple[int, int, int]:
method isoformat (line 1697) | def isoformat(self, sep: str = "T", timespec: str = "auto") -> str:
method ctime (line 1709) | def ctime(self) -> str:
method strftime (line 1721) | def strftime(self, format: str) -> str:
method for_json (line 1735) | def for_json(self) -> str:
method __add__ (line 1749) | def __add__(self, other: Any) -> "Arrow":
method __radd__ (line 1755) | def __radd__(self, other: Union[timedelta, relativedelta]) -> "Arrow":
method __sub__ (line 1759) | def __sub__(self, other: Union[timedelta, relativedelta]) -> "Arrow":
method __sub__ (line 1763) | def __sub__(self, other: Union[dt_datetime, "Arrow"]) -> timedelta:
method __sub__ (line 1766) | def __sub__(self, other: Any) -> Union[timedelta, "Arrow"]:
method __rsub__ (line 1778) | def __rsub__(self, other: Any) -> timedelta:
method __eq__ (line 1786) | def __eq__(self, other: Any) -> bool:
method __ne__ (line 1792) | def __ne__(self, other: Any) -> bool:
method __gt__ (line 1798) | def __gt__(self, other: Any) -> bool:
method __ge__ (line 1804) | def __ge__(self, other: Any) -> bool:
method __lt__ (line 1810) | def __lt__(self, other: Any) -> bool:
method __le__ (line 1816) | def __le__(self, other: Any) -> bool:
method _get_tzinfo (line 1824) | def _get_tzinfo(tz_expr: Optional[TZ_EXPR]) -> dt_tzinfo:
method _get_datetime (line 1837) | def _get_datetime(
method _get_frames (line 1852) | def _get_frames(cls, name: _T_FRAMES) -> Tuple[str, str, int]:
method _get_iteration_params (line 1885) | def _get_iteration_params(cls, end: Any, limit: Optional[int]) -> Tupl...
method _is_last_day_of_month (line 1899) | def _is_last_day_of_month(date: "Arrow") -> bool:
FILE: arrow/factory.py
class ArrowFactory (line 21) | class ArrowFactory:
method __init__ (line 31) | def __init__(self, type: Type[Arrow] = Arrow) -> None:
method get (line 35) | def get(
method get (line 44) | def get(
method get (line 64) | def get(
method get (line 75) | def get(
method get (line 85) | def get(self, *args: Any, **kwargs: Any) -> Arrow:
method utcnow (line 299) | def utcnow(self) -> Arrow:
method now (line 311) | def now(self, tz: Optional[TZ_EXPR] = None) -> Arrow:
FILE: arrow/formatter.py
class DateTimeFormatter (line 23) | class DateTimeFormatter:
method __init__ (line 34) | def __init__(self, locale: str = DEFAULT_LOCALE) -> None:
method format (line 37) | def format(cls, dt: datetime, fmt: str) -> str:
method _format_token (line 43) | def _format_token(self, dt: datetime, token: Optional[str]) -> Optiona...
FILE: arrow/locales.py
function get_locale (line 46) | def get_locale(name: str) -> "Locale":
function get_locale_by_class_name (line 63) | def get_locale_by_class_name(name: str) -> "Locale":
class Locale (line 78) | class Locale:
method __init_subclass__ (line 119) | def __init_subclass__(cls, **kwargs: Any) -> None:
method __init__ (line 126) | def __init__(self) -> None:
method describe (line 129) | def describe(
method describe_multi (line 148) | def describe_multi(
method day_name (line 181) | def day_name(self, day: int) -> str:
method day_abbreviation (line 190) | def day_abbreviation(self, day: int) -> str:
method month_name (line 199) | def month_name(self, month: int) -> str:
method month_abbreviation (line 208) | def month_abbreviation(self, month: int) -> str:
method month_number (line 217) | def month_number(self, name: str) -> Optional[int]:
method year_full (line 232) | def year_full(self, year: int) -> str:
method year_abbreviation (line 239) | def year_abbreviation(self, year: int) -> str:
method meridian (line 246) | def meridian(self, hour: int, token: Any) -> Optional[str]:
method ordinal_number (line 259) | def ordinal_number(self, n: int) -> str:
method _ordinal_number (line 266) | def _ordinal_number(self, n: int) -> str:
method _name_to_ordinal (line 269) | def _name_to_ordinal(self, lst: Sequence[str]) -> Dict[str, int]:
method _format_timeframe (line 272) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
method _format_relative (line 276) | def _format_relative(
class EnglishLocale (line 290) | class EnglishLocale(Locale):
method _ordinal_number (line 374) | def _ordinal_number(self, n: int) -> str:
method describe (line 385) | def describe(
class ItalianLocale (line 405) | class ItalianLocale(Locale):
method _ordinal_number (line 474) | def _ordinal_number(self, n: int) -> str:
class SpanishLocale (line 478) | class SpanishLocale(Locale):
method _ordinal_number (line 549) | def _ordinal_number(self, n: int) -> str:
class FrenchBaseLocale (line 553) | class FrenchBaseLocale(Locale):
method _ordinal_number (line 608) | def _ordinal_number(self, n: int) -> str:
class FrenchLocale (line 614) | class FrenchLocale(FrenchBaseLocale, Locale):
class FrenchCanadianLocale (line 634) | class FrenchCanadianLocale(FrenchBaseLocale, Locale):
class GreekLocale (line 654) | class GreekLocale(Locale):
class JapaneseLocale (line 723) | class JapaneseLocale(Locale):
class SwedishLocale (line 792) | class SwedishLocale(Locale):
class FinnishLocale (line 861) | class FinnishLocale(Locale):
method _format_timeframe (line 934) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
method _ordinal_number (line 945) | def _ordinal_number(self, n: int) -> str:
class ChineseCNLocale (line 949) | class ChineseCNLocale(Locale):
class ChineseTWLocale (line 1017) | class ChineseTWLocale(Locale):
class HongKongLocale (line 1077) | class HongKongLocale(Locale):
class KoreanLocale (line 1145) | class KoreanLocale(Locale):
method _ordinal_number (line 1223) | def _ordinal_number(self, n: int) -> str:
method _format_relative (line 1241) | def _format_relative(
class DutchLocale (line 1260) | class DutchLocale(Locale):
class SlavicBaseLocale (line 1330) | class SlavicBaseLocale(Locale):
method _format_timeframe (line 1333) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
class BelarusianLocale (line 1348) | class BelarusianLocale(SlavicBaseLocale):
class PolishLocale (line 1426) | class PolishLocale(SlavicBaseLocale):
class RussianLocale (line 1516) | class RussianLocale(SlavicBaseLocale):
class AfrikaansLocale (line 1606) | class AfrikaansLocale(Locale):
class BulgarianLocale (line 1674) | class BulgarianLocale(SlavicBaseLocale):
class UkrainianLocale (line 1752) | class UkrainianLocale(SlavicBaseLocale):
class MacedonianLocale (line 1830) | class MacedonianLocale(SlavicBaseLocale):
class MacedonianLatinLocale (line 1929) | class MacedonianLatinLocale(SlavicBaseLocale):
class GermanBaseLocale (line 2028) | class GermanBaseLocale(Locale):
method _ordinal_number (line 2108) | def _ordinal_number(self, n: int) -> str:
method describe (line 2111) | def describe(
class GermanLocale (line 2135) | class GermanLocale(GermanBaseLocale, Locale):
class SwissLocale (line 2139) | class SwissLocale(GermanBaseLocale, Locale):
class AustrianLocale (line 2143) | class AustrianLocale(GermanBaseLocale, Locale):
class NorwegianLocale (line 2163) | class NorwegianLocale(Locale):
method _ordinal_number (line 2230) | def _ordinal_number(self, n: int) -> str:
class NewNorwegianLocale (line 2234) | class NewNorwegianLocale(Locale):
method _ordinal_number (line 2301) | def _ordinal_number(self, n: int) -> str:
class PortugueseLocale (line 2305) | class PortugueseLocale(Locale):
class BrazilianPortugueseLocale (line 2374) | class BrazilianPortugueseLocale(PortugueseLocale):
class TagalogLocale (line 2380) | class TagalogLocale(Locale):
method _ordinal_number (line 2449) | def _ordinal_number(self, n: int) -> str:
class VietnameseLocale (line 2453) | class VietnameseLocale(Locale):
class TurkishLocale (line 2521) | class TurkishLocale(Locale):
class AzerbaijaniLocale (line 2592) | class AzerbaijaniLocale(Locale):
class ArabicLocale (line 2660) | class ArabicLocale(Locale):
method _format_timeframe (line 2746) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
class LevantArabicLocale (line 2760) | class LevantArabicLocale(ArabicLocale):
class AlgeriaTunisiaArabicLocale (line 2794) | class AlgeriaTunisiaArabicLocale(ArabicLocale):
class MauritaniaArabicLocale (line 2828) | class MauritaniaArabicLocale(ArabicLocale):
class MoroccoArabicLocale (line 2862) | class MoroccoArabicLocale(ArabicLocale):
class IcelandicLocale (line 2896) | class IcelandicLocale(Locale):
method _format_timeframe (line 2897) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
class DanishLocale (line 2981) | class DanishLocale(Locale):
method _ordinal_number (line 3049) | def _ordinal_number(self, n: int) -> str:
class MalayalamLocale (line 3053) | class MalayalamLocale(Locale):
class HindiLocale (line 3126) | class HindiLocale(Locale):
class CzechLocale (line 3194) | class CzechLocale(Locale):
method _format_timeframe (line 3296) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
class SlovakLocale (line 3324) | class SlovakLocale(Locale):
method _format_timeframe (line 3427) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
class FarsiLocale (line 3454) | class FarsiLocale(Locale):
class HebrewLocale (line 3540) | class HebrewLocale(Locale):
method _format_timeframe (line 3606) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
method describe_multi (line 3619) | def describe_multi(
class MarathiLocale (line 3650) | class MarathiLocale(Locale):
class CatalanLocale (line 3718) | class CatalanLocale(Locale):
class BasqueLocale (line 3794) | class BasqueLocale(Locale):
class HungarianLocale (line 3858) | class HungarianLocale(Locale):
method _format_timeframe (line 3927) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
class EsperantoLocale (line 3939) | class EsperantoLocale(Locale):
method _ordinal_number (line 4007) | def _ordinal_number(self, n: int) -> str:
class ThaiLocale (line 4011) | class ThaiLocale(Locale):
method year_full (line 4082) | def year_full(self, year: int) -> str:
method year_abbreviation (line 4087) | def year_abbreviation(self, year: int) -> str:
method _format_relative (line 4092) | def _format_relative(
class LaotianLocale (line 4111) | class LaotianLocale(Locale):
method year_full (line 4189) | def year_full(self, year: int) -> str:
method year_abbreviation (line 4194) | def year_abbreviation(self, year: int) -> str:
method _format_relative (line 4199) | def _format_relative(
class BengaliLocale (line 4218) | class BengaliLocale(Locale):
method _ordinal_number (line 4285) | def _ordinal_number(self, n: int) -> str:
class RomanshLocale (line 4299) | class RomanshLocale(Locale):
class RomanianLocale (line 4369) | class RomanianLocale(Locale):
class SlovenianLocale (line 4436) | class SlovenianLocale(Locale):
class IndonesianLocale (line 4507) | class IndonesianLocale(Locale):
class NepaliLocale (line 4582) | class NepaliLocale(Locale):
class EstonianLocale (line 4651) | class EstonianLocale(Locale):
method _format_timeframe (line 4717) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
class LatvianLocale (line 4726) | class LatvianLocale(Locale):
class SwahiliLocale (line 4806) | class SwahiliLocale(Locale):
class CroatianLocale (line 4890) | class CroatianLocale(Locale):
method _format_timeframe (line 4969) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
class LatinLocale (line 4981) | class LatinLocale(Locale):
class LithuanianLocale (line 5061) | class LithuanianLocale(Locale):
class MalayLocale (line 5141) | class MalayLocale(Locale):
class MalteseLocale (line 5221) | class MalteseLocale(Locale):
method _format_timeframe (line 5300) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
class SamiLocale (line 5312) | class SamiLocale(Locale):
class OdiaLocale (line 5391) | class OdiaLocale(Locale):
method _ordinal_number (line 5467) | def _ordinal_number(self, n: int) -> str:
class SerbianLocale (line 5481) | class SerbianLocale(Locale):
method _format_timeframe (line 5560) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
class LuxembourgishLocale (line 5572) | class LuxembourgishLocale(Locale):
method _ordinal_number (line 5654) | def _ordinal_number(self, n: int) -> str:
method describe (line 5657) | def describe(
class ZuluLocale (line 5674) | class ZuluLocale(Locale):
method _format_timeframe (line 5699) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
class TamilLocale (line 5771) | class TamilLocale(Locale):
method _ordinal_number (line 5849) | def _ordinal_number(self, n: int) -> str:
class AlbanianLocale (line 5858) | class AlbanianLocale(Locale):
class GeorgianLocale (line 5938) | class GeorgianLocale(Locale):
class SinhalaLocale (line 6022) | class SinhalaLocale(Locale):
method _format_timeframe (line 6091) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
method describe (line 6110) | def describe(
class UrduLocale (line 6185) | class UrduLocale(Locale):
class KazakhLocale (line 6265) | class KazakhLocale(Locale):
class AmharicLocale (line 6332) | class AmharicLocale(Locale):
method _ordinal_number (line 6461) | def _ordinal_number(self, n: int) -> str:
method _format_timeframe (line 6464) | def _format_timeframe(self, timeframe: TimeFrameLiteral, delta: int) -...
method describe (line 6483) | def describe(
class ArmenianLocale (line 6503) | class ArmenianLocale(Locale):
class UzbekLocale (line 6589) | class UzbekLocale(Locale):
FILE: arrow/parser.py
class ParserError (line 36) | class ParserError(ValueError):
class ParserMatchError (line 53) | class ParserMatchError(ParserError):
class _Parts (line 102) | class _Parts(TypedDict, total=False):
class DateTimeParser (line 142) | class DateTimeParser:
method __init__ (line 209) | def __init__(self, locale: str = DEFAULT_LOCALE, cache_size: int = 0) ...
method parse_iso (line 252) | def parse_iso(
method parse (line 373) | def parse(
method _generate_pattern_re (line 441) | def _generate_pattern_re(self, fmt: str) -> Tuple[List[_FORMAT_TYPE], ...
method _parse_token (line 533) | def _parse_token(
method _parse_token (line 560) | def _parse_token(
method _parse_token (line 568) | def _parse_token(
method _parse_token (line 576) | def _parse_token(
method _parse_token (line 584) | def _parse_token(
method _parse_token (line 591) | def _parse_token(
method _build_datetime (line 696) | def _build_datetime(parts: _Parts) -> datetime:
method _parse_multiformat (line 830) | def _parse_multiformat(self, string: str, formats: Iterable[str]) -> d...
method _generate_choice_re (line 865) | def _generate_choice_re(
class TzinfoParser (line 885) | class TzinfoParser:
method parse (line 895) | def parse(cls, tzinfo_string: str) -> dt_tzinfo:
FILE: arrow/util.py
function next_weekday (line 17) | def next_weekday(
function is_timestamp (line 45) | def is_timestamp(value: Any) -> bool:
function validate_ordinal (line 58) | def validate_ordinal(value: Any) -> None:
function normalize_timestamp (line 70) | def normalize_timestamp(timestamp: float) -> float:
function iso_to_gregorian (line 83) | def iso_to_gregorian(iso_year: int, iso_week: int, iso_day: int) -> date...
function validate_bounds (line 107) | def validate_bounds(bounds: str) -> None:
FILE: tests/conftest.py
function time_utcnow (line 14) | def time_utcnow(request):
function time_2013_01_01 (line 19) | def time_2013_01_01(request):
function time_2013_02_03 (line 26) | def time_2013_02_03(request):
function time_2013_02_15 (line 31) | def time_2013_02_15(request):
function time_1975_12_25 (line 37) | def time_1975_12_25(request):
function arrow_formatter (line 45) | def arrow_formatter(request):
function arrow_factory (line 50) | def arrow_factory(request):
function lang_locales (line 55) | def lang_locales(request):
function lang_locale (line 60) | def lang_locale(request):
function dt_parser (line 68) | def dt_parser(request):
function dt_parser_regex (line 73) | def dt_parser_regex(request):
function tzinfo_parser (line 78) | def tzinfo_parser(request):
FILE: tests/test_api.py
class TestModule (line 4) | class TestModule:
method test_get (line 5) | def test_get(self, mocker):
method test_utcnow (line 10) | def test_utcnow(self, mocker):
method test_now (line 15) | def test_now(self, mocker):
method test_factory (line 20) | def test_factory(self):
FILE: tests/test_arrow.py
class TestTestArrowInit (line 24) | class TestTestArrowInit:
method test_init_bad_input (line 25) | def test_init_bad_input(self):
method test_init (line 35) | def test_init(self):
method test_init_pytz_timezone (line 65) | def test_init_pytz_timezone(self):
method test_init_zoneinfo_timezone (line 75) | def test_init_zoneinfo_timezone(self):
method test_init_dateutil_timezone (line 85) | def test_init_dateutil_timezone(self):
method test_init_with_fold (line 95) | def test_init_with_fold(self):
class TestTestArrowFactory (line 107) | class TestTestArrowFactory:
method test_now (line 108) | def test_now(self):
method test_utcnow (line 113) | def test_utcnow(self):
method test_fromtimestamp (line 122) | def test_fromtimestamp(self):
method test_utcfromtimestamp (line 143) | def test_utcfromtimestamp(self):
method test_fromdatetime (line 154) | def test_fromdatetime(self):
method test_fromdatetime_dt_tzinfo (line 161) | def test_fromdatetime_dt_tzinfo(self):
method test_fromdatetime_tzinfo_arg (line 168) | def test_fromdatetime_tzinfo_arg(self):
method test_fromdate (line 175) | def test_fromdate(self):
method test_strptime (line 182) | def test_strptime(self):
method test_fromordinal (line 195) | def test_fromordinal(self):
class TestTestArrowRepresentation (line 214) | class TestTestArrowRepresentation:
method test_repr (line 215) | def test_repr(self):
method test_str (line 220) | def test_str(self):
method test_hash (line 225) | def test_hash(self):
method test_format (line 230) | def test_format(self):
method test_bare_format (line 235) | def test_bare_format(self):
method test_format_no_format_string (line 240) | def test_format_no_format_string(self):
method test_clone (line 245) | def test_clone(self):
class TestArrowAttribute (line 253) | class TestArrowAttribute:
method test_getattr_base (line 254) | def test_getattr_base(self):
method test_getattr_week (line 258) | def test_getattr_week(self):
method test_getattr_quarter (line 261) | def test_getattr_quarter(self):
method test_getattr_dt_value (line 282) | def test_getattr_dt_value(self):
method test_tzinfo (line 285) | def test_tzinfo(self):
method test_naive (line 288) | def test_naive(self):
method test_timestamp (line 291) | def test_timestamp(self):
method test_int_timestamp (line 294) | def test_int_timestamp(self):
method test_float_timestamp (line 297) | def test_float_timestamp(self):
method test_getattr_fold (line 300) | def test_getattr_fold(self):
method test_getattr_ambiguous (line 312) | def test_getattr_ambiguous(self):
method test_getattr_imaginary (line 319) | def test_getattr_imaginary(self):
class TestArrowComparison (line 328) | class TestArrowComparison:
method test_eq (line 329) | def test_eq(self):
method test_ne (line 334) | def test_ne(self):
method test_gt (line 339) | def test_gt(self):
method test_ge (line 351) | def test_ge(self):
method test_lt (line 358) | def test_lt(self):
method test_le (line 370) | def test_le(self):
class TestArrowMath (line 379) | class TestArrowMath:
method test_add_timedelta (line 380) | def test_add_timedelta(self):
method test_add_other (line 385) | def test_add_other(self):
method test_radd (line 389) | def test_radd(self):
method test_sub_timedelta (line 394) | def test_sub_timedelta(self):
method test_sub_datetime (line 399) | def test_sub_datetime(self):
method test_sub_arrow (line 404) | def test_sub_arrow(self):
method test_sub_other (line 409) | def test_sub_other(self):
method test_rsub_datetime (line 413) | def test_rsub_datetime(self):
method test_rsub_other (line 418) | def test_rsub_other(self):
class TestArrowDatetimeInterface (line 424) | class TestArrowDatetimeInterface:
method test_date (line 425) | def test_date(self):
method test_time (line 430) | def test_time(self):
method test_timetz (line 435) | def test_timetz(self):
method test_astimezone (line 440) | def test_astimezone(self):
method test_utcoffset (line 447) | def test_utcoffset(self):
method test_dst (line 452) | def test_dst(self):
method test_timetuple (line 457) | def test_timetuple(self):
method test_utctimetuple (line 462) | def test_utctimetuple(self):
method test_toordinal (line 467) | def test_toordinal(self):
method test_weekday (line 472) | def test_weekday(self):
method test_isoweekday (line 477) | def test_isoweekday(self):
method test_isocalendar (line 482) | def test_isocalendar(self):
method test_isoformat (line 487) | def test_isoformat(self):
method test_isoformat_timespec (line 492) | def test_isoformat_timespec(self):
method test_simplejson (line 505) | def test_simplejson(self):
method test_ctime (line 510) | def test_ctime(self):
method test_strftime (line 515) | def test_strftime(self):
class TestArrowFalsePositiveDst (line 521) | class TestArrowFalsePositiveDst:
method test_dst (line 545) | def test_dst(self):
class TestArrowConversion (line 568) | class TestArrowConversion:
method test_to (line 569) | def test_to(self):
method test_to_pacific_then_utc (line 581) | def test_to_pacific_then_utc(self):
method test_to_amsterdam_then_utc (line 586) | def test_to_amsterdam_then_utc(self):
method test_to_israel_same_offset (line 591) | def test_to_israel_same_offset(self):
method test_anchorage_dst (line 599) | def test_anchorage_dst(self):
method test_chicago_fall (line 606) | def test_chicago_fall(self):
method test_toronto_gap (line 613) | def test_toronto_gap(self):
method test_sydney_gap (line 622) | def test_sydney_gap(self):
class TestArrowPickling (line 632) | class TestArrowPickling:
method test_pickle_and_unpickle (line 633) | def test_pickle_and_unpickle(self):
class TestArrowReplace (line 643) | class TestArrowReplace:
method test_not_attr (line 644) | def test_not_attr(self):
method test_replace (line 648) | def test_replace(self):
method test_replace_tzinfo (line 658) | def test_replace_tzinfo(self):
method test_replace_fold (line 665) | def test_replace_fold(self):
method test_replace_fold_and_other (line 674) | def test_replace_fold_and_other(self):
method test_replace_week (line 680) | def test_replace_week(self):
method test_replace_quarter (line 684) | def test_replace_quarter(self):
method test_replace_quarter_and_fold (line 688) | def test_replace_quarter_and_fold(self):
method test_replace_other_kwargs (line 695) | def test_replace_other_kwargs(self):
class TestArrowShift (line 700) | class TestArrowShift:
method test_not_attr (line 701) | def test_not_attr(self):
method test_shift (line 710) | def test_shift(self):
method test_shift_negative (line 766) | def test_shift_negative(self):
method test_shift_quarters_bug (line 801) | def test_shift_quarters_bug(self):
method test_shift_positive_imaginary (line 818) | def test_shift_positive_imaginary(self):
method test_shift_negative_imaginary (line 848) | def test_shift_negative_imaginary(self):
method test_shift_with_imaginary_check (line 871) | def test_shift_with_imaginary_check(self):
method test_shift_without_imaginary_check (line 876) | def test_shift_without_imaginary_check(self):
method test_shift_kiritimati (line 884) | def test_shift_kiritimati(self):
method shift_imaginary_seconds (line 892) | def shift_imaginary_seconds(self):
class TestArrowRange (line 900) | class TestArrowRange:
method test_year (line 901) | def test_year(self):
method test_quarter (line 915) | def test_quarter(self):
method test_month (line 927) | def test_month(self):
method test_week (line 941) | def test_week(self):
method test_day (line 956) | def test_day(self):
method test_hour (line 970) | def test_hour(self):
method test_minute (line 992) | def test_minute(self):
method test_second (line 1006) | def test_second(self):
method test_arrow (line 1020) | def test_arrow(self):
method test_naive_tz (line 1036) | def test_naive_tz(self):
method test_aware_same_tz (line 1044) | def test_aware_same_tz(self):
method test_aware_different_tz (line 1054) | def test_aware_different_tz(self):
method test_aware_tz (line 1064) | def test_aware_tz(self):
method test_imaginary (line 1075) | def test_imaginary(self):
method test_unsupported (line 1087) | def test_unsupported(self):
method test_range_over_months_ending_on_different_days (line 1095) | def test_range_over_months_ending_on_different_days(self):
method test_range_over_quarter_months_ending_on_different_days (line 1126) | def test_range_over_quarter_months_ending_on_different_days(self):
method test_range_over_year_maintains_end_date_across_leap_year (line 1134) | def test_range_over_year_maintains_end_date_across_leap_year(self):
class TestArrowSpanRange (line 1145) | class TestArrowSpanRange:
method test_year (line 1146) | def test_year(self):
method test_quarter (line 1170) | def test_quarter(self):
method test_month (line 1182) | def test_month(self):
method test_week (line 1194) | def test_week(self):
method test_day (line 1213) | def test_day(self):
method test_days (line 1239) | def test_days(self):
method test_hour (line 1265) | def test_hour(self):
method test_minute (line 1301) | def test_minute(self):
method test_second (line 1327) | def test_second(self):
method test_naive_tz (line 1353) | def test_naive_tz(self):
method test_aware_same_tz (line 1364) | def test_aware_same_tz(self):
method test_aware_different_tz (line 1377) | def test_aware_different_tz(self):
method test_aware_tz (line 1391) | def test_aware_tz(self):
method test_bounds_param_is_passed (line 1403) | def test_bounds_param_is_passed(self):
method test_exact_bound_exclude (line 1415) | def test_exact_bound_exclude(self):
method test_exact_floor_equals_end (line 1451) | def test_exact_floor_equals_end(self):
method test_exact_bound_include (line 1506) | def test_exact_bound_include(self):
method test_small_interval_exact_open_bounds (line 1538) | def test_small_interval_exact_open_bounds(self):
class TestArrowInterval (line 1559) | class TestArrowInterval:
method test_incorrect_input (line 1560) | def test_incorrect_input(self):
method test_correct (line 1568) | def test_correct(self):
method test_bounds_param_is_passed (line 1590) | def test_bounds_param_is_passed(self):
method test_exact (line 1607) | def test_exact(self):
class TestArrowSpan (line 1633) | class TestArrowSpan:
method test_span_attribute (line 1634) | def test_span_attribute(self):
method test_span_year (line 1638) | def test_span_year(self):
method test_span_quarter (line 1644) | def test_span_quarter(self):
method test_span_quarter_count (line 1650) | def test_span_quarter_count(self):
method test_span_year_count (line 1656) | def test_span_year_count(self):
method test_span_month (line 1662) | def test_span_month(self):
method test_span_week (line 1668) | def test_span_week(self):
method test_span_day (line 1694) | def test_span_day(self):
method test_span_hour (line 1700) | def test_span_hour(self):
method test_span_minute (line 1706) | def test_span_minute(self):
method test_span_second (line 1712) | def test_span_second(self):
method test_span_microsecond (line 1718) | def test_span_microsecond(self):
method test_floor (line 1724) | def test_floor(self):
method test_floor_week_start (line 1730) | def test_floor_week_start(self):
method test_ceil_week_start (line 1759) | def test_ceil_week_start(self):
method test_floor_ceil_week_start_values (line 1788) | def test_floor_ceil_week_start_values(self):
method test_floor_ceil_week_start_backward_compatibility (line 1817) | def test_floor_ceil_week_start_backward_compatibility(self):
method test_floor_ceil_week_start_ignored_for_non_week_frames (line 1831) | def test_floor_ceil_week_start_ignored_for_non_week_frames(self):
method test_floor_ceil_week_start_validation (line 1847) | def test_floor_ceil_week_start_validation(self):
method test_span_inclusive_inclusive (line 1886) | def test_span_inclusive_inclusive(self):
method test_span_exclusive_inclusive (line 1892) | def test_span_exclusive_inclusive(self):
method test_span_exclusive_exclusive (line 1898) | def test_span_exclusive_exclusive(self):
method test_bounds_are_validated (line 1904) | def test_bounds_are_validated(self):
method test_exact (line 1908) | def test_exact(self):
method test_exact_inclusive_inclusive (line 1917) | def test_exact_inclusive_inclusive(self):
method test_exact_exclusive_inclusive (line 1923) | def test_exact_exclusive_inclusive(self):
method test_exact_exclusive_exclusive (line 1929) | def test_exact_exclusive_exclusive(self):
method test_all_parameters_specified (line 1935) | def test_all_parameters_specified(self):
class TestArrowHumanize (line 1943) | class TestArrowHumanize:
method test_granularity (line 1944) | def test_granularity(self):
method test_multiple_granularity (line 2040) | def test_multiple_granularity(self):
method test_seconds (line 2113) | def test_seconds(self):
method test_minute (line 2123) | def test_minute(self):
method test_minutes (line 2132) | def test_minutes(self):
method test_hour (line 2141) | def test_hour(self):
method test_hours (line 2150) | def test_hours(self):
method test_day (line 2159) | def test_day(self):
method test_days (line 2180) | def test_days(self):
method test_week (line 2199) | def test_week(self):
method test_weeks (line 2208) | def test_weeks(self):
method test_month (line 2217) | def test_month(self):
method test_months (line 2226) | def test_months(self):
method test_year (line 2236) | def test_year(self):
method test_years (line 2245) | def test_years(self):
method test_arrow (line 2260) | def test_arrow(self):
method test_datetime_tzinfo (line 2267) | def test_datetime_tzinfo(self):
method test_other (line 2274) | def test_other(self):
method test_invalid_locale (line 2280) | def test_invalid_locale(self):
method test_none (line 2286) | def test_none(self):
method test_week_limit (line 2297) | def test_week_limit(self):
method test_untranslated_granularity (line 2307) | def test_untranslated_granularity(self, mocker):
method test_empty_granularity_list (line 2317) | def test_empty_granularity_list(self):
method test_no_floats (line 2329) | def test_no_floats(self):
method test_no_floats_multi_gran (line 2335) | def test_no_floats_multi_gran(self):
class TestArrowHumanizeTestsWithLocale (line 2345) | class TestArrowHumanizeTestsWithLocale:
method test_now (line 2346) | def test_now(self):
method test_seconds (line 2353) | def test_seconds(self):
method test_years (line 2359) | def test_years(self):
function locale_list_no_weeks (line 2369) | def locale_list_no_weeks() -> List[str]:
function locale_list_with_weeks (line 2510) | def locale_list_with_weeks() -> List[str]:
function slavic_locales (line 2588) | def slavic_locales() -> List[str]:
class TestArrowDehumanize (line 2608) | class TestArrowDehumanize:
method test_now (line 2609) | def test_now(self, locale_list_no_weeks: List[str]):
method test_seconds (line 2625) | def test_seconds(self, locale_list_no_weeks: List[str]):
method test_minute (line 2641) | def test_minute(self, locale_list_no_weeks: List[str]):
method test_minutes (line 2657) | def test_minutes(self, locale_list_no_weeks: List[str]):
method test_hour (line 2673) | def test_hour(self, locale_list_no_weeks: List[str]):
method test_hours (line 2687) | def test_hours(self, locale_list_no_weeks: List[str]):
method test_week (line 2701) | def test_week(self, locale_list_with_weeks: List[str]):
method test_weeks (line 2715) | def test_weeks(self, locale_list_with_weeks: List[str]):
method test_year (line 2729) | def test_year(self, locale_list_no_weeks: List[str]):
method test_years (line 2743) | def test_years(self, locale_list_no_weeks: List[str]):
method test_gt_than_10_years (line 2757) | def test_gt_than_10_years(self, locale_list_no_weeks: List[str]):
method test_mixed_granularity (line 2771) | def test_mixed_granularity(self, locale_list_no_weeks: List[str]):
method test_mixed_granularity_hours (line 2787) | def test_mixed_granularity_hours(self, locale_list_no_weeks: List[str]):
method test_mixed_granularity_day (line 2803) | def test_mixed_granularity_day(self, locale_list_no_weeks: List[str]):
method test_mixed_granularity_day_hour (line 2819) | def test_mixed_granularity_day_hour(self, locale_list_no_weeks: List[s...
method test_unsupported_locale (line 2836) | def test_unsupported_locale(self):
method test_normalized_locale (line 2856) | def test_normalized_locale(self):
method test_require_relative_unit (line 2872) | def test_require_relative_unit(self, locale_list_no_weeks: List[str]):
method test_scrambled_input (line 2892) | def test_scrambled_input(self, locale_list_no_weeks: List[str]):
method test_no_units_modified (line 2918) | def test_no_units_modified(self, locale_list_no_weeks: List[str]):
method test_slavic_locales (line 2933) | def test_slavic_locales(self, slavic_locales: List[str]):
method test_czech_slovak (line 2963) | def test_czech_slovak(self):
class TestArrowIsBetween (line 2991) | class TestArrowIsBetween:
method test_start_before_end (line 2992) | def test_start_before_end(self):
method test_exclusive_exclusive_bounds (line 2998) | def test_exclusive_exclusive_bounds(self):
method test_exclusive_exclusive_bounds_same_date (line 3004) | def test_exclusive_exclusive_bounds_same_date(self):
method test_inclusive_exclusive_bounds (line 3010) | def test_inclusive_exclusive_bounds(self):
method test_exclusive_inclusive_bounds (line 3016) | def test_exclusive_inclusive_bounds(self):
method test_inclusive_inclusive_bounds_same_date (line 3022) | def test_inclusive_inclusive_bounds_same_date(self):
method test_inclusive_inclusive_bounds_target_before_start (line 3028) | def test_inclusive_inclusive_bounds_target_before_start(self):
method test_type_error_exception (line 3034) | def test_type_error_exception(self):
method test_value_error_exception (line 3050) | def test_value_error_exception(self):
class TestArrowUtil (line 3068) | class TestArrowUtil:
method test_get_datetime (line 3069) | def test_get_datetime(self):
method test_get_tzinfo (line 3086) | def test_get_tzinfo(self):
method test_get_iteration_params (line 3093) | def test_get_iteration_params(self):
FILE: tests/test_factory.py
class TestGet (line 20) | class TestGet:
method test_no_args (line 21) | def test_no_args(self):
method test_timestamp_one_arg_no_arg (line 26) | def test_timestamp_one_arg_no_arg(self):
method test_one_arg_none (line 32) | def test_one_arg_none(self):
method test_struct_time (line 36) | def test_struct_time(self):
method test_one_arg_timestamp (line 42) | def test_one_arg_timestamp(self):
method test_one_arg_expanded_timestamp (line 69) | def test_one_arg_expanded_timestamp(self):
method test_one_arg_timestamp_with_tzinfo (line 81) | def test_one_arg_timestamp_with_tzinfo(self):
method test_one_arg_arrow (line 92) | def test_one_arg_arrow(self):
method test_one_arg_datetime (line 98) | def test_one_arg_datetime(self):
method test_one_arg_date (line 103) | def test_one_arg_date(self):
method test_one_arg_tzinfo (line 109) | def test_one_arg_tzinfo(self):
method test_one_arg_dateparser_datetime (line 121) | def test_one_arg_dateparser_datetime(self):
method test_kwarg_tzinfo (line 129) | def test_kwarg_tzinfo(self):
method test_kwarg_tzinfo_string (line 140) | def test_kwarg_tzinfo_string(self):
method test_kwarg_normalize_whitespace (line 152) | def test_kwarg_normalize_whitespace(self):
method test_one_arg_datetime_tzinfo_kwarg (line 171) | def test_one_arg_datetime_tzinfo_kwarg(self):
method test_one_arg_arrow_tzinfo_kwarg (line 180) | def test_one_arg_arrow_tzinfo_kwarg(self):
method test_one_arg_date_tzinfo_kwarg (line 189) | def test_one_arg_date_tzinfo_kwarg(self):
method test_one_arg_iso_calendar_tzinfo_kwarg (line 199) | def test_one_arg_iso_calendar_tzinfo_kwarg(self):
method test_one_arg_iso_str (line 206) | def test_one_arg_iso_str(self):
method test_one_arg_iso_calendar (line 211) | def test_one_arg_iso_calendar(self):
method test_one_arg_other (line 239) | def test_one_arg_other(self):
method test_one_arg_bool (line 243) | def test_one_arg_bool(self):
method test_one_arg_decimal (line 250) | def test_one_arg_decimal(self):
method test_two_args_datetime_tzinfo (line 257) | def test_two_args_datetime_tzinfo(self):
method test_two_args_datetime_tz_str (line 262) | def test_two_args_datetime_tz_str(self):
method test_two_args_date_tzinfo (line 267) | def test_two_args_date_tzinfo(self):
method test_two_args_date_tz_str (line 272) | def test_two_args_date_tz_str(self):
method test_two_args_datetime_other (line 277) | def test_two_args_datetime_other(self):
method test_two_args_date_other (line 281) | def test_two_args_date_other(self):
method test_two_args_str_str (line 285) | def test_two_args_str_str(self):
method test_two_args_str_tzinfo (line 290) | def test_two_args_str_tzinfo(self):
method test_two_args_twitter_format (line 297) | def test_two_args_twitter_format(self):
method test_two_args_str_list (line 304) | def test_two_args_str_list(self):
method test_two_args_unicode_unicode (line 309) | def test_two_args_unicode_unicode(self):
method test_two_args_other (line 314) | def test_two_args_other(self):
method test_three_args_with_tzinfo (line 318) | def test_three_args_with_tzinfo(self):
method test_three_args (line 326) | def test_three_args(self):
method test_full_kwargs (line 329) | def test_full_kwargs(self):
method test_three_kwargs (line 340) | def test_three_kwargs(self):
method test_tzinfo_string_kwargs (line 345) | def test_tzinfo_string_kwargs(self):
method test_insufficient_kwargs (line 349) | def test_insufficient_kwargs(self):
method test_locale (line 356) | def test_locale(self):
method test_locale_kwarg_only (line 366) | def test_locale_kwarg_only(self):
method test_locale_with_tzinfo (line 370) | def test_locale_with_tzinfo(self):
class TestUtcNow (line 376) | class TestUtcNow:
method test_utcnow (line 377) | def test_utcnow(self):
class TestNow (line 385) | class TestNow:
method test_no_tz (line 386) | def test_no_tz(self):
method test_tzinfo (line 389) | def test_tzinfo(self):
method test_tz_str (line 394) | def test_tz_str(self):
FILE: tests/test_formatter.py
class TestFormatterFormatToken (line 29) | class TestFormatterFormatToken:
method test_format (line 30) | def test_format(self):
method test_year (line 37) | def test_year(self):
method test_month (line 42) | def test_month(self):
method test_day (line 49) | def test_day(self):
method test_hour (line 61) | def test_hour(self):
method test_minute (line 83) | def test_minute(self):
method test_second (line 88) | def test_second(self):
method test_sub_second (line 93) | def test_sub_second(self):
method test_timestamp (line 110) | def test_timestamp(self):
method test_timezone (line 120) | def test_timezone(self):
method test_timezone_formatter (line 130) | def test_timezone_formatter(self, full_tz_name):
method test_am_pm (line 140) | def test_am_pm(self):
method test_week (line 149) | def test_week(self):
method test_nonsense (line 157) | def test_nonsense(self):
method test_escape (line 162) | def test_escape(self):
class TestFormatterBuiltinFormats (line 213) | class TestFormatterBuiltinFormats:
method test_atom (line 214) | def test_atom(self):
method test_cookie (line 220) | def test_cookie(self):
method test_rfc_822 (line 226) | def test_rfc_822(self):
method test_rfc_850 (line 232) | def test_rfc_850(self):
method test_rfc_1036 (line 238) | def test_rfc_1036(self):
method test_rfc_1123 (line 244) | def test_rfc_1123(self):
method test_rfc_2822 (line 250) | def test_rfc_2822(self):
method test_rfc3339 (line 256) | def test_rfc3339(self):
method test_rfc3339_strict (line 262) | def test_rfc3339_strict(self):
method test_rss (line 268) | def test_rss(self):
method test_w3c (line 274) | def test_w3c(self):
FILE: tests/test_locales.py
class TestLocaleValidation (line 7) | class TestLocaleValidation:
method test_locale_validation (line 10) | def test_locale_validation(self):
method test_locale_name_validation (line 35) | def test_locale_name_validation(self):
method test_duplicated_locale_name (line 44) | def test_duplicated_locale_name(self):
class TestModule (line 51) | class TestModule:
method test_get_locale (line 52) | def test_get_locale(self, mocker):
method test_get_locale_by_class_name (line 73) | def test_get_locale_by_class_name(self, mocker):
method test_locales (line 89) | def test_locales(self):
class TestCustomLocale (line 93) | class TestCustomLocale:
method test_custom_locale_subclass (line 94) | def test_custom_locale_subclass(self):
class TestEnglishLocale (line 109) | class TestEnglishLocale:
method test_describe (line 110) | def test_describe(self):
method test_format_timeframe (line 114) | def test_format_timeframe(self):
method test_format_relative_now (line 118) | def test_format_relative_now(self):
method test_format_relative_past (line 123) | def test_format_relative_past(self):
method test_format_relative_future (line 128) | def test_format_relative_future(self):
method test_ordinal_number (line 133) | def test_ordinal_number(self):
method test_meridian_invalid_token (line 164) | def test_meridian_invalid_token(self):
class TestItalianLocale (line 171) | class TestItalianLocale:
method test_ordinal_number (line 172) | def test_ordinal_number(self):
class TestSpanishLocale (line 177) | class TestSpanishLocale:
method test_ordinal_number (line 178) | def test_ordinal_number(self):
method test_format_timeframe (line 181) | def test_format_timeframe(self):
class TestFrenchLocale (line 230) | class TestFrenchLocale:
method test_ordinal_number (line 231) | def test_ordinal_number(self):
method test_month_abbreviation (line 235) | def test_month_abbreviation(self):
class TestFrenchCanadianLocale (line 240) | class TestFrenchCanadianLocale:
method test_month_abbreviation (line 241) | def test_month_abbreviation(self):
class TestRussianLocale (line 246) | class TestRussianLocale:
method test_singles_timeframe (line 247) | def test_singles_timeframe(self):
method test_singles_relative (line 262) | def test_singles_relative(self):
method test_plurals_timeframe (line 279) | def test_plurals_timeframe(self):
method test_plurals_relative (line 344) | def test_plurals_relative(self):
method test_plurals2 (line 409) | def test_plurals2(self):
class TestPolishLocale (line 431) | class TestPolishLocale:
method test_plurals (line 432) | def test_plurals(self):
class TestIcelandicLocale (line 483) | class TestIcelandicLocale:
method test_format_timeframe (line 484) | def test_format_timeframe(self):
class TestMalayalamLocale (line 525) | class TestMalayalamLocale:
method test_format_timeframe (line 526) | def test_format_timeframe(self):
method test_format_relative_now (line 530) | def test_format_relative_now(self):
method test_format_relative_past (line 535) | def test_format_relative_past(self):
method test_format_relative_future (line 539) | def test_format_relative_future(self):
class TestMalteseLocale (line 545) | class TestMalteseLocale:
method test_format_timeframe (line 546) | def test_format_timeframe(self):
method test_weekday (line 565) | def test_weekday(self):
class TestHindiLocale (line 572) | class TestHindiLocale:
method test_format_timeframe (line 573) | def test_format_timeframe(self):
method test_format_relative_now (line 577) | def test_format_relative_now(self):
method test_format_relative_past (line 581) | def test_format_relative_past(self):
method test_format_relative_future (line 585) | def test_format_relative_future(self):
class TestCzechLocale (line 591) | class TestCzechLocale:
method test_format_timeframe (line 592) | def test_format_timeframe(self):
method test_format_relative_now (line 659) | def test_format_relative_now(self):
method test_format_relative_future (line 663) | def test_format_relative_future(self):
method test_format_relative_past (line 667) | def test_format_relative_past(self):
class TestSlovakLocale (line 673) | class TestSlovakLocale:
method test_format_timeframe (line 674) | def test_format_timeframe(self):
method test_format_relative_now (line 733) | def test_format_relative_now(self):
method test_format_relative_future (line 737) | def test_format_relative_future(self):
method test_format_relative_past (line 741) | def test_format_relative_past(self):
class TestBulgarianLocale (line 747) | class TestBulgarianLocale:
method test_plurals2 (line 748) | def test_plurals2(self):
class TestMacedonianLocale (line 770) | class TestMacedonianLocale:
method test_singles_mk (line 771) | def test_singles_mk(self):
method test_meridians_mk (line 780) | def test_meridians_mk(self):
method test_describe_mk (line 786) | def test_describe_mk(self):
method test_relative_mk (line 802) | def test_relative_mk(self):
method test_plurals_mk (line 824) | def test_plurals_mk(self):
method test_multi_describe_mk (line 887) | def test_multi_describe_mk(self):
class TestMacedonianLatinLocale (line 912) | class TestMacedonianLatinLocale:
method test_singles_mk (line 913) | def test_singles_mk(self):
method test_meridians_mk (line 922) | def test_meridians_mk(self):
method test_describe_mk (line 928) | def test_describe_mk(self):
method test_relative_mk (line 944) | def test_relative_mk(self):
method test_plurals_mk (line 966) | def test_plurals_mk(self):
method test_multi_describe_mk (line 1029) | def test_multi_describe_mk(self):
class TestHebrewLocale (line 1055) | class TestHebrewLocale:
method test_couple_of_timeframe (line 1056) | def test_couple_of_timeframe(self):
method test_describe_multi (line 1102) | def test_describe_multi(self):
class TestAzerbaijaniLocale (line 1124) | class TestAzerbaijaniLocale:
method test_singles_mk (line 1125) | def test_singles_mk(self):
method test_describe_mk (line 1134) | def test_describe_mk(self):
method test_relative_mk (line 1150) | def test_relative_mk(self):
method test_plurals_mk (line 1175) | def test_plurals_mk(self):
class TestMarathiLocale (line 1194) | class TestMarathiLocale:
method test_dateCoreFunctionality (line 1195) | def test_dateCoreFunctionality(self):
method test_format_timeframe (line 1202) | def test_format_timeframe(self):
method test_format_relative_now (line 1206) | def test_format_relative_now(self):
method test_format_relative_past (line 1210) | def test_format_relative_past(self):
method test_format_relative_future (line 1214) | def test_format_relative_future(self):
method test_ordinal_number (line 1219) | def test_ordinal_number(self):
class TestFinnishLocale (line 1224) | class TestFinnishLocale:
method test_format_timeframe (line 1225) | def test_format_timeframe(self):
method test_format_relative_now (line 1265) | def test_format_relative_now(self):
method test_format_relative_past (line 1269) | def test_format_relative_past(self):
method test_format_relative_future (line 1273) | def test_format_relative_future(self):
method test_ordinal_number (line 1277) | def test_ordinal_number(self):
class TestGeorgianLocale (line 1282) | class TestGeorgianLocale:
method test_format_timeframe (line 1283) | def test_format_timeframe(self):
method test_weekday (line 1329) | def test_weekday(self):
class TestGermanLocale (line 1335) | class TestGermanLocale:
method test_ordinal_number (line 1336) | def test_ordinal_number(self):
method test_define (line 1339) | def test_define(self):
method test_weekday (line 1353) | def test_weekday(self):
class TestHungarianLocale (line 1360) | class TestHungarianLocale:
method test_format_timeframe (line 1361) | def test_format_timeframe(self):
class TestEsperantoLocale (line 1409) | class TestEsperantoLocale:
method test_format_timeframe (line 1410) | def test_format_timeframe(self):
method test_ordinal_number (line 1416) | def test_ordinal_number(self):
class TestLaotianLocale (line 1421) | class TestLaotianLocale:
method test_year_full (line 1422) | def test_year_full(self):
method test_year_abbreviation (line 1425) | def test_year_abbreviation(self):
method test_format_relative_now (line 1428) | def test_format_relative_now(self):
method test_format_relative_past (line 1432) | def test_format_relative_past(self):
method test_format_relative_future (line 1440) | def test_format_relative_future(self):
method test_format_timeframe (line 1444) | def test_format_timeframe(self):
method test_weekday (line 1471) | def test_weekday(self):
class TestThaiLocale (line 1478) | class TestThaiLocale:
method test_year_full (line 1479) | def test_year_full(self):
method test_year_abbreviation (line 1482) | def test_year_abbreviation(self):
method test_format_relative_now (line 1485) | def test_format_relative_now(self):
method test_format_relative_past (line 1489) | def test_format_relative_past(self):
method test_format_relative_future (line 1497) | def test_format_relative_future(self):
method test_format_timeframe (line 1501) | def test_format_timeframe(self):
method test_weekday (line 1526) | def test_weekday(self):
method test_ordinal_number (line 1533) | def test_ordinal_number(self):
class TestBengaliLocale (line 1541) | class TestBengaliLocale:
method test_ordinal_number (line 1542) | def test_ordinal_number(self):
class TestRomanianLocale (line 1556) | class TestRomanianLocale:
method test_timeframes (line 1557) | def test_timeframes(self):
method test_relative_timeframes (line 1569) | def test_relative_timeframes(self):
class TestArabicLocale (line 1590) | class TestArabicLocale:
method test_timeframes (line 1591) | def test_timeframes(self):
class TestFarsiLocale (line 1626) | class TestFarsiLocale:
method test_timeframes (line 1627) | def test_timeframes(self):
method test_weekday (line 1645) | def test_weekday(self):
class TestNepaliLocale (line 1654) | class TestNepaliLocale:
method test_format_timeframe (line 1655) | def test_format_timeframe(self):
method test_format_relative_now (line 1659) | def test_format_relative_now(self):
method test_format_relative_future (line 1663) | def test_format_relative_future(self):
method test_format_relative_past (line 1667) | def test_format_relative_past(self):
class TestIndonesianLocale (line 1673) | class TestIndonesianLocale:
method test_timeframes (line 1674) | def test_timeframes(self):
method test_format_relative_now (line 1689) | def test_format_relative_now(self):
method test_format_relative_past (line 1692) | def test_format_relative_past(self):
method test_format_relative_future (line 1696) | def test_format_relative_future(self):
class TestTagalogLocale (line 1701) | class TestTagalogLocale:
method test_singles_tl (line 1702) | def test_singles_tl(self):
method test_meridians_tl (line 1711) | def test_meridians_tl(self):
method test_describe_tl (line 1717) | def test_describe_tl(self):
method test_relative_tl (line 1753) | def test_relative_tl(self):
method test_plurals_tl (line 1798) | def test_plurals_tl(self):
method test_multi_describe_tl (line 1861) | def test_multi_describe_tl(self):
method test_ordinal_number_tl (line 1884) | def test_ordinal_number_tl(self):
class TestCroatianLocale (line 1897) | class TestCroatianLocale:
method test_format_timeframe (line 1898) | def test_format_timeframe(self):
method test_weekday (line 1937) | def test_weekday(self):
class TestSerbianLocale (line 1944) | class TestSerbianLocale:
method test_format_timeframe (line 1945) | def test_format_timeframe(self):
method test_weekday (line 1984) | def test_weekday(self):
class TestLatinLocale (line 1991) | class TestLatinLocale:
method test_format_timeframe (line 1992) | def test_format_timeframe(self):
method test_weekday (line 2007) | def test_weekday(self):
class TestLithuanianLocale (line 2013) | class TestLithuanianLocale:
method test_format_timeframe (line 2014) | def test_format_timeframe(self):
method test_weekday (line 2032) | def test_weekday(self):
class TestMalayLocale (line 2039) | class TestMalayLocale:
method test_format_timeframe (line 2040) | def test_format_timeframe(self):
method test_weekday (line 2055) | def test_weekday(self):
class TestSamiLocale (line 2061) | class TestSamiLocale:
method test_format_timeframe (line 2062) | def test_format_timeframe(self):
method test_weekday (line 2077) | def test_weekday(self):
class TestZuluLocale (line 2083) | class TestZuluLocale:
method test_format_timeframe (line 2084) | def test_format_timeframe(self):
method test_weekday (line 2130) | def test_weekday(self):
class TestAlbanianLocale (line 2136) | class TestAlbanianLocale:
method test_format_timeframe (line 2137) | def test_format_timeframe(self):
method test_weekday_and_month (line 2155) | def test_weekday_and_month(self):
class TestUrduLocale (line 2166) | class TestUrduLocale:
method test_format_timeframe (line 2167) | def test_format_timeframe(self):
method test_weekday_and_month (line 2185) | def test_weekday_and_month(self):
class TestEstonianLocale (line 2196) | class TestEstonianLocale:
method test_format_timeframe (line 2197) | def test_format_timeframe(self):
class TestPortugueseLocale (line 2240) | class TestPortugueseLocale:
method test_format_timeframe (line 2241) | def test_format_timeframe(self):
class TestLatvianLocale (line 2258) | class TestLatvianLocale:
method test_format_timeframe (line 2259) | def test_format_timeframe(self):
method test_weekday (line 2278) | def test_weekday(self):
class TestBrazilianPortugueseLocale (line 2285) | class TestBrazilianPortugueseLocale:
method test_format_timeframe (line 2286) | def test_format_timeframe(self):
class TestHongKongLocale (line 2304) | class TestHongKongLocale:
method test_format_timeframe (line 2305) | def test_format_timeframe(self):
method test_format_relative_now (line 2337) | def test_format_relative_now(self):
method test_format_relative_past (line 2340) | def test_format_relative_past(self):
method test_format_relative_future (line 2356) | def test_format_relative_future(self):
class TestChineseTWLocale (line 2374) | class TestChineseTWLocale:
method test_format_timeframe (line 2375) | def test_format_timeframe(self):
method test_format_relative_now (line 2407) | def test_format_relative_now(self):
method test_format_relative_past (line 2410) | def test_format_relative_past(self):
method test_format_relative_future (line 2426) | def test_format_relative_future(self):
class TestChineseCNLocale (line 2444) | class TestChineseCNLocale:
method test_format_timeframe (line 2445) | def test_format_timeframe(self):
method test_format_relative_now (line 2477) | def test_format_relative_now(self):
method test_format_relative_past (line 2480) | def test_format_relative_past(self):
method test_format_relative_future (line 2496) | def test_format_relative_future(self):
class TestSwahiliLocale (line 2514) | class TestSwahiliLocale:
method test_format_timeframe (line 2515) | def test_format_timeframe(self):
method test_format_relative_now (line 2538) | def test_format_relative_now(self):
method test_format_relative_past (line 2542) | def test_format_relative_past(self):
method test_format_relative_future (line 2546) | def test_format_relative_future(self):
class TestKoreanLocale (line 2552) | class TestKoreanLocale:
method test_format_timeframe (line 2553) | def test_format_timeframe(self):
method test_format_relative (line 2570) | def test_format_relative(self):
method test_ordinal_number (line 2610) | def test_ordinal_number(self):
class TestDutchLocale (line 2628) | class TestDutchLocale:
method test_plurals (line 2629) | def test_plurals(self):
class TestJapaneseLocale (line 2648) | class TestJapaneseLocale:
method test_format_timeframe (line 2649) | def test_format_timeframe(self):
class TestSwedishLocale (line 2668) | class TestSwedishLocale:
method test_plurals (line 2669) | def test_plurals(self):
class TestOdiaLocale (line 2688) | class TestOdiaLocale:
method test_ordinal_number (line 2689) | def test_ordinal_number(self):
method test_format_timeframe (line 2701) | def test_format_timeframe(self):
method test_format_relative_now (line 2705) | def test_format_relative_now(self):
method test_format_relative_past (line 2709) | def test_format_relative_past(self):
method test_format_relative_future (line 2713) | def test_format_relative_future(self):
class TestTurkishLocale (line 2719) | class TestTurkishLocale:
method test_singles_mk (line 2720) | def test_singles_mk(self):
method test_meridians_mk (line 2729) | def test_meridians_mk(self):
method test_describe_mk (line 2735) | def test_describe_mk(self):
method test_relative_mk (line 2751) | def test_relative_mk(self):
method test_plurals_mk (line 2776) | def test_plurals_mk(self):
class TestLuxembourgishLocale (line 2795) | class TestLuxembourgishLocale:
method test_ordinal_number (line 2796) | def test_ordinal_number(self):
method test_define (line 2799) | def test_define(self):
method test_weekday (line 2813) | def test_weekday(self):
class TestTamilLocale (line 2820) | class TestTamilLocale:
method test_format_timeframe (line 2821) | def test_format_timeframe(self):
method test_ordinal_number (line 2838) | def test_ordinal_number(self):
method test_format_relative_now (line 2845) | def test_format_relative_now(self):
method test_format_relative_past (line 2849) | def test_format_relative_past(self):
method test_format_relative_future (line 2853) | def test_format_relative_future(self):
method test_weekday (line 2857) | def test_weekday(self):
class TestSinhalaLocale (line 2864) | class TestSinhalaLocale:
method test_format_timeframe (line 2865) | def test_format_timeframe(self):
method test_describe_si (line 2911) | def test_describe_si(self):
method test_format_relative_now (line 2937) | def test_format_relative_now(self):
method test_format_relative_future (line 2941) | def test_format_relative_future(self):
method test_format_relative_past (line 2946) | def test_format_relative_past(self):
method test_weekday (line 2951) | def test_weekday(self):
class TestKazakhLocale (line 2958) | class TestKazakhLocale:
method test_singles_mk (line 2959) | def test_singles_mk(self):
method test_describe_mk (line 2968) | def test_describe_mk(self):
method test_relative_mk (line 2984) | def test_relative_mk(self):
method test_plurals_mk (line 3005) | def test_plurals_mk(self):
class TestNorwegianLocale (line 3023) | class TestNorwegianLocale:
method test_describe (line 3024) | def test_describe(self):
method test_plurals (line 3028) | def test_plurals(self):
method test_ordinal_number (line 3045) | def test_ordinal_number(self):
method test_format_timeframe (line 3049) | def test_format_timeframe(self):
method test_format_relative_now (line 3053) | def test_format_relative_now(self):
method test_format_relative_past (line 3058) | def test_format_relative_past(self):
method test_format_relative_future (line 3063) | def test_format_relative_future(self):
method test_weekday (line 3068) | def test_weekday(self):
class TestNewNorwegianLocale (line 3075) | class TestNewNorwegianLocale:
method test_describe (line 3076) | def test_describe(self):
method test_plurals (line 3080) | def test_plurals(self):
method test_ordinal_number (line 3097) | def test_ordinal_number(self):
method test_format_timeframe (line 3101) | def test_format_timeframe(self):
method test_format_relative_now (line 3105) | def test_format_relative_now(self):
method test_format_relative_past (line 3110) | def test_format_relative_past(self):
method test_format_relative_future (line 3115) | def test_format_relative_future(self):
method test_weekday (line 3120) | def test_weekday(self):
class TestDanishLocale (line 3127) | class TestDanishLocale:
method test_describe (line 3128) | def test_describe(self):
method test_plurals (line 3132) | def test_plurals(self):
method test_ordinal_number (line 3149) | def test_ordinal_number(self):
method test_format_timeframe (line 3153) | def test_format_timeframe(self):
method test_format_relative_now (line 3157) | def test_format_relative_now(self):
method test_format_relative_past (line 3162) | def test_format_relative_past(self):
method test_format_relative_future (line 3167) | def test_format_relative_future(self):
method test_weekday (line 3172) | def test_weekday(self):
class TestAmharicLocale (line 3179) | class TestAmharicLocale:
method test_format_timeframe (line 3180) | def test_format_timeframe(self):
method test_describe_am (line 3218) | def test_describe_am(self):
method test_format_relative_now (line 3229) | def test_format_relative_now(self):
method test_ordinal_number (line 3233) | def test_ordinal_number(self):
method test_format_relative_future (line 3236) | def test_format_relative_future(self):
method test_format_relative_past (line 3241) | def test_format_relative_past(self):
method test_weekday (line 3246) | def test_weekday(self):
class TestArmenianLocale (line 3253) | class TestArmenianLocale:
method test_describe (line 3254) | def test_describe(self):
method test_meridians_hy (line 3258) | def test_meridians_hy(self):
method test_format_timeframe (line 3264) | def test_format_timeframe(self):
method test_weekday (line 3305) | def test_weekday(self):
class TestUzbekLocale (line 3312) | class TestUzbekLocale:
method test_singles_mk (line 3313) | def test_singles_mk(self):
method test_describe_mk (line 3322) | def test_describe_mk(self):
method test_relative_mk (line 3342) | def test_relative_mk(self):
method test_plurals_mk (line 3373) | def test_plurals_mk(self):
class TestGreekLocale (line 3391) | class TestGreekLocale:
method test_format_relative_future (line 3392) | def test_format_relative_future(self):
method test_month_abbreviation (line 3397) | def test_month_abbreviation(self):
method test_format_timeframe (line 3400) | def test_format_timeframe(self):
class TestAfrikaansLocale (line 3408) | class TestAfrikaansLocale:
method test_timeframes (line 3409) | def test_timeframes(self):
method test_weekday (line 3437) | def test_weekday(self):
method test_format_relative_past (line 3445) | def test_format_relative_past(self):
method test_format_relative_future (line 3448) | def test_format_relative_future(self):
class TestAlgeriaTunisiaArabicLocale (line 3453) | class TestAlgeriaTunisiaArabicLocale:
method test_weekday (line 3454) | def test_weekday(self):
method test_format_relative_past (line 3462) | def test_format_relative_past(self):
method test_format_relative_future (line 3465) | def test_format_relative_future(self):
class TestAustrianLocale (line 3470) | class TestAustrianLocale:
method test_weekday (line 3471) | def test_weekday(self):
class TestBasqueLocale (line 3481) | class TestBasqueLocale:
method test_timeframes (line 3482) | def test_timeframes(self):
method test_weekday (line 3505) | def test_weekday(self):
method test_format_relative_past (line 3513) | def test_format_relative_past(self):
method test_format_relative_future (line 3516) | def test_format_relative_future(self):
class TestBelarusianLocale (line 3521) | class TestBelarusianLocale:
method test_timeframes (line 3522) | def test_timeframes(self):
method test_weekday (line 3545) | def test_weekday(self):
method test_format_relative_past (line 3553) | def test_format_relative_past(self):
method test_format_relative_future (line 3556) | def test_format_relative_future(self):
class TestLevantArabicLocale (line 3561) | class TestLevantArabicLocale:
method test_weekday (line 3562) | def test_weekday(self):
class TestMauritaniaArabicLocale (line 3569) | class TestMauritaniaArabicLocale:
method test_weekday (line 3570) | def test_weekday(self):
class TestMoroccoArabicLocale (line 3577) | class TestMoroccoArabicLocale:
method test_weekday (line 3578) | def test_weekday(self):
class TestRomanshLocale (line 3585) | class TestRomanshLocale:
method test_timeframes (line 3586) | def test_timeframes(self):
method test_weekday (line 3609) | def test_weekday(self):
method test_format_relative_past (line 3617) | def test_format_relative_past(self):
method test_format_relative_future (line 3620) | def test_format_relative_future(self):
class TestSlovenianLocale (line 3625) | class TestSlovenianLocale:
method test_timeframes (line 3626) | def test_timeframes(self):
method test_weekday (line 3649) | def test_weekday(self):
method test_format_relative_past (line 3657) | def test_format_relative_past(self):
method test_format_relative_future (line 3660) | def test_format_relative_future(self):
class TestUkrainianLocale (line 3665) | class TestUkrainianLocale:
method test_timeframes (line 3666) | def test_timeframes(self):
method test_weekday (line 3689) | def test_weekday(self):
method test_format_relative_past (line 3697) | def test_format_relative_past(self):
method test_format_relative_future (line 3700) | def test_format_relative_future(self):
class TestVietnameseLocale (line 3705) | class TestVietnameseLocale:
method test_timeframes (line 3706) | def test_timeframes(self):
method test_weekday (line 3732) | def test_weekday(self):
method test_format_relative_past (line 3740) | def test_format_relative_past(self):
method test_format_relative_future (line 3743) | def test_format_relative_future(self):
class TestCatalanLocale (line 3748) | class TestCatalanLocale:
method test_timeframes (line 3749) | def test_timeframes(self):
method test_weekday (line 3772) | def test_weekday(self):
method test_format_relative_past (line 3780) | def test_format_relative_past(self):
method test_format_relative_future (line 3783) | def test_format_relative_future(self):
FILE: tests/test_parser.py
class TestDateTimeParser (line 23) | class TestDateTimeParser:
method test_parse_multiformat (line 24) | def test_parse_multiformat(self, mocker):
method test_parse_multiformat_all_fail (line 46) | def test_parse_multiformat_all_fail(self, mocker):
method test_parse_multiformat_unself_expected_fail (line 64) | def test_parse_multiformat_unself_expected_fail(self, mocker):
method test_parse_token_nonsense (line 78) | def test_parse_token_nonsense(self):
method test_parse_token_invalid_meridians (line 83) | def test_parse_token_invalid_meridians(self):
method test_parser_no_caching (line 90) | def test_parser_no_caching(self, mocker):
method test_parser_1_line_caching (line 99) | def test_parser_1_line_caching(self, mocker):
method test_parser_multiple_line_caching (line 118) | def test_parser_multiple_line_caching(self, mocker):
method test_YY_and_YYYY_format_list (line 141) | def test_YY_and_YYYY_format_list(self):
method test_timestamp_format_list (line 157) | def test_timestamp_format_list(self):
class TestDateTimeParserParse (line 169) | class TestDateTimeParserParse:
method test_parse_list (line 170) | def test_parse_list(self, mocker):
method test_parse_unrecognized_token (line 181) | def test_parse_unrecognized_token(self, mocker):
method test_parse_parse_no_match (line 190) | def test_parse_parse_no_match(self):
method test_parse_separators (line 194) | def test_parse_separators(self):
method test_parse_numbers (line 198) | def test_parse_numbers(self):
method test_parse_am (line 205) | def test_parse_am(self):
method test_parse_year_two_digit (line 209) | def test_parse_year_two_digit(self):
method test_parse_timestamp (line 215) | def test_parse_timestamp(self):
method test_parse_negative_timestamp (line 252) | def test_parse_negative_timestamp(self):
method test_parse_expanded_timestamp (line 265) | def test_parse_expanded_timestamp(self):
method test_parse_names (line 293) | def test_parse_names(self):
method test_parse_pm (line 299) | def test_parse_pm(self):
method test_parse_tz_hours_only (line 316) | def test_parse_tz_hours_only(self):
method test_parse_tz_zz (line 321) | def test_parse_tz_zz(self):
method test_parse_tz_name_zzz (line 326) | def test_parse_tz_name_zzz(self, full_tz_name):
method test_parse_subsecond (line 343) | def test_parse_subsecond(self):
method test_parse_subsecond_rounding (line 382) | def test_parse_subsecond_rounding(self):
method test_parse_subsecond_rounding_overflow (line 408) | def test_parse_subsecond_rounding_overflow(self):
method test_parse_long_year (line 433) | def test_parse_long_year(self):
method test_parse_with_extra_words_at_start_and_end_invalid (line 443) | def test_parse_with_extra_words_at_start_and_end_invalid(self):
method test_parse_with_extra_words_at_start_and_end_valid (line 460) | def test_parse_with_extra_words_at_start_and_end_valid(self):
method test_parse_with_punctuation_fences (line 503) | def test_parse_with_punctuation_fences(self):
method test_parse_with_leading_and_trailing_whitespace (line 525) | def test_parse_with_leading_and_trailing_whitespace(self):
method test_parse_YYYY_DDDD (line 540) | def test_parse_YYYY_DDDD(self):
method test_parse_YYYY_DDD (line 548) | def test_parse_YYYY_DDD(self):
method test_parse_YYYY_MM_DDDD (line 557) | def test_parse_YYYY_MM_DDDD(self):
method test_parse_DDD_only (line 562) | def test_parse_DDD_only(self):
method test_parse_DDDD_only (line 566) | def test_parse_DDDD_only(self):
method test_parse_ddd_and_dddd (line 570) | def test_parse_ddd_and_dddd(self):
method test_parse_ddd_and_dddd_ignore_case (line 637) | def test_parse_ddd_and_dddd_ignore_case(self):
method test_parse_ddd_and_dddd_then_format (line 645) | def test_parse_ddd_and_dddd_then_format(self):
method test_parse_HH_24 (line 684) | def test_parse_HH_24(self):
method test_parse_W (line 719) | def test_parse_W(self):
method test_parse_normalize_whitespace (line 755) | def test_parse_normalize_whitespace(self):
class TestDateTimeParserRegex (line 784) | class TestDateTimeParserRegex:
method test_format_year (line 785) | def test_format_year(self):
method test_format_month (line 788) | def test_format_month(self):
method test_format_day (line 791) | def test_format_day(self):
method test_format_hour (line 794) | def test_format_hour(self):
method test_format_minute (line 797) | def test_format_minute(self):
method test_format_second (line 800) | def test_format_second(self):
method test_format_subsecond (line 803) | def test_format_subsecond(self):
method test_format_tz (line 813) | def test_format_tz(self):
method test_format_am_pm (line 816) | def test_format_am_pm(self):
method test_format_timestamp (line 819) | def test_format_timestamp(self):
method test_format_timestamp_milli (line 822) | def test_format_timestamp_milli(self):
method test_escape (line 825) | def test_escape(self):
method test_month_names (line 830) | def test_month_names(self):
method test_month_abbreviations (line 839) | def test_month_abbreviations(self):
method test_digits (line 848) | def test_digits(self):
method test_tz (line 860) | def test_tz(self):
method test_timestamp (line 877) | def test_timestamp(self):
method test_timestamp_milli (line 886) | def test_timestamp_milli(self):
method test_time (line 894) | def test_time(self):
class TestDateTimeParserISO (line 917) | class TestDateTimeParserISO:
method test_YYYY (line 918) | def test_YYYY(self):
method test_YYYY_DDDD (line 921) | def test_YYYY_DDDD(self):
method test_YYYY_DDDD_HH_mm_ssZ (line 945) | def test_YYYY_DDDD_HH_mm_ssZ(self):
method test_YYYY_MM_DDDD (line 954) | def test_YYYY_MM_DDDD(self):
method test_YYYY_MM (line 958) | def test_YYYY_MM(self):
method test_YYYY_MM_DD (line 964) | def test_YYYY_MM_DD(self):
method test_YYYY_MM_DDTHH_mmZ (line 970) | def test_YYYY_MM_DDTHH_mmZ(self):
method test_YYYY_MM_DDTHH_mm (line 975) | def test_YYYY_MM_DDTHH_mm(self):
method test_YYYY_MM_DDTHH (line 978) | def test_YYYY_MM_DDTHH(self):
method test_YYYY_MM_DDTHHZ (line 981) | def test_YYYY_MM_DDTHHZ(self):
method test_YYYY_MM_DDTHH_mm_ssZ (line 986) | def test_YYYY_MM_DDTHH_mm_ssZ(self):
method test_YYYY_MM_DDTHH_mm_ss (line 991) | def test_YYYY_MM_DDTHH_mm_ss(self):
method test_YYYY_MM_DD_HH_mmZ (line 996) | def test_YYYY_MM_DD_HH_mmZ(self):
method test_YYYY_MM_DD_HH_mm (line 1001) | def test_YYYY_MM_DD_HH_mm(self):
method test_YYYY_MM_DD_HH (line 1004) | def test_YYYY_MM_DD_HH(self):
method test_invalid_time (line 1007) | def test_invalid_time(self):
method test_YYYY_MM_DD_HH_mm_ssZ (line 1017) | def test_YYYY_MM_DD_HH_mm_ssZ(self):
method test_YYYY_MM_DD_HH_mm_ss (line 1022) | def test_YYYY_MM_DD_HH_mm_ss(self):
method test_YYYY_MM_DDTHH_mm_ss_S (line 1027) | def test_YYYY_MM_DDTHH_mm_ss_S(self):
method test_YYYY_MM_DDTHH_mm_ss_SZ (line 1061) | def test_YYYY_MM_DDTHH_mm_ss_SZ(self):
method test_W (line 1086) | def test_W(self):
method test_invalid_Z (line 1099) | def test_invalid_Z(self):
method test_parse_subsecond (line 1121) | def test_parse_subsecond(self):
method test_gnu_date (line 1144) | def test_gnu_date(self):
method test_isoformat (line 1156) | def test_isoformat(self):
method test_parse_iso_normalize_whitespace (line 1161) | def test_parse_iso_normalize_whitespace(self):
method test_parse_iso_with_leading_and_trailing_whitespace (line 1176) | def test_parse_iso_with_leading_and_trailing_whitespace(self):
method test_parse_iso_with_extra_words_at_start_and_end_invalid (line 1212) | def test_parse_iso_with_extra_words_at_start_and_end_invalid(self):
method test_iso8601_basic_format (line 1238) | def test_iso8601_basic_format(self):
method test_midnight_end_day (line 1281) | def test_midnight_end_day(self):
class TestTzinfoParser (line 1315) | class TestTzinfoParser:
method test_parse_local (line 1316) | def test_parse_local(self):
method test_parse_utc (line 1321) | def test_parse_utc(self):
method test_parse_utc_withoffset (line 1325) | def test_parse_utc_withoffset(self):
method test_parse_iso (line 1333) | def test_parse_iso(self):
method test_parse_str (line 1349) | def test_parse_str(self):
method test_parse_fails (line 1352) | def test_parse_fails(self):
class TestDateTimeParserMonthName (line 1358) | class TestDateTimeParserMonthName:
method test_shortmonth_capitalized (line 1359) | def test_shortmonth_capitalized(self):
method test_shortmonth_allupper (line 1362) | def test_shortmonth_allupper(self):
method test_shortmonth_alllower (line 1365) | def test_shortmonth_alllower(self):
method test_month_capitalized (line 1368) | def test_month_capitalized(self):
method test_month_allupper (line 1373) | def test_month_allupper(self):
method test_month_alllower (line 1378) | def test_month_alllower(self):
method test_localized_month_name (line 1383) | def test_localized_month_name(self):
method test_localized_month_abbreviation (line 1388) | def test_localized_month_abbreviation(self):
class TestDateTimeParserMeridians (line 1395) | class TestDateTimeParserMeridians:
method test_meridians_lowercase (line 1396) | def test_meridians_lowercase(self):
method test_meridians_capitalized (line 1405) | def test_meridians_capitalized(self):
method test_localized_meridians_lowercase (line 1414) | def test_localized_meridians_lowercase(self):
method test_localized_meridians_capitalized (line 1424) | def test_localized_meridians_capitalized(self):
method test_es_meridians (line 1435) | def test_es_meridians(self):
method test_fr_meridians (line 1447) | def test_fr_meridians(self):
class TestDateTimeParserMonthOrdinalDay (line 1456) | class TestDateTimeParserMonthOrdinalDay:
method test_english (line 1457) | def test_english(self):
method test_italian (line 1494) | def test_italian(self):
method test_spanish (line 1501) | def test_spanish(self):
method test_french (line 1506) | def test_french(self):
class TestDateTimeParserSearchDate (line 1523) | class TestDateTimeParserSearchDate:
method test_parse_search (line 1524) | def test_parse_search(self):
method test_parse_search_with_numbers (line 1529) | def test_parse_search_with_numbers(self):
method test_parse_search_with_names (line 1538) | def test_parse_search_with_names(self):
method test_parse_search_locale_with_names (line 1543) | def test_parse_search_locale_with_names(self):
method test_parse_search_fails (line 1554) | def test_parse_search_fails(self):
method test_escape (line 1558) | def test_escape(self):
class TestFuzzInput (line 1592) | class TestFuzzInput:
method test_no_match_group (line 1594) | def test_no_match_group(self):
method test_regex_module_error (line 1602) | def test_regex_module_error(self):
FILE: tests/test_util.py
class TestUtil (line 9) | class TestUtil:
method test_next_weekday (line 10) | def test_next_weekday(self):
method test_is_timestamp (line 39) | def test_is_timestamp(self):
method test_validate_ordinal (line 59) | def test_validate_ordinal(self):
method test_normalize_timestamp (line 116) | def test_normalize_timestamp(self):
method test_iso_gregorian (line 128) | def test_iso_gregorian(self):
FILE: tests/utils.py
function make_full_tz_list (line 8) | def make_full_tz_list():
function assert_datetime_equality (line 18) | def assert_datetime_equality(dt1, dt2, within=10):
function assert_timezone_equivalence (line 24) | def assert_timezone_equivalence(tz1, tz2, dt):
Condensed preview — 50 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (815K chars).
[
{
"path": ".github/FUNDING.yml",
"chars": 23,
"preview": "open_collective: arrow\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 739,
"preview": "---\nname: \"🐞 Bug Report\"\nabout: Find a bug? Create a report to help us improve.\ntitle: ''\nlabels: 'bug'\nassignees: ''\n-"
},
{
"path": ".github/ISSUE_TEMPLATE/documentation.md",
"chars": 408,
"preview": "---\nname: \"📚 Documentation\"\nabout: Find errors or problems in the docs (https://arrow.readthedocs.io)?\ntitle: ''\nlabels"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 387,
"preview": "---\nname: \"💡 Feature Request\"\nabout: Have an idea for a new feature or improvement?\ntitle: ''\nlabels: 'enhancement'\nass"
},
{
"path": ".github/dependabot.yml",
"chars": 118,
"preview": "version: 2\nupdates:\n - package-ecosystem: \"github-actions\"\n directory: \"/\"\n schedule:\n interval: \"weekly\"\n"
},
{
"path": ".github/pull_request_template.md",
"chars": 1117,
"preview": "## Pull Request Checklist\n\nThank you for taking the time to improve Arrow! Before submitting your pull request, please c"
},
{
"path": ".github/workflows/continuous_integration.yml",
"chars": 2626,
"preview": "name: tests\n\non:\n pull_request: # Run on all pull requests\n push: # Run only on pushes to master\n branches:\n -"
},
{
"path": ".github/workflows/release.yml",
"chars": 786,
"preview": "name: release\n\non:\n workflow_dispatch: # run manually\n push: # run on matching tags\n tags:\n - '*.*.*'\n\njobs:\n "
},
{
"path": ".gitignore",
"chars": 2747,
"preview": "README.rst.new\n\n# Small entry point file for debugging tasks\ntest.py\n\n# Byte-compiled / optimized / DLL files\n__pycache_"
},
{
"path": ".pre-commit-config.yaml",
"chars": 1651,
"preview": "default_language_version:\n python: python3\nrepos:\n - repo: https://github.com/pre-commit/pre-commit-hooks\n rev: v6."
},
{
"path": ".readthedocs.yaml",
"chars": 863,
"preview": "# Read the Docs configuration file for Sphinx projects\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html f"
},
{
"path": "CHANGELOG.rst",
"chars": 35527,
"preview": "Changelog\n=========\n\n1.4.0 (2025-10-18)\n------------------\n\n- [ADDED] Added ``week_start`` parameter to ``floor()`` and "
},
{
"path": "LICENSE",
"chars": 11341,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "Makefile",
"chars": 1155,
"preview": ".PHONY: auto test docs clean\n\nauto: build311\n\nbuild38: PYTHON_VER = python3.8\nbuild39: PYTHON_VER = python3.9\nbuild310: "
},
{
"path": "README.rst",
"chars": 5703,
"preview": "Arrow: Better dates & times for Python\n======================================\n\n.. start-inclusion-marker-do-not-remove\n\n"
},
{
"path": "arrow/__init__.py",
"chars": 928,
"preview": "from ._version import __version__\nfrom .api import get, now, utcnow\nfrom .arrow import Arrow\nfrom .factory import ArrowF"
},
{
"path": "arrow/_version.py",
"chars": 22,
"preview": "__version__ = \"1.4.0\"\n"
},
{
"path": "arrow/api.py",
"chars": 2735,
"preview": "\"\"\"\nProvides the default implementation of :class:`ArrowFactory <arrow.factory.ArrowFactory>`\nmethods for use as a modul"
},
{
"path": "arrow/arrow.py",
"chars": 65200,
"preview": "\"\"\"\nProvides the :class:`Arrow <arrow.arrow.Arrow>` class, an enhanced ``datetime``\nreplacement.\n\n\"\"\"\n\nimport calendar\ni"
},
{
"path": "arrow/constants.py",
"chars": 3117,
"preview": "\"\"\"Constants used internally in arrow.\"\"\"\n\nimport sys\nfrom datetime import datetime\nfrom typing import Final\n\n# datetime"
},
{
"path": "arrow/factory.py",
"chars": 11375,
"preview": "\"\"\"\nImplements the :class:`ArrowFactory <arrow.factory.ArrowFactory>` class,\nproviding factory methods for common :class"
},
{
"path": "arrow/formatter.py",
"chars": 5139,
"preview": "\"\"\"Provides the :class:`Arrow <arrow.formatter.DateTimeFormatter>` class, an improved formatter for datetimes.\"\"\"\n\nimpor"
},
{
"path": "arrow/locales.py",
"chars": 146036,
"preview": "\"\"\"Provides internationalization for arrow in over 60 languages and dialects.\"\"\"\n\nfrom math import trunc\nfrom typing imp"
},
{
"path": "arrow/parser.py",
"chars": 33363,
"preview": "\"\"\"Provides the :class:`Arrow <arrow.parser.DateTimeParser>` class, a better way to parse datetime strings.\"\"\"\n\nimport r"
},
{
"path": "arrow/py.typed",
"chars": 0,
"preview": ""
},
{
"path": "arrow/util.py",
"chars": 3625,
"preview": "\"\"\"Helpful functions used internally within arrow.\"\"\"\n\nimport datetime\nfrom typing import Any, Optional\n\nfrom dateutil.r"
},
{
"path": "docs/Makefile",
"chars": 634,
"preview": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line, and also\n# from the "
},
{
"path": "docs/api-guide.rst",
"chars": 453,
"preview": "***************************************\nAPI Guide\n***************************************\n\n:mod:`arrow.arrow`\n=========="
},
{
"path": "docs/conf.py",
"chars": 1598,
"preview": "# mypy: ignore-errors\n# -- Path setup --------------------------------------------------------------\n\nimport os\nimport s"
},
{
"path": "docs/getting-started.rst",
"chars": 292,
"preview": "***************************************\nGetting started\n***************************************\n\nAssuming you have Pytho"
},
{
"path": "docs/guide.rst",
"chars": 19954,
"preview": "***************************************\nUser’s Guide\n***************************************\n\n\nCreation\n~~~~~~~~\n\nGet 'n"
},
{
"path": "docs/index.rst",
"chars": 571,
"preview": "Arrow: Better dates & times for Python\n======================================\n\nRelease v\\ |release| (`Installation`_) (`"
},
{
"path": "docs/make.bat",
"chars": 760,
"preview": "@ECHO OFF\n\npushd %~dp0\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-bu"
},
{
"path": "docs/releases.rst",
"chars": 142,
"preview": "***************************************\nRelease History\n***************************************\n\n.. _releases:\n\n.. inclu"
},
{
"path": "pyproject.toml",
"chars": 1827,
"preview": "[build-system]\nrequires = [\"flit_core >=3.2,<4\"]\nbuild-backend = \"flit_core.buildapi\"\n\n[project]\nname = \"arrow\"\nauthors "
},
{
"path": "requirements/requirements-docs.txt",
"chars": 105,
"preview": "-r requirements.txt\ndoc8\nsphinx>=7.0.0\nsphinx-autobuild\nsphinx-autodoc-typehints\nsphinx_rtd_theme>=1.3.0\n"
},
{
"path": "requirements/requirements-tests.txt",
"chars": 136,
"preview": "-r requirements.txt\ndateparser==1.*\npre-commit\npytest\npytest-cov\npytest-mock\npytz==2025.2\nsimplejson==3.*\ntypes-python-d"
},
{
"path": "requirements/requirements.txt",
"chars": 99,
"preview": "backports.zoneinfo==0.2.1;python_version<'3.9'\npython-dateutil>=2.7.0\ntzdata;python_version>='3.9'\n"
},
{
"path": "setup.cfg",
"chars": 689,
"preview": "[mypy]\npython_version = 3.11\n\nshow_error_codes = True\npretty = True\n\nallow_any_expr = True\nallow_any_decorated = True\nal"
},
{
"path": "tests/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "tests/conftest.py",
"chars": 2083,
"preview": "from datetime import datetime\n\nimport pytest\n\ntry:\n from zoneinfo import ZoneInfo\nexcept ImportError:\n from backpo"
},
{
"path": "tests/test_api.py",
"chars": 770,
"preview": "import arrow\n\n\nclass TestModule:\n def test_get(self, mocker):\n mocker.patch(\"arrow.api._factory.get\", return_v"
},
{
"path": "tests/test_arrow.py",
"chars": 109863,
"preview": "try:\n from zoneinfo import ZoneInfo\nexcept ImportError:\n from backports.zoneinfo import ZoneInfo\n\nimport pickle\nim"
},
{
"path": "tests/test_factory.py",
"chars": 13217,
"preview": "import time\nfrom datetime import date, datetime, timezone\nfrom decimal import Decimal\n\nimport pytest\nfrom dateutil impor"
},
{
"path": "tests/test_formatter.py",
"chars": 9553,
"preview": "try:\n from zoneinfo import ZoneInfo\nexcept ImportError:\n from backports.zoneinfo import ZoneInfo\n\nfrom datetime im"
},
{
"path": "tests/test_locales.py",
"chars": 190849,
"preview": "import pytest\n\nfrom arrow import arrow, locales\n\n\n@pytest.mark.usefixtures(\"lang_locales\")\nclass TestLocaleValidation:\n "
},
{
"path": "tests/test_parser.py",
"chars": 61837,
"preview": "import calendar\nimport os\nimport time\nfrom datetime import datetime, timedelta, timezone\n\nimport pytest\nfrom dateutil im"
},
{
"path": "tests/test_util.py",
"chars": 4552,
"preview": "import time\nfrom datetime import datetime, timezone\n\nimport pytest\n\nfrom arrow import util\n\n\nclass TestUtil:\n def tes"
},
{
"path": "tests/utils.py",
"chars": 1370,
"preview": "try:\n import zoneinfo\nexcept ImportError:\n from backports import zoneinfo\nfrom dateutil.zoneinfo import get_zonefi"
},
{
"path": "tox.ini",
"chars": 1328,
"preview": "[tox]\nminversion = 3.18.0\nenvlist = py{py3,38,39,310,311,312,313,314}\nskip_missing_interpreters = true\n\n[gh-actions]\npyt"
}
]
About this extraction
This page contains the full source code of the arrow-py/arrow GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 50 files (741.6 KB), approximately 213.5k tokens, and a symbol index with 1115 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.