NOTE: I’ve tried to make all of these posts able to be copied as is into the template editor and work.
Due to some of the examples I’ve included you will get errors when you copy this post until you make corrections and use your correct entities in those examples.
I’ll annotate those sections that need to be modified in bold and with a “@@”.
–
The Unix Epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1 00:00:00
as_timestamp() - converts a properly formatted date/time string to a Unix Epoch representation.
time (GMT) = 2018-12-14 19:57:27 (UTC)
time (my time zone in UTC representation): 2018-12-14T19:57:27-05:00
time (my time zone local representation) : 2018-12-14 14:57:27
time as Epoch timestamp: 1544817447
–
A unix date/time string requires a correct format for the conversion algorithms to work correctly.
For example, here are time and date strings that won’t work:
time = 07:30
Set time as a string = time_string = ‘07:30’
{%- set time_string = '07:30' %}
time_string = {{ time_string }}
time_string as a timestamp = {{ as_timestamp(time_string) }} <== Doesn't work :(
–
date = 2018-12-12
Set date as a string = date_string = ‘2018-12-12’
{%- set date_string = '2018-12-12' %}
date as a string = {{ date_string }}
date_string as a timestamp = {{ as_timestamp(date_string) }} <== Doesn't work :(
–
A correct date/time string requires at least the following format:
date/time = 2008-02-09 21:00:00 (as local date/time)
Set date/time 1 as a string = good_time_string = ‘2008-02-09 21:00’
{%- set good_time_string = '2008-02-09 21:00' %}
Properly formatted date/time 1 as string = {{ good_time_string }}
Properly formatted date/time 1 as a timestamp = {{ as_timestamp(good_time_string) }} <== Works! :)
–
Or this will also work:
date/time = 2018-12-11T12:24:32.00+00:00 (as UTC date/time)
(This is the string format used in the attributes of date/time objects in HA. HOWEVER: This is not, what I will call, a true UNIX “datetime object” as used in the later sections. I’m not sure what the correct terminology is tho.)
The “+00:00” (or -00:00) is the UTC offset for your local timezone and is an addition to the hour:minute which will be adjusted when converted to local date/time (NOTE: “+00:00:00” won’t work)
Set date/time 2 as a string = good_time_string_UTC = ‘2018-12-11T12:24:32.00-00:00’
{%- set good_time_string_UTC = '2018-12-11T12:24:32.00-00:00' %}
Properly formatted date/time 2 as string = {{ good_time_string_UTC }} (UTC)
Properly formatted date/time 2 as timestamp = {{ as_timestamp(good_time_string_UTC) }} (UTC)
–
timestamp_custom() - converts a UNIX Epoch timestamp into a custom date/time string = unix_epoch_timestamp|timestamp_custom(format)
A custom time stamp can be used to represent the date and/or time in any format you want by using the time format directives from post 2.
date/time 1 as a custom timestamp = {{ as_timestamp(good_time_string)|timestamp_custom ('%Y/%m/%d %H%M') }}
When custom timestamp is used you can specify whether it gets converted to local or stays in UTC by inserting “, true” or “, false” to the end of the format section (true is default):
date/time 2 as custom local timestamp = {{ as_timestamp(good_time_string_UTC)|timestamp_custom ('%Y/%m/%d %H%M') }} (local)
date/time 2 as custom UTC timestamp = {{ as_timestamp(good_time_string_UTC)|timestamp_custom ('%Y/%m/%d %H%M', false) }} (UTC)
Or you can specify a default local/UTC format using the following filters:
date/time 2 as local timestamp = {{ as_timestamp(good_time_string_UTC)|timestamp_local }} (local)
date/time 2 as UTC timestamp = {{ as_timestamp(good_time_string_UTC)|timestamp_utc }} (UTC)
Add %z to display UTC offset of the above custom timestamp:
date/time 2 as UTC representation = {{ as_timestamp(good_time_string_UTC)|timestamp_custom ('%Y/%m/%d %H%M %z') }}
Next, since a UNIX Epoch timestamp is just an integer or floating point number then you can use pretty much any true number (not a number represented by a string) and convert it to a time string using timestmp_custom():
1223366 as a custom timestamp = {{ 1223366|timestamp_custom ('%Y/%m/%d %H%M') }}
–
Since a UNIX Epoch time stamp are just the number of seconds since a specific date then we can use that information to then manipulate date/time mathematically.
For example, to add 1 hour (3600 seconds) to the time above:
date/time 2 + 3600 seconds = {{ (as_timestamp(good_time_string_UTC) + 3600)|timestamp_custom ('%Y/%m/%d %H%M') }}
–
@@ The examples in this section will work as long as you pick an entity_id that includes an attribute that contains a time value. You can simply just pick any automation or script that has run recently:
Example 2
To find the number of hours since the last time a script was triggered:
The current time is - {{ now() }} (local time)
The script was last triggered - {{ states.script.garage_lights_timer.attributes.last_triggered }} (UTC time)
now() as a timestamp = {{ as_timestamp(now()) }}
One of my scripts "last_triggered" attribute as a timestamp = {{ as_timestamp(states.script.garage_lights_timer.attributes.last_triggered) }}
{{ as_timestamp(now()) }} - {{ as_timestamp(states.script.garage_lights_timer.attributes.last_triggered) }} = {{ ( (as_timestamp(now()) - as_timestamp(states.script.garage_lights_timer.attributes.last_triggered))) | int }} seconds
Therefor, the script was triggered {{ ( (as_timestamp(now()) - as_timestamp(states.script.garage_lights_timer.attributes.last_triggered)) / 3600 ) | round(2) }} hours ago.
/@@
–
@@ The following section uses current values based on the sensors created by the Time & Date component in HA @@
Here are examples using HA entities in date/time calculations:
date sensor = {{ states.sensor.date.state }}
date sensor as timestamp = {{ as_timestamp(states.sensor.date.state) }} ==> doesn't work
time sensor = {{ states.sensor.time.state }}
date + time sensor (concatenated) = {{ states.sensor.date.state + states.sensor.time.state }}
date + time sensor (concatenated) as timestamp = {{ as_timestamp(states.sensor.date.state + states.sensor.time.state) }} <== Doesn't work :(
Notice that above ends up not working because just adding them together doesn’t result in a properly formatted date/time string.
To do that you need to create it in the following way:
date + time sensor (concatenated with a space) = {{ states.sensor.date.state + ' ' + states.sensor.time.state }}
date + time sensor as timestamp = {{ as_timestamp(states.sensor.date.state + ' ' + states.sensor.time.state) }} <== Works! :)
/@@
–
This is an example using timestamps to set a sensor for the time to leave for work.
The calculation checks to see if the next leave time is today but after the current time.
If it is then it sets the leave time to today at the set time.
If the next leave time is before the current time it sets the next leave time to tomorrow at the set time.
If the next leave time is tomorrow it then checks if tomorrow is a Saturday or Sunday and if yes then it sets the leave time for the next Monday.
This exercise was taken from this thread (Remaining time until next leave to work) and is what inspired me to start trying to dig in and learn this stuff.
now = {{ now() }}
Set current date & time to now as a timestamp:
{%- set current_date_time = as_timestamp(now()) %}
current_date_time as timestamp = {{ current_date_time }}
Then use custom_timestamp to extract the day of the week (0-6) as a string value:
current day of week = {{ current_date_time|timestamp_custom('%w') }}
Set desired time to leave for work = leave_time = 06:00
{%- set leave_time = '06:00' %}
Create a variable - next_leave - and set it to the current date at a specific time of the day (“leave_time” above) by concatenating the two strings and converting to a timestamp:
{%- set next_leave = as_timestamp(states.sensor.date.state + ' ' + leave_time) %}
next_leave = (date sensor + leave_time) as a timestamp = {{ next_leave }}
next_leave as a custom timestamp date/time string = {{ next_leave|timestamp_local }}
Convert current_date_time as a timestamp & next_leave as a timestamp to integers then check if current_date_time (as an integer timestamp) is after next_leave (as an integer timestamp) then set next_leave_mod to the next day (add 86400 seconds) at “time to leave”.
If it’s not then set the next leave to today at “time to leave”:
{%- if current_date_time | int >= next_leave | int %}
{% set next_leave_mod = next_leave | int + 86400 %}
{%- else %}
{% set next_leave_mod = next_leave | int %}
{%- endif %}
next_leave_mod as timestamp = {{ next_leave_mod }}
next_leave_mod as a custom timestamp date/time string = {{ next_leave_mod|timestamp_local }}
Determine the next_leave_mod day as number (0 - 6):
{%- set weekday = next_leave_mod | timestamp_custom('%w') | int %}
next day of week to leave = {{weekday}}
And determine if day of week to leave would be on a weekend day. If it would be on Saturday (day of week = 6) then add 48 hours (172800 seconds) to next_leave, or if it would be on Sunday (day of week = 0) then add 24 hours (86400 seconds) to next_leave:
{%- if weekday == 6 %}
{% set next_leave_mod = next_leave | int + 172800 %}
- The next day to leave would normally be Saturday. Adjusting day to Monday
- next_leave_mod as timestamp + 48 hours = {{next_leave_mod}}
{%- endif %}
{%- if weekday == 0 %}
{% set next_leave_mod = next_leave | int + 86400 %}
- The next day to leave would normally be Sunday. Adjusting leave day to Monday
- next_leave_ mod + 24 hours = {{next_leave_mod}}
{% endif %}
next_leave_mod as custom timestamp = {{ next_leave_mod | timestamp_custom('%Y-%m-%d %H:%M') }}
Therefore, leave time = {{ next_leave_mod | timestamp_custom('%Y-%m-%d %H:%M') }}