How to show date of last Wednesday of the month?

Yes, but you’re not understanding what HA does under the hood.

device_class:timestamps REQUIRE a datetime object being returned. Not a string. This is a requirement. So using isoformat() will result in an error in the logs. After the template is resolved, HA will take the datetime object and format it in isoformat. Just look at the state of the sensor in developer tools instead of arguing. You’ll see that the state has a T in it. The template in the template editor will not have the T because it hasn’t been resolved by the template sensor code.

yes, that is correct, (for the state, not the attributes though)

not arguing here, simply trying to understand why things are not equal throughout the system.

given the state used here is

{{([ns.spring,ns.fall]|min)}}

and the attributes are:

            {%- set next = [ns.spring, ns.fall] | reject('<',now())|min %}
              {"spring": "{{ns.spring}}",
             "fall": "{{ns.fall}}",
             etc etc

wouldn’t it be expected these attributes also show the T?

well, it was a bit quirky with the range set too tight, now it does work correctly

No because you aren’t using isoformat. You’re just outputting the datetime as a string. Remember device_class: timestamp has extra steps to turn datetimes into iso formatted datetime strings. Attributes do not, so you have to do it.

1 Like

It does not work, it will be off by an hour. There is no way to get the correct time of the second transition due to the nature of DST. It will always be off by 1 hour.

EDIT: Well there probably is a way but it would be a ton of work for no gain. You’d have figure out your next loss/gain and inverse that value on the following loss/gain.

1 Like

hehe, I had those, but just took them out because of your suggestion…will reset that.

o that is what you meant. Yes, that I can confirm…

in good company though as even Brittanica is an hour off for Europe…

Getting back to my earlier search:
how to find the 2 next DST changes (which will always be on last Sunday in March and October, which ever comes first), and yes, ofc preferably with the correct timing.

Summertime 02 → 03 am, Wintertime 03 → 02 am. Since those are fixed they needn’t even be templated?

yeah, I guess it’s not really that important for the second change. In fact it would only need to be a date.

I would merely like to have the sensor update after the actual first change, so it does not display the full Sunday ’ today there’s a DST change’.
technicaly it would be correct of course, but at 3 am, it would preferably change to show the next two changes

The first would therefor need to be correct to the hour.

They aren’t fixed.

sure, not globally. but they are in EU… and I was after that

After struggling with “the last x of the month” for a while I now use this method……

Find the first x of the following month and subtract 7 days. Very reliable.

That’s typically how you’d do it in code anyways. Time is a PITA

1 Like

My (very belated) attempt at the original question:

There’s a subtlety lurking there in the word “next” — if it’s already past the last Wednesday of this month, it should show next month’s last Wednesday. My solution below as a single-line (split for readability) template, not using loops, namespaces or if statements, but after a lot of iterations and an unhealthy obsession on this particular puzzle. The 2 in the top line is the weekday number for Wednesday.

{{ ((range((now().replace(hour=12)-timedelta(days=now().weekday()-2))|as_timestamp|int,
           (now()+timedelta(days=80))|as_timestamp|int,
           604800)
    |select('>',now().replace(hour=11)|as_timestamp())
    |map('as_datetime')
    |groupby('year')
    |first)[1]
   |groupby('month')
   |first)[1][-1].date() }}
  • Creates a list of timestamps spaced a week (604,800s) apart out for 80 days (a safe number to consider all of this month and next) starting from midday on a Wednesday: might be the previous one or the next one depending where we are in the current week;
  • Filters out those days that are in the past;
  • Transforms the remaining days into datetime objects;
  • Groups them by year and takes the list of dates in the earliest year (if there is more than one; a prior attempt missed this nuance and failed to calculate across year boundaries correctly);
  • Groups by month and takes the first month with a Wednesday in it;
  • Gets the last item in that list and converts it to a date.

When in doubt, run your code in the Developer Tools → Template tool, you’ll see the problem. When I paste your value template in there here’s the output:

TypeError: 'weekday' is an invalid keyword argument for replace()