Skip to content

Added ds_format_locale method in macros which allows localizing datetime formatting using Babel #40746

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 30 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
db87642
refactor: Added locale parameter to the ds_format method in macros to…
davidblain-infrabel Jul 12, 2024
137da5b
refactor: Improved test cases for ds_format in macros
davidblain-infrabel Jul 12, 2024
62211e8
Merge branch 'main' into feature/localize-macro-ds-format
dabla Jul 12, 2024
adfded8
refactor: Fixed static checks
dabla Jul 12, 2024
7c2c1bc
refactor: Updated example docstring ds_format in macros
dabla Jul 12, 2024
2091d34
refactor: Fixed static check on docstring of ds_format macro
davidblain-infrabel Jul 12, 2024
03503e5
refactor: Added Dutch month named 'juli' as it is being asserted in t…
davidblain-infrabel Jul 12, 2024
3c04ef6
refactor: Removed call to getdefaultlocale in apply_locale as it's ba…
davidblain-infrabel Jul 12, 2024
959c079
refactor: Fixed test helpers for apply_locale
davidblain-infrabel Jul 12, 2024
e0608b2
Merge branch 'main' into feature/localize-macro-ds-format
dabla Jul 12, 2024
e1722a8
Merge branch 'main' into feature/localize-macro-ds-format
dabla Jul 12, 2024
0c2e603
refactor: Updated docstrings and added versionadded directive for loc…
davidblain-infrabel Jul 13, 2024
3184964
Merge branch 'main' into feature/localize-macro-ds-format
dabla Jul 13, 2024
7a61453
refactor: Reordered the juli word
davidblain-infrabel Jul 13, 2024
17174bf
refactor: Skip test if locale is not supported
davidblain-infrabel Jul 13, 2024
c4d7e8f
Merge branch 'main' into feature/localize-macro-ds-format
dabla Jul 15, 2024
9cdc5ff
Merge branch 'main' into feature/localize-macro-ds-format
dabla Jul 15, 2024
3b605db
refactor: Removed failing test case
davidblain-infrabel Jul 15, 2024
6861fc9
refactor: Added separate ds_format_locale macro method which allows t…
davidblain-infrabel Jul 15, 2024
264e003
Merge branch 'main' into feature/localize-macro-ds-format
dabla Jul 15, 2024
40ff131
refactor: Reformatted ds_format and ds_format_locale macro
davidblain-infrabel Jul 15, 2024
64e1b78
refactor: Reorganized imports of macros
davidblain-infrabel Jul 15, 2024
aecead4
refactor: Try to ignore spellcheck for Babel format example in docstr…
davidblain-infrabel Jul 15, 2024
8aa5076
Merge branch 'main' into feature/localize-macro-ds-format
dabla Jul 15, 2024
8187b3c
Merge branch 'main' into feature/localize-macro-ds-format
dabla Jul 15, 2024
c10ef77
Merge branch 'main' into feature/localize-macro-ds-format
dabla Jul 16, 2024
eb0747e
Merge branch 'main' into feature/localize-macro-ds-format
dabla Jul 16, 2024
a06e015
Merge branch 'main' into feature/localize-macro-ds-format
dabla Jul 16, 2024
f075f17
Merge branch 'main' into feature/localize-macro-ds-format
dabla Jul 17, 2024
2e62fea
Merge branch 'main' into feature/localize-macro-ds-format
dabla Jul 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 36 additions & 3 deletions airflow/macros/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
from typing import TYPE_CHECKING, Any

import dateutil # noqa: F401
from babel import Locale
from babel.dates import LC_TIME, format_datetime

