From b86a1ece010d029d3ea7ddebb9cc5d56673ee889 Mon Sep 17 00:00:00 2001 From: Charles Spirakis Date: Fri, 6 May 2016 18:33:46 -0700 Subject: [PATCH] Allow conversion from date strings to "unix" timestamp. (#1985) "unix" timestamp is number of seconds since Jan 1, 1970 UTC. This allows scripts that use templates to generate time deltas in seconds if desired from state attributes such as last_updated. Some examples: timestamp now is {{ as_timestamp(now) }} timstamp of last change is {{ as_timestamp(states.binary_sensor.garage_door.last_changed) }} seconds since last change is {{ as_timestamp(now) - as_timestamp(states.binary_sensor.garage_door.last_changed) }} --- homeassistant/helpers/template.py | 1 + homeassistant/util/dt.py | 12 ++++++++++++ tests/util/test_dt.py | 13 +++++++++++++ 3 files changed, 26 insertions(+) diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index b072f1b2df7..8e039432728 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -56,6 +56,7 @@ def render(hass, template, variables=None, **kwargs): 'now': dt_util.as_local(utcnow), 'states': AllStates(hass), 'utcnow': utcnow, + 'as_timestamp': dt_util.as_timestamp, }).render(kwargs).strip() except jinja2.TemplateError as err: raise TemplateError(err) diff --git a/homeassistant/util/dt.py b/homeassistant/util/dt.py index fbd962b3e45..bbcefa54fac 100644 --- a/homeassistant/util/dt.py +++ b/homeassistant/util/dt.py @@ -1,4 +1,5 @@ """Provides helper methods to handle the time in HA.""" +import calendar import datetime as dt import re @@ -59,6 +60,17 @@ def as_utc(dattim): return dattim.astimezone(UTC) +def as_timestamp(dt_value): + """Convert a date/time into a unix time (seconds since 1970).""" + if hasattr(dt_value, "utctimetuple"): + parsed_dt = dt_value + else: + parsed_dt = parse_datetime(str(dt_value)) + if not parsed_dt: + raise ValueError("not a valid date/time.") + return calendar.timegm(parsed_dt.utctimetuple()) + + def as_local(dattim): """Convert a UTC datetime object to local time zone.""" if dattim.tzinfo == DEFAULT_TIME_ZONE: diff --git a/tests/util/test_dt.py b/tests/util/test_dt.py index c98359f3416..da5b56d42a9 100644 --- a/tests/util/test_dt.py +++ b/tests/util/test_dt.py @@ -107,6 +107,19 @@ class TestDateUtil(unittest.TestCase): datetime(1986, 7, 9, tzinfo=dt_util.UTC), dt_util.utc_from_timestamp(521251200)) + def test_as_timestamp(self): + """Test as_timestamp method.""" + ts = 1462401234 + utc_dt = dt_util.utc_from_timestamp(ts) + self.assertEqual(ts, dt_util.as_timestamp(utc_dt)) + utc_iso = utc_dt.isoformat() + self.assertEqual(ts, dt_util.as_timestamp(utc_iso)) + + # confirm the ability to handle a string passed in + delta = dt_util.as_timestamp("2016-01-01 12:12:12") + delta -= dt_util.as_timestamp("2016-01-01 12:12:11") + self.assertEquals(1, delta) + def test_parse_datetime_converts_correctly(self): """Test parse_datetime converts strings.""" assert \