The EPIC Time Conversion and Manipulation Thread!

@finity, @123 I understand when you say

but do you think in this code the goal is to have a combination of 2 string representations of times?

07:32 - 00:30 = {{ strptime('07:32', '%H:%M') + strptime('30', '%M') }}

He actually wants this

which he mistakenly explains as

but in fact he wants a much more complex thing.

My understanding is + and - are functions and their result depends on the data you pass to it and some implicit type conversions that might happen. And the type error it generates speaks for it I think.
Some data types may even have ‘+’ but not ‘-’ (if it does not make sense) and vice versa.

“In the land of the blind, the one-eyed is king”

@123, @AhmadK
Maybe this isn’t the right place but I’ve often come across the term ‘Pythonic’ to describe the Python language structure wrt deciding how to implement it. As I understand it this describes the principle that Python should be readable to non Python programmers.

This ambiguous use of the ‘+’ operator perturbs me especially in light of the single use of it’s opposite and natural ‘companion’, ‘-’ and it just feels, wrong. As a Python novice, I just wonder how you two feel about this?

It’s purely an intellectual question, nothing more…

I have’t finished my first book on Python yet so can’t tell you what exactly ‘Pythonic’ is (perhaps each person has its own understanding when they use this term) but I slightly doubt that it means ‘readable to non Python programmers’.

Yeah, I had a quick look-up and you are probably right that is not accurate, although I have definitely seen that said or at least implied, in the past.

I found this:
"Exploiting the features of the Python language to produce code that is clear, concise and maintainable.

Pythonic means code that doesn’t just get the syntax right but that follows the conventions of the Python community and uses the language in the way it is intended to be used."

Compare the example I posted here for finding the last item in a list, using python’s [-1], versus the previous post in the same thread that employs Jinja2’s length filter. Basically, “pythonic” means doing it the ‘python way’ and taking advantage of its strengths.

Quick question - if I have several sensors I want to format in a particular way, do I have to create the same template sensor each time with a different entity, or is there a way to create a “template” template sensor which can be reused by just passing the entity each time? Kinda like the way we can template Lovelace cards, but for the sensor itself, if you see what I mean?

Thanks to @finity for this thread, and also to @pedro who also added some very useful info on this Date formatting thread, both have been very helpful and enlightening, so thank you both!

as far as i know that is correct.

Also, it’s not @pedro, it’s @petro. :wink:

1 Like

Ah dammit, thats a shame! Thanks for confirming :+1:

Oh Boll*cks! Sorry @petro! Thanks for correcting me :slight_smile:

No hay problema

1 Like

You can reduce some of the duplication by using YAML anchors and aliases. I provided an example here:

2 Likes

Aaah! Interesting (I’d heard of the yaml anchors, but never looked into them further so didnt realise I could use them in the sensors (rather than in the lovelace side of things). Thank you @123, that should help somewhat :+1:

1 Like

Thanks for that.

I never use those so I never remember to think about them.

Just wanted to thank you again for this thread @finity.
Every time I get stuck on something time/date related the answer is always right here! I bet you if you were to organize it all formal like and submit it, it could become part of the official docs.

1 Like

Have you checked the docs recently? it’s in better state than it used to be in terms of Time section.

Thank you :slightly_smiling_face:

I wouldn’t even know where to start on trying to get it to be part of the docs.

submit a pr on the documentation on github… super easy.

I’ve done a couple of doc PR’s already and that isn’t too bad.

It’s the “organizing” part that has me hesitant about laying it all out in a way that fits with the format of everything else.

2 Likes

I can’t get timestamp_custom to work with the following, what am I doing wrong?

{%- set t1 = states.sensor.vast_brunnsgatan_tram2.state %}
{%- set t2 = now().strftime("%H:%M") %}

{{ t1 }} - {{ t2 }} = X minutes

{{ strptime(t1, "%H:%M") - strptime(t2, "%H:%M") | timestamp_custom("%M") }}

Gives me xx:xx:xx instead of just x for minutes.

Because when you subtract a datetime from a datetime, you get a timedelta object. Not a datetime. Strftime and timestamp_custom do not work because it does not have the strftime method.

You can get the seconds out and divide it by 60.

{{ (strptime(t1, "%H:%M") - strptime(t2, "%H:%M")).seconds / 60 }}

but you’ll end up with minutes and a remainder.

so you can round it

{{ ((strptime(t1, "%H:%M") - strptime(t2, "%H:%M")).seconds /60) | round() }}

or truncate it

{{ ((strptime(t1, "%H:%M") - strptime(t2, "%H:%M")).seconds /60) | int }}

If you want to get technical, truncating is the route to go

1 Like

I think in your case the assumption is both now() and states.sensor.vast_brunnsgatan_tram2.state represent time within the same day (as you’re only using hours and minutes).

In this case there is no need to heavily use datetime as t2.time already has hour and minute field and all we need to do is extract hour and minute from t1 and do some basic maths:

{% set t1 = states('sensor.vast_brunnsgatan_tram2') %}
{% set t2 = now().time() %}
{{ (t2.hour - t1[0:2]|int)*60 + t2.minute - t1[-2:]|int }} minutes