This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 6058014559 Added ds_format_locale method in macros which allows 
localizing datetime formatting using Babel (#40746)
6058014559 is described below

commit 6058014559f6f891b1d526daa6fa61e90841757b
Author: David Blain <[email protected]>
AuthorDate: Wed Jul 17 17:36:12 2024 +0200

    Added ds_format_locale method in macros which allows localizing datetime 
formatting using Babel (#40746)
    
    
    
    ---------
    
    Co-authored-by: David Blain <[email protected]>
---
 airflow/macros/__init__.py  | 39 ++++++++++++++++++++++++++++++++++++---
 docs/spelling_wordlist.txt  |  1 +
 tests/macros/test_macros.py | 20 ++++++++++++++++++++
 3 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/airflow/macros/__init__.py b/airflow/macros/__init__.py
index cf0e5a3ef9..b18984b94e 100644
--- a/airflow/macros/__init__.py
+++ b/airflow/macros/__init__.py
@@ -25,6 +25,8 @@ from random import random  # noqa: F401
 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
@@ -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.
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index 5b1dda6949..99589be246 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -878,6 +878,7 @@ Json
 json
 jsonl
 jthomas
+juli
 Jupyter
 jupyter
 jupytercmd
diff --git a/tests/macros/test_macros.py b/tests/macros/test_macros.py
index 76ea22dd92..5dc0108ae0 100644
--- a/tests/macros/test_macros.py
+++ b/tests/macros/test_macros.py
@@ -59,6 +59,26 @@ def test_ds_format(ds, input_format, output_format, 
expected):
     assert result == expected
 
 
[email protected](
+    "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",
     [

Reply via email to