Add default parameter to as_datetime template function/filter (#107229)
* improve as_datetime * Improve `as_datetime` Jinja filter/function * review * resolve more review items * change test for datetime input * Update docstring * update docstrings for tests * remove whitespace * only_default * Update do string and comment * improve comment * Adjust comment --------- Co-authored-by: Martin Hjelmare <marhje52@gmail.com>pull/109066/head
parent
be8af7bea3
commit
b386960661
|
@ -1836,14 +1836,24 @@ def forgiving_as_timestamp(value, default=_SENTINEL):
|
|||
return default
|
||||
|
||||
|
||||
def as_datetime(value):
|
||||
def as_datetime(value: Any, default: Any = _SENTINEL) -> Any:
|
||||
"""Filter and to convert a time string or UNIX timestamp to datetime object."""
|
||||
try:
|
||||
# Check for a valid UNIX timestamp string, int or float
|
||||
timestamp = float(value)
|
||||
return dt_util.utc_from_timestamp(timestamp)
|
||||
except ValueError:
|
||||
return dt_util.parse_datetime(value)
|
||||
except (ValueError, TypeError):
|
||||
# Try to parse datetime string to datetime object
|
||||
try:
|
||||
return dt_util.parse_datetime(value, raise_on_error=True)
|
||||
except (ValueError, TypeError):
|
||||
if default is _SENTINEL:
|
||||
# Return None on string input
|
||||
# to ensure backwards compatibility with HA Core 2024.1 and before.
|
||||
if isinstance(value, str):
|
||||
return None
|
||||
raise_no_default("as_datetime", value)
|
||||
return default
|
||||
|
||||
|
||||
def as_timedelta(value: str) -> timedelta | None:
|
||||
|
|
|
@ -1151,7 +1151,6 @@ def test_as_datetime(hass: HomeAssistant, input) -> None:
|
|||
expected = dt_util.parse_datetime(input)
|
||||
if expected is not None:
|
||||
expected = str(expected)
|
||||
|
||||
assert (
|
||||
template.Template(f"{{{{ as_datetime('{input}') }}}}", hass).async_render()
|
||||
== expected
|
||||
|
@ -1162,34 +1161,64 @@ def test_as_datetime(hass: HomeAssistant, input) -> None:
|
|||
)
|
||||
|
||||
|
||||
def test_as_datetime_from_timestamp(hass: HomeAssistant) -> None:
|
||||
"""Test converting a UNIX timestamp to a date object."""
|
||||
tests = [
|
||||
@pytest.mark.parametrize(
|
||||
("input", "output"),
|
||||
[
|
||||
(1469119144, "2016-07-21 16:39:04+00:00"),
|
||||
(1469119144.0, "2016-07-21 16:39:04+00:00"),
|
||||
(-1, "1969-12-31 23:59:59+00:00"),
|
||||
]
|
||||
for input, output in tests:
|
||||
# expected = dt_util.parse_datetime(input)
|
||||
if output is not None:
|
||||
output = str(output)
|
||||
],
|
||||
)
|
||||
def test_as_datetime_from_timestamp(
|
||||
hass: HomeAssistant,
|
||||
input: int | float,
|
||||
output: str,
|
||||
) -> None:
|
||||
"""Test converting a UNIX timestamp to a date object."""
|
||||
assert (
|
||||
template.Template(f"{{{{ as_datetime({input}) }}}}", hass).async_render()
|
||||
== output
|
||||
)
|
||||
assert (
|
||||
template.Template(f"{{{{ {input} | as_datetime }}}}", hass).async_render()
|
||||
== output
|
||||
)
|
||||
assert (
|
||||
template.Template(f"{{{{ as_datetime('{input}') }}}}", hass).async_render()
|
||||
== output
|
||||
)
|
||||
assert (
|
||||
template.Template(f"{{{{ '{input}' | as_datetime }}}}", hass).async_render()
|
||||
== output
|
||||
)
|
||||
|
||||
assert (
|
||||
template.Template(f"{{{{ as_datetime({input}) }}}}", hass).async_render()
|
||||
== output
|
||||
)
|
||||
assert (
|
||||
template.Template(f"{{{{ {input} | as_datetime }}}}", hass).async_render()
|
||||
== output
|
||||
)
|
||||
assert (
|
||||
template.Template(f"{{{{ as_datetime('{input}') }}}}", hass).async_render()
|
||||
== output
|
||||
)
|
||||
assert (
|
||||
template.Template(f"{{{{ '{input}' | as_datetime }}}}", hass).async_render()
|
||||
== output
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("input", "default", "output"),
|
||||
[
|
||||
(1469119144, 123, "2016-07-21 16:39:04+00:00"),
|
||||
('"invalid"', ["default output"], ["default output"]),
|
||||
(["a", "list"], 0, 0),
|
||||
({"a": "dict"}, None, None),
|
||||
],
|
||||
)
|
||||
def test_as_datetime_default(
|
||||
hass: HomeAssistant, input: Any, default: Any, output: str
|
||||
) -> None:
|
||||
"""Test invalid input and return default value."""
|
||||
|
||||
assert (
|
||||
template.Template(
|
||||
f"{{{{ as_datetime({input}, default={default}) }}}}", hass
|
||||
).async_render()
|
||||
== output
|
||||
)
|
||||
assert (
|
||||
template.Template(
|
||||
f"{{{{ {input} | as_datetime({default}) }}}}", hass
|
||||
).async_render()
|
||||
== output
|
||||
)
|
||||
|
||||
|
||||
def test_as_local(hass: HomeAssistant) -> None:
|
||||
|
|
Loading…
Reference in New Issue