The EPIC Time Conversion and Manipulation Thread!

appreciate it!

Iā€™m using a fairly basic

{{ relative_time(states.binary_sensor.kitchen_presence_sensor_presence.last_changed }}

Which returns:
1 day
2 hours
1 minute
59 seconds
etc

Iā€™d like to abbreviate the unit, so:
1d
2h
1m
59s

Just for my templates to fit into my Cards. Iā€™m sure the answer is already around but couldnā€™t find it after a few searches.
Many thanks!

Edit: for anyone with my question, hereā€™s a solution:

{{ relative_time(current_time - time_diff) | replace(" minutes", "m") | replace(" minute", "m") | replace(" seconds", "s") }} until off

Canā€™t be bothered to replaces second in singular, and probably should add ā€œhourā€ and ā€œhoursā€.

I have read this entire thread, and multiple articles, and just more confused.
I receive a timestamp via a webhook, in Unix format. Using an trigger I have got that unix time in to a sensor - sensor.timestamp. I would now like to get that in to a more human friendly format. However I cannot get the template format right to do it. The closest I got was

{{ states('sensor.timestamp') | as_datetime}}

Which returns null.
I am overlooking something simple, but after three days, i cannot see it.

Post the state of your sensor. Itā€™s not simple.

Not sure what format you wanted that information in.
This is how the sensor appears in Developer Tools, State.

This is how the sensor is created:

  - trigger:
      - platform: webhook
        local_only: false
        webhook_id: something_secret
    sensor:
    
      - name: "xxxxx Timestamp"
        state: "{{ trigger.json.timestamp }}"
        icon: mdi:clock-time-eight-outline          

If there is a better way of getting the timestamp in to human readable time directly off the webhook, then that is fine as well, I donā€™t mind.

Add device_class: timestamp to the sensor definition and the UI will know how to handle it, but also add | as datetime to the state template. It will be displayed according to your locale. You donā€™t need to store the state in human-readable form. Presentation is usually separated from internal state.

I changed the code to this:

      - name: "xxxx Timestamp"
        state: "{{ trigger.json.timestamp }}"
        icon: mdi:clock-time-eight-outline
        device_class: timestamp

When I did that, the following error was logged:

ValueError: Invalid datetime: sensor.timestamp has timestamp device class but provides state 1695399553830:<class 'str'> resulting in ''str' object has no attribute 'tzinfo''

Is that what you were expecting me to do, or was it something else?

Almostā€¦ Note what the docs I linked to say about the device class. It must either be an ISO formatted string or a datetime object.

state: "{{ trigger.json.timestamp | as_datetime }}"

I am getting this error, which means it cannot be either ISO string or a datetime object, although I cannot tell why a string of numbers isnā€™t ISO.

Error rendering state template for sensor.timestamp: TypeError: argument must be str

And in Developer Tools it is just Unknown.

Post the JSON sent by the call that sends it to the webhook. No screenshots.

This is what webhook.site reports it as.
I have changed a couple of unrelated entries for privacy reasons.

{
"alt": x,
"ambientTemperature": 16,
"apiVersion": 2,
"appVersion": "0.25.1.0011",
"batteryLevel": 59496,
"chargePortConnected": false,
"ignitionState": "On",
"lat": X,
"lon": x,
"power": 850000,
"selectedGear": "P",
"speed": 0,
"stateOfCharge": 0.74,
"timestamp": 1695210904538
}

Somethingā€™s very wrong with that timestamp valueā€¦

This should work, but defaults to 0:

{{ trigger.json.timestamp | timestamp_local(0) }}

Trying it in Python to debug it further, I get this:

In [6]: from datetime import datetime

In [7]: datetime.fromtimestamp(1695210904538)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-7-eee505ea12e4> in <module>
----> 1 datetime.fromtimestamp(1695210904538)

ValueError: year 55689 is out of range

Divide it by 1000, or 100. Sometimes apis use a timestamp in millisecond or microseconds

Youā€™re right!

{{ (1695210904538/1000) | timestamp_local(0) 

@scriven33

{{ trigger.json.timestamp | multiply(1/1000) | timestamp_local }}

or

{{ trigger.json.timestamp | multiply(1/1000) | as_datetime }}

That would explain why I couldnā€™t get it to work when I tried before I posted. I checked it using the time/date conversion site linked above and got the right result, so I thought the number was right, but didnā€™t think to divide it. Put that new entry in and it was working immediately.

Thanks for your help @parautenbach and @petro - got there in the end.

1 Like

Dear people,

I am sorry that I might not be have putting so much effort in this an reading all the posts here.

I need your help.

I want to let HA notify me of an upcoming calendar event with his kind of message and its code :

service: notify.notify
data:
title: Upcoming Calendar Event !
message: >-
ā€œEvent :{{ trigger.calendar_event.summary }} @ {{((
as_timestamp(trigger.calendar_event.start) ) | timestamp_custom(ā€™%Xā€™) |
string)[0:5]}} from icloud Calendar(name(d)) Thuis as (Not ALL Day Event) in
{{ (trigger.offset | as_local).strftime(ā€%-I:%M")}} - Event Test 8899"

the output is when the trigger offset is 13:01 minutes before the start of the event/appointment01 e.g. is (and the event name is ā€œTest HAS calendar 46ā€ :


Event :Test HA calendar 46 at Saturday @ 11:40:00 from icloud Calendar(name(d)) Thuis as (Not ALL Day Event) in -1 day, 23:47:00 - Event Test 889

But I really would like to say it like this (output) :

Event :Test HA calendar 46 at Saturday @ 11:40:00 from icloud Calendar(name(d)) Thuis as (Not ALL Day Event) in 13 minutes - Event Test 889

or when the offset is 1 hour and 15 minutes (so before the event :

Event :Test HA calendar 46 at Saturday @ 11:40:00 from icloud Calendar(name(d)) Thuis as (Not ALL Day Event) in 1 hour and 15 minutes - Event Test 889

Here are some more examples of output of the same code with different offsets (times before the event starts :

Event :Test HA calendar 46 at Saturday @ 11:40:00 from icloud Calendar(name(d)) Thuis as (Not ALL Day Event) in -1 day, 23:54:46 - Event Test 889
---------------------------------------------------------------------------- when 05:14 minutes before-----------

please help me with the conversion at least and maybe withe the calculation.

THANK YOU VERY MUCH !!

Ps: Before using trigger.offset I tried to compare the now() time and the start time of the calendar event (= trigger.calendar_event.start) in a calculation and put that as a nice time string in there till the event . but that got me even further into the rabbit hole/desperate. (my automation malfunctioned completely)
(a frustrated & desperate user)

Another veision would be :

service: notify.persistent_notification
data:
title: Upcoming Calendar Event !
message: >-
Event :{{ trigger.calendar_event.summary }} at {{((
as_timestamp(trigger.calendar_event.start) ) | timestamp_custom(ā€™%Xā€™) |
string)[0:5]}} from icloud Calendar(name(d)) Thuis as (Not ALL Day
Event) in {{trigger.offset | string }} - Event Test 889

with output (05:14 minute before the calandar event starts:

Event :Test HA calendar 47 at 11:55 from icloud Calendar(name(d)) Thuis as (Not ALL Day Event) in -1 day, 23:54:46 - Event Test 889

The trigger.offset returns a timedelta object, so you would have to use functions and methods that apply to that type of object. I would recommend that you set up the Easy Time Macros. Once you have that set up, your template would be as follows:

service: notify.notify
data:
title: Upcoming Calendar Event !
message: >-
  {% from 'easy_time.jinja' import custom_time %}
  {% set start = trigger.calendar_event.start | as_datetime  %}
  ā€œEvent :{{ trigger.calendar_event.summary }} @ {{ start.strftime('%H:%M') }} 
  from icloud Calendar(name(d)) Thuis as (Not ALL Day Event) in {{ custom_time( start, 'hour, minute') }} - Event Test 8899"

Helpā€¦ canā€™t get it to workā€¦

{{ ((as_datetime(states("sensor.washing_machine_washer_completion_time")) - now())) }}

results in

0:21:08.894172

I just need the hour and minutesā€¦ but canā€™t find a way to remove the seconds. What am I missing?

I am sure there is an easier way but this will work. It coverts time to seconds and works from there. I donā€™t have your sensor so I used sun2 dawn.

{% set sec = -(states("sensor.home_sun_dawn") | as_timestamp - now() | as_timestamp) %}
{{ sec }}
{% set hours = (sec / 3600) | int(0) %}
{{ hours }}
{% set minute = ((sec - hours * 3600) / 60) | int(0) %}
{{ minute }}
{{ hours~':'~minute }}

Here it is in the developer

you may need to remove the negative sign in front of the sec = -(

Looks like I found a way by using UNIX timestamps:

{{ (as_timestamp(states("sensor.washing_machine_washer_completion_time")) - as_timestamp(now())) | timestamp_custom("%H:%M")}}