The EPIC Time Conversion and Manipulation Thread!

the omni present template in my config notifications

{{as_timestamp(now())|timestamp_custom('%X')}}: 

can be abbreviated to:

{{now().strftime('%X')}}

too? Or would this mess with the google_tts service … will test to see what happens.

still thinking how to shorten this:

{%- set date = as_timestamp(now()) + (1 * 86400) -%}
          {{date|timestamp_custom('%a %-d %b')}}

this cant be correct (though at first sight is calculates ok) because it doesn’t guard on month days…:

{%- set date = now().replace(day=now().day+1) -%}

strftime is not local. just keep the timestamp_custom.

{{ as_timestamp(now() + timedelta(days=1)) | timestamp_custom('%a %-d %b') }}
1 Like

perfect! thanks!

given the ‘new’ time delta, is there a change needed for this offsetday.

          {% macro getalarm(offsetday=0) %}
          {% set day = (now().weekday() + offsetday) % 7 %}
          {% set offset = offsetday * 86400 %}
          {% if day in range(5) %}
            {% set hour = states('input_number.alarmclock_wd_hour') %}
            {% set minute = states('input_number.alarmclock_wd_minute') %}
          {% else %}
            {% set hour = states('input_number.alarmclock_we_hour') %}
            {% set minute = states('input_number.alarmclock_we_minute') %}
          {% endif %}
          {% set alarm = hour|float|multiply(3600) + minute|float|multiply(60) %}
          {% set time = now().hour * 3600 + now().minute * 60 %}
          {{(offset - time) + alarm if offsetday else alarm - time}}
          {% endmacro %}

edit and cut…

sorry for the previous edit, I tested something silly. Question remains though, can we use the timedelta() in a useful way here, or is it futile, given the rest of the template for the nextalarm (which is calculating a timestamp):

          {% set weekday = is_state('input_boolean.alarmclock_wd_enabled','on') %}
          {% set weekend = is_state('input_boolean.alarmclock_we_enabled','on') %}
          {% set weekdays = [0,1,2,3,4] %}
          {% set weekends = [5,6] %}
          {% set day = now().weekday() %}
          {% set nextday = day + 1 if day != 6 else 0 %}
          {% if nextday in weekdays %}
            {% if weekday %}
              {% set offsetday = nextday %}
            {% elif weekend %}
              {% set offsetday = weekends[0] %}
            {% else %}
              {% set offsetday = None %}
            {% endif %}
          {% elif nextday in weekends %}
            {% if weekend %}
              {% set offsetday = nextday %}
            {% elif weekday %}
              {% set offsetday = weekdays[0] %}
            {% else %}
              {% set offsetday = None %}
            {% endif %}
          {% else %}
            {% set offsetday = None %}
          {% endif %}

          {% if offsetday != None %}
            {% set offset = offsetday-day if offsetday > day else offsetday - day + 7 %}
            {% if (day in weekdays and weekday) or (day in weekends and weekend) %}
              {% set today_alarm = getalarm()|float %}
            {% else %}
              {% set today_alarm = -1 %}
            {% endif %}
            {% set next_alarm = getalarm(offset)|float %}
            {% set time = now().replace(second=0).replace(microsecond=0) %}
            {% if today_alarm > 0 %}
              {{as_timestamp(time) + today_alarm}}
            {% else %}
              {{as_timestamp(time) + next_alarm}}
            {% endif %}
          {% else %}
            0
          {% endif %}

I have a MQTT topic called “Simplisafe” and I have a sensor (1P7U5) which pulls the “time” field from the MQTT json.

I’d like to modify my below sensor to render the MQTT message’s time from 2021-01-12 19:27:53 to something like (in strf terms) %I:%M %p.

How can I achieve this?

  - platform: mqtt
    name: "Justin East Window"
    state_topic: Simplisafe
    value_template: >
      {% if value_json.device == "1P7U5" %}
        {{ value_json.time }}
      {% else %}
        {{ states("sensor.justin_east_window") }}
      {% endif %}
    json_attributes_template: >
      {% if value_json.device == "1P7U5" %}
        {{ {'time': value_json.time, 'extradata': value_json.extradata} | tojson }}"
      {% else %}
        {{ {'time': state_attr("sensor.justin_east_window", "time"), 'extradata': state_attr("sensor.justin_east_window", "extradata")} | tojson }}"
      {% endif %}

using your date & time as an example here is the conversion:

{{ as_timestamp(strptime('2021-01-12 19:27:53', '%Y-%m-%d %H:%M:%S')) | timestamp_custom('%I:%M %p') }}

if the entity attribute you want to convert is the “justin_east_window” entity and it has the same formatr as the example you gave above you should be able to get it work like:

{{ as_timestamp(strptime(state_attr('sensor.justin_east_window', 'time'), '%Y-%m-%d %H:%M:%S')) | timestamp_custom('%I:%M %p') }}

Where do I put this?

I’m not sure I can answer that with the information you’ve provided.

How do you plan on using the newly rendered time format?

frontend
I have simple sensor cards for my frontend to display the time.

Then you likely will want to use it in the value_template section.

I think this should work:

    value_template: >
      {% if value_json.device == "1P7U5" %}
        {% set datetime = value_json.time %}
        {{ as_timestamp(strptime(datetime, '%Y-%m-%d %H:%M:%S')) | timestamp_custom('%I:%M %p') }}
      {% else %}
        {{ states("sensor.justin_east_window") }}
      {% endif %}
1 Like

Thank you so much for this thread. I have just spent an hour trying to drop the leading “0” from a time format, and found the oh-so-simple answer here. Most of the other threads have awful kludges in them.

1 Like

I’ve lost the rest of my few hairs with Taras’ code and this open issue. :crazy_face:

really baffled now, but using this:

      daylight_remaining_hm:
        friendly_name: 'Daylight remaining hh:mm'
        value_template: >
          {% set nw = now().replace(microsecond=0) %}
          {% set sr = state_attr('sensor.astral_sunrise', 'today') %}
          {% set ss = state_attr('sensor.astral_sunset', 'today') %}
          {% if nw < sr %}
            {{ ss - sr }}
          {% elif nw < ss %}
            {{ ss - nw }}
          {% else %}
            0:00:00
          {% endif %}

I see the time left to be 7:11:02.028393 … obviously I want to see HH:MM. checking one of the conversions mentioned atop of this thread, I want to use strptime:

          {% set nw = now().replace(microsecond=0) %}
          {% set sr = state_attr('sensor.astral_sunrise', 'today') %}
          {% set ss = state_attr('sensor.astral_sunset', 'today') %}
          {% if nw < sr %}
            {% set tl = ss - sr %}
            {{ strptime(tl,'%H:%M') }}
          {% elif nw < ss %}
            {% set tl = ss - nw %}
            {{ strptime(tl,'%H:%M') }}
          {% else %}
            0:00:00
          {% endif %}

which doesn’t do anything, still outputs 7:09:02.028393. Missing the obvious here, sp please have a look if you have a spare minute please? thanks

Because it’s not a datetime object it’s a timedelta object. strptime does not work on time deltas. Also strptime takes a string and turns it into a datetime object. strftime takes a datetime object and turns it into a string. If I recall correctly, strftime works on timedelta. I recalled wrong, strftime doesn’t work on timedelta either.

hmm, so where does this all leave us now. This has worked up to the time change in recent HA update.

Ive fallen back to

          {{(as_timestamp(state_attr('sun.sun','next_setting')) - now().timestamp())
             |timestamp_custom('%H:%M',false)}}

for now, but really need to understand (and use) the change in the template with Phils astral Sun2 component … heck, why does this subject stay so challenging.

btw, these are just strings aren’t they?

what has worked up to this timechange? strptime on timedeltas, that’s not true. You’re mixing up functionality. Strfttime, and strptime has never worked on timedeltas, only datetimes.

just think of it this way:

What’s tuesday - monday? 1 day. Ok, what day of the week is that? Don’t have an answer? That’s because there is no answer, hence why strftime and striptime do not work on timedeltas. Because timedeltas are a change in time. Stftime and strptime include formats that would not be possible on a time delta, like %A which is the day of the week as a word.

sorry, should have been more specific… I meant to say, the first template here worked fine up to the time change in HA. It showed the time in HH:MM m and now shows the microseconds output.

so I need to manipulate that back in to HH:MM

Na, you’re still miss remembering. Timedetla’s string repr has not changed in 20 years. It has always been d:hh:mm.ssssss.

it’s possible that the datetimes didn’t track microseconds which didn’t translate to the timedelta, but you would have still gotten a day and zero all the way out.

anyways…

or if you want the days, remove the microsecond

      daylight_remaining_hm:
        friendly_name: 'Daylight remaining hh:mm'
        value_template: >
          {% set nw = now().replace(microsecond=0) %}
          {% set sr = state_attr('sensor.astral_sunrise', 'today').replace(microsecond=0) %}
          {% set ss = state_attr('sensor.astral_sunset', 'today').replace(microsecond=0) %}
          {% if nw < sr %}
            {{ ss - sr }}
          {% elif nw < ss %}
            {{ ss - nw }}
          {% else %}
            0:00:00
          {% endif %}