import airflow.utils.yaml as yaml # noqa: F401
from airflow.utils.deprecation_tools import add_deprecated_classes
Expand Down Expand Up @@ -64,18 +66,49 @@ def ds_format(ds: str, input_format: str, output_format: str) -> str:
"""
Output datetime string in a given format.

:param ds: input string which contains a date
:param input_format: input string format. E.g. %Y-%m-%d
:param output_format: output string format E.g. %Y-%m-%d
:param ds: Input string which contains a date.
:param input_format: Input string format (e.g., '%Y-%m-%d').
:param output_format: Output string format (e.g., '%Y-%m-%d').

>>> ds_format("2015-01-01", "%Y-%m-%d", "%m-%d-%y")
'01-01-15'
>>> ds_format("1/5/2015", "%m/%d/%Y", "%Y-%m-%d")
'2015-01-05'
>>> ds_format("12/07/2024", "%d/%m/%Y", "%A %d %B %Y", "en_US")
'Friday 12 July 2024'
"""
return datetime.strptime(str(ds), input_format).strftime(output_format)


def ds_format_locale(
ds: str, input_format: str, output_format: str, locale: Locale | str | None = None
) -> str:
"""
Output localized datetime string in a given Babel format.

:param ds: Input string which contains a date.
:param input_format: Input string format (e.g., '%Y-%m-%d').
:param output_format: Output string Babel format (e.g., `yyyy-MM-dd`).
:param locale: Locale used to format the output string (e.g., 'en_US').
If locale not specified, default LC_TIME will be used and if that's also not available,
'en_US' will be used.

>>> ds_format("2015-01-01", "%Y-%m-%d", "MM-dd-yy")
'01-01-15'
>>> ds_format("1/5/2015", "%m/%d/%Y", "yyyy-MM-dd")
'2015-01-05'
>>> ds_format("12/07/2024", "%d/%m/%Y", "EEEE dd MMMM yyyy", "en_US")
'Friday 12 July 2024'

.. versionadded:: 2.10.0
"""
return format_datetime(
datetime.strptime(str(ds), input_format),
format=output_format,
locale=locale or LC_TIME or Locale("en_US"),
)


def datetime_diff_for_humans(dt: Any, since: DateTime | None = None) -> str:
"""
Return a human-readable/approximate difference between datetimes.
Expand Down
1 change: 1 addition & 0 deletions docs/spelling_wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,7 @@ Json
json
jsonl
jthomas
juli
Jupyter
jupyter
jupytercmd
Expand Down
20 changes: 20 additions & 0 deletions tests/macros/test_macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,26 @@ def test_ds_format(ds, input_format, output_format, expected):
assert result == expected


@pytest.mark.parametrize(
"ds, input_format, output_format, locale, expected",
[
("2015-01-02", "%Y-%m-%d", "MM-dd-yy", None, "01-02-15"),
("2015-01-02", "%Y-%m-%d", "yyyy-MM-dd", None, "2015-01-02"),
("1/5/2015", "%m/%d/%Y", "MM-dd-yy", None, "01-05-15"),
("1/5/2015", "%m/%d/%Y", "yyyy-MM-dd", None, "2015-01-05"),
("12/07/2024", "%d/%m/%Y", "EEEE dd MMMM yyyy", "en_US", "Friday 12 July 2024"),
("12/07/2024", "%d/%m/%Y", "EEEE dd MMMM yyyy", "nl_BE", "vrijdag 12 juli 2024"),
(lazy_object_proxy.Proxy(lambda: "2015-01-02"), "%Y-%m-%d", "MM-dd-yy", None, "01-02-15"),
(lazy_object_proxy.Proxy(lambda: "2015-01-02"), "%Y-%m-%d", "yyyy-MM-dd", None, "2015-01-02"),
(lazy_object_proxy.Proxy(lambda: "1/5/2015"), "%m/%d/%Y", "MM-dd-yy", None, "01-05-15"),
(lazy_object_proxy.Proxy(lambda: "1/5/2015"), "%m/%d/%Y", "yyyy-MM-dd", None, "2015-01-05"),
],
)
def test_ds_format_locale(ds, input_format, output_format, locale, expected):
result = macros.ds_format_locale(ds, input_format, output_format, locale)
assert result == expected


@pytest.mark.parametrize(
"dt, since, expected",
[
Expand Down