The EPIC Time Conversion and Manipulation Thread!

I think this is what you’re looking for:

{% set last_changed = states.binary_sensor.main_door.last_changed %}
{% if last_changed < today_at() - timedelta(days=6) %}
  More than a week ago
{% elif last_changed < today_at() - timedelta(days=1) %}
  {{ last_changed.strftime('%A at %H:%M') }}
{% elif last_changed < today_at() %}
  {{ last_changed.strftime('Yesterday at %H:%M') }}
{% else %}
  {{ last_changed.strftime('Today at %H:%M') }} ({{ relative_time(last_changed) }} ago)
{% endif %}

Hi Petro,
May I trouble you with one last thing… I’ve trying to get it to work with no luck after several trial, I guess I need to do some intensive reading about States and Attributes.

What if instead of last changed attribute (which changes after each restart, I want to use an input_datetime helper to make it persistant over re-start… how can I insert this in your code.
It keeps giving me error either no attribute or can’t use < between strings and datetime.

Sorry for the inconvenience

States are always strings, so you will need to convert the state of the Input datetime helper to a offset-aware datetime object by replacing the first line of the template:

{% set last_changed = states('input_datetime.XXXX') | as_datetime | as_local %}
2 Likes

Thank you big time. I can now see what I did wrong… I had the as_local filter before the | as_datetime… makes perfect sense now and works flawlessly.
Much appreciated
RS

I’m trying to format elapsed time into something like ##d ##h ##m or ##:##:##

Here’s what I’ve got so far:

{{ (as_timestamp(now()) - as_timestamp(states('sensor.uptime'))) | timestamp_custom('%dd %hh %mm') }}

Which gives me 31d Dech 12m off an epoch of ~9000 which should be more like 0d 2h 30m. What’s the proper syntax to depict elapsed time from 0 instead of the start of the epoch?

This will be formatted ddd hh:mm:ss

{{ now() - states('sensor.uptime') | as_datetime | as_local }}

If you want a custom format, you have to do the math.

Here’s the math laid out…

With all that Python/Jinja2 is capable of…is that really the most compact way to convert/format seconds into another timeframe?

Yes, there is no way to format a timedelta that’s naturally built into python or jinja.

Just so you know, most languages don’t have this. I was surprised when I found out that C# does have it, but the implementation is terrible in comparison to the strftime equivalent.

Wow! That’s seems like something that should’ve been handled already. OK, thank you.

I use this on my “Router” uptime sensor , sure i didn’t bother about showing D/H/M, as i have a “personal perspective” of the word “UserFriendly” :slight_smile: … it’s my system, only i need to understand :grin:

        - type: custom:template-entity-row
          name: Uptime
          active: true
          state: >
            {% set s = states('sensor.rt_ax68u_d680_uptime')| int(3) %}{{
            '%02d:%02d:%02d' % ((s/86400)|int(3),((s%86400) /
            3600)|int(3),(s%3600) / 60) }}

Thanks. It doesn’t work for me. I get 00:00:00 using the whole thing. What type and format does your sensor output and what does the output of that template look like?

{% set s = states('sensor.uptime')| int(3) %}
{{'%02d:%02d:%02d' % ((s/86400)|int(3),((s%86400) / 3600)|int(3),(s%3600) / 60) }}
{{ s }}
{{ states('sensor.uptime') }}

gives me

image

if htat’s what you want, just use what I linked, no point in re inventing the wheel

          {%- set up_time = as_timestamp(now())-as_timestamp(states('sensor.uptime')) %}

          {%- macro phrase(name, divisor, mod=None) %}
            {%- set value = ((up_time // divisor) % (mod if mod else divisor)) | int %}
            {{- '{} {}'.format(value, name) if value | int > 0 else '' }}
          {%- endmacro %}
          
          {%- set values = [ 
                     phrase('w', 60*60*24*7), 
                     phrase('d', 60*60*24, 7),
                     phrase('h', 60*60, 24),
                     phrase('m', 60), 
                 ] | select('!=','') | list %}
                        
          {{ values | join(', ') }}

Thanks, and I probably will. I just need another day to process why this takes 12 LOC. :wink:

I made the template easily expandable for people who don’t understand code. They can copy the template and remove lines that they don’t want. This could be much shorter and custom, but why bother when this works for all needs/wants

2 Likes

After comparing/contrasting the three example ways to represent the same time at the beginning of this comment, why does:

{{ now() }}

give me this?

2022-05-20 12:37:00.029958-04:00

Which is my local time EDT (UTC-4). So, it’s providing me with a local time and the UTC offset which is not a combination that comment suggests is correct (either the time should be 16:37 or the offset should be dropped).

Because I made a mistake in my explanation?

But I think you are right. I should have made that example read:

time (my time zone in UTC representation): 2018-12-14T14:57:27-05:00

Thanks for pointing it out.

Sensor reports “seconds”
Output in card ( D:H:M )
image

Edit: Without template
image

Edit: Actually this seems to have change at some point, last year it was only an INT, no commas, and no trailing s :slight_smile:

That explains why it wasn’t working for me. Mine is a DTG.

OK, thanks. I wasn’t sure which format was correct or if HA was presenting it wrong.