Creating Holiday season templates

I am using this (thanks petro!!):

When I tried to modify it to create a Halloween sensor, it returns back as True for today (November 17th)

# Is it the Halloween Season? (Last Saturday of September to first Saturday after Halloween)
      halloween_season:
        unique_id: halloween_season
        friendly_name: Halloween Season
        value_template: >
          {%- set month, week, day = 9, 4, 5 %}
          {%- set today = now().date() %}
          {%- set temp = today.replace(month=month, day=1) %}
          {%- set adjust = (day - temp.weekday()) % 7 %}
          {%- set temp = temp + timedelta(days=adjust) %}
          {%- set halloween1 = temp + timedelta(weeks = week - 1) %}
          {%- set month, week, day = 11, 1, 5 %}
          {%- set temp = today.replace(month=month, day=1) %}
          {%- set adjust = (day - temp.weekday()) % 7 %}
          {%- set temp = temp + timedelta(days=adjust) %}
          {%- set halloween2 = temp + timedelta(weeks = week - 1) %}
          {{ today < halloween2 or today > halloween1 }}

I tried to make one for Thanksgiving as well. But as the Halloween one is broken, I have to assume this one is as well

# Is it the Thanksgiving Season? (Thursday before Thanksgiving to Thanksgiving)
      thanksgiving_season:
        unique_id: thanksgiving_season
        friendly_name: Thanksgiving Season
        value_template: >
          {%- set month, week, day = 11, 3, 3 %}
          {%- set today = now().date() %}
          {%- set temp = today.replace(month=month, day=1) %}
          {%- set adjust = (day - temp.weekday()) % 7 %}
          {%- set temp = temp + timedelta(days=adjust) %}
          {%- set thanksgiving1 = temp + timedelta(weeks = week - 1) %}
          {%- set month, week, day = 11, 4, 3 %}
          {%- set temp = today.replace(month=month, day=1) %}
          {%- set adjust = (day - temp.weekday()) % 7 %}
          {%- set temp = temp + timedelta(days=adjust) %}
          {%- set thanksgiving2 = temp + timedelta(weeks = week - 1) %}
          {{ today < thanksgiving2 or today > thanksgiving1 }}

Can anyone help me solve this? I’d like to create a slew of sensors based on the Thanksgiving one that show a week before a holiday through the Holiday itself.

christmas season crosses the year, so the if statement at the end covers that.

change your last lines to

{{ halloween1 < today < halloween2 }}

1 Like

Thank you!! As an aside, I almost hate how easy this comes to you, I am quite jealous

Follow up question.

Why is day = 3 a Friday? I could understand if Friday was either 5 or 6, but 3? And then how is day = 5 a Saturday?

0 = monday
1 = tuesday
2 = wednesday
3 = thursday
4 = friday
5 = saturday
6 = sunday

Based on the above, {%- set month, week, day = 11, 4, 3 %} , I thought that meant 3 is a Friday. I"m really confused

thanksgiving is the 4th Thursday of november

maybe you’re confused because the season starts on friday? that’s because it’s using >, not >=. What’s greater than thursday? friday. What’s greater than or equal to thursday? thursday.

1 Like

and now i feel even more stupid, you are absolutely correct

Ok, while i have you, can you help with Easter? I found this template to find Easter, which outputs 2022-4-17. How would I modify as above so that it shows me the week before Easter through Easter day as Easter season?

Do you really want the whole week or the days since Maundy Thursday/Good Friday?

Just because I was bored, here’s a quick and dirty solution:

{% set Y = now().year %}
{% set G = Y % 19 + 1 %}
{% set C = (Y / 100) | int + 1 %}
{% set X = (3*C / 4) |int - 12 %}
{% set Z = ((8*C + 5) / 25) |int - 5 %}
{% set D = (5*Y / 4)|int - X - 10 %}
{% set E = (11*G + 20 + Z - X ) % 30 %}
{% set E = E+1 if (E==25 and G>11 or E==24) else E %}
{% set N = 44 - E %}
{% set N = N+30 if N<21 else N %}
{% set N = N + 7 - (( D + N ) % 7) %}
{% set M = 4    if N>31 else 3 %}
{% set N = N-31 if N>31 else N %}
{% set Easter = strptime('%04d-%02d-%02d'%(Y,M,N), '%Y-%M-%d').date() %}
{% set today = now().date() %}
{% set wk_before_Easter = Easter - timedelta(days=7) %}
{{ wk_before_Easter <= today <= Easter }}

I also went that route. Here’s how I use my Easter sensor for carnival:

{% if now().month==11 and now().day==11 or
      (as_local(as_datetime(states('sensor.easter'))) - now()).days in range(45,52)%}

When you reply to people, make sure you reply to the person not the thread.

I have canned macros for dates that you can use.

Use these charts to fill in the required number for each macro.

month number
January 1
February 2
March 3
April 4
May 5
June 6
July 7
August 8
September 9
October 10
November 11
December 12
week number
1st 1
2nd 2
3rd 3
4th 4
5th 5
6th 6
day number
Monday 0
Tuesday 1
Wednesday 2
Thursday 3
Friday 4
Saturday 5
Sunday 6

Month Week Day macro

      {%- macro mwd(month, week, day) -%}
      {%- set today = today_at() %}
      {%- set temp = today.replace(month=month, day=1) %}
      {%- set adjust = (day - temp.weekday()) % 7 %}
      {%- set temp = temp + timedelta(days=adjust) -%}
      {{ (temp + timedelta(weeks = week - 1)).isoformat() }}
      {%- endmacro %}

Month Day macro

      {%- macro md(month, day) -%}
      {{ today_at().replace(month=month, day=day).isoformat() }}
      {%- endmacro %}

Last Day in Month Macro

      {%- macro lastdayinmonth(month, day) -%}
      {%- set today = today_at() %}
      {%- set temp = today.replace(month=month, day=1) + timedelta(days=31) %}
      {%- set temp = temp.replace(day=1) - timedelta(days=7) %}
      {%- set adjust = (day - temp.weekday()) % 7 %}
      {%- set temp = temp + timedelta(days=adjust) -%}
      {{ (temp).isoformat() }}
      {%- endmacro %}

Easter Macro

      {%- macro easter() %}
      {%- set year = now().year %}
      {%- set special_years = ['1954', '1981', '2049', '2076'] %}
      {%- set special_year_sub = 7 %}
      {%- set a = year % 19 %}
      {%- set b = year % 4 %}
      {%- set c = year % 7 %}
      {%- set d = (19 * a + 24) % 30 %}
      {%- set e = ((2 * b) + (4 * c) + (6 * d) + 5) % 7 %}
      {%- set day = (22 + d + e) - special_year_sub if year in special_years else 22 + d + e %}
      {%- set month = 4 if day > 31 else 3 %}
      {%- set day = day - 31 if day > 31 else day -%}
      {{ today_at().replace(month=month, day=day).isoformat() }}
      {%- endmacro %}

Using the macros to create dates

      {%- set easter_day = easter() | as_datetime %}
      {%- set thanksgiving = mwd(11, 4, 3) | as_datetime %}
      {%- set valentines = md(2,14) | as_datetime %}
      {%- set memorial_day = lastdayinmonth(5,0) | as_datetime %}

Comparing the macros

      {%- set thanksgiving = mwd(11, 4, 3) | as_datetime %}
      {%- set christmas = md(12, 25) | as_datetime %}
      {{ thanksgiving <= now() <= christmas }}

Crossing the year…

      {%- set t = now() %}
      {%- set thanksgiving = mwd(11, 4, 3) | as_datetime %}
      {%- set jan_1st = md(1, 1) | as_datetime %}
      {{ t <= jan_1st or t >= thanksgiving }}

Single Sensor that does it all attached to scenes

Click here you want to see my single sensor that handles all holidays that are mapped to scenes…


It can be altered to make a sensor that just outputs the name of the holiday too. If you want that, let me know and I’ll make alterations here.

4 Likes

My apologies, I will try and remember to reply.

Would this work for Memorial day (last Monday of May)

# Is it the week of Memorial Day? (The week before and including Memorial Day)
      memorial_day:
        unique_id: memorial_day
        friendly_name: Week before Memorial Day
        value_template: >
            {% set isoweekday = 1 %}
            {% set month = 5 %}
            {% set year = now().year %}
            {% if month == 12 %} {% set month = 1 %} {% set year = year + 1 %}
            {% else %} {% set month = month + 1 %}
            {% endif %}
            {% set lastday = now().date().replace(year=year).replace(month=month).replace(day=1) - timedelta(days=1) %}
            {% set ns = namespace(lastday = lastday) %}
            {% for i in range(1, 8) if ns.lastday.isoweekday() != isoweekday %}
            {% set memorialday2 = ns.lastday - timedelta(days=1) %}
            {% set memorialday1 = memorialday2 - timedelta(days=7) %}
            {{ memorialday1 <= today <= memorialday2 }}

I added it to my last post

1 Like

I would like that. Idealy i’m looking for a sensor that is on/true during the holiday period.
I already managed to make one for christmass. I would also like one for easter but I have no idea how to get started with that one. Valentine’s day etc should all be quite straight forward.