From c4d4d0a218cc2889a8ef0e2932e8e5368208d53b Mon Sep 17 00:00:00 2001 From: MosheEichler Date: Sun, 6 Aug 2023 15:56:25 +0300 Subject: [PATCH] add support for Elasticsearch datetime format --- arrow/__init__.py | 2 ++ arrow/formatter.py | 9 +++++---- tests/test_formatter.py | 7 +++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/arrow/__init__.py b/arrow/__init__.py index bc5970970..e167ef72b 100644 --- a/arrow/__init__.py +++ b/arrow/__init__.py @@ -13,6 +13,7 @@ FORMAT_RFC3339, FORMAT_RSS, FORMAT_W3C, + FORMAT_ES, ) from .parser import ParserError @@ -35,5 +36,6 @@ "FORMAT_RFC3339", "FORMAT_RSS", "FORMAT_W3C", + "FORMAT_ES", "ParserError", ] diff --git a/arrow/formatter.py b/arrow/formatter.py index 728bea1aa..9e44f9ea8 100644 --- a/arrow/formatter.py +++ b/arrow/formatter.py @@ -26,6 +26,7 @@ FORMAT_RFC3339: Final[str] = "YYYY-MM-DD HH:mm:ssZZ" FORMAT_RSS: Final[str] = "ddd, DD MMM YYYY HH:mm:ss Z" FORMAT_W3C: Final[str] = "YYYY-MM-DD HH:mm:ssZZ" +FORMAT_ES: Final[str] = "yyyy-MM-dd HH:mm:ss.SSSZ" class DateTimeFormatter: @@ -35,7 +36,7 @@ class DateTimeFormatter: # emulated in Python's re library, see https://stackoverflow.com/a/13577411/2701578 _FORMAT_RE: Final[Pattern[str]] = re.compile( - r"(\[(?:(?=(?P[^]]))(?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)" + r"(\[(?:(?=(?P[^]]))(?P=literal))*\]|YYY?Y?|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 @@ -56,9 +57,9 @@ 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": + if token in ("YYYY", "yyyy"): return self.locale.year_full(dt.year) - if token == "YY": + if token in ("YY", "yy"): return self.locale.year_abbreviation(dt.year) if token == "MMMM": @@ -74,7 +75,7 @@ def _format_token(self, dt: datetime, token: Optional[str]) -> Optional[str]: return f"{dt.timetuple().tm_yday:03d}" if token == "DDD": return f"{dt.timetuple().tm_yday}" - if token == "DD": + if token in ("DD", "dd"): return f"{dt.day:02d}" if token == "D": return f"{dt.day}" diff --git a/tests/test_formatter.py b/tests/test_formatter.py index 06831f1e0..b2a8297b4 100644 --- a/tests/test_formatter.py +++ b/tests/test_formatter.py @@ -15,6 +15,7 @@ FORMAT_RFC3339, FORMAT_RSS, FORMAT_W3C, + FORMAT_ES, ) from .utils import make_full_tz_list @@ -278,3 +279,9 @@ def test_w3c(self): self.formatter.format(self.datetime, FORMAT_W3C) == "1975-12-25 14:15:16-05:00" ) + + def test_elasticsearch(self): + assert ( + self.formatter.format(self.datetime, FORMAT_ES) + == "1975-12-25 14:15:16.000-0500" + )