Help with month counting larger than 12 months

Hello community,

my counting sensor for a contract duration is not working since the new year.

- sensor:
    - name: "Stromverbrauch - Monate"
      unique_id: stromverbrauch_monate
      state: >
        {% if (now().timestamp() | timestamp_custom('%Y') | float(default=0)) < (as_timestamp(states('input_datetime.stromvertrag_vertragsbeginn_aktuell')) | timestamp_custom('%Y') | float(default=0)) %}
        {{ (min(12,(now().timestamp() | timestamp_custom('%m') | float(default=0)) - (as_timestamp(states('input_datetime.stromvertrag_vertragsbeginn_aktuell')) | timestamp_custom('%m') | float(default=0)) + 13)) | int(default=0)}}
        {% else %}
        {{ ((now().timestamp() | timestamp_custom('%m') | float(default=0)) - (as_timestamp(states('input_datetime.stromvertrag_vertragsbeginn_aktuell')) | timestamp_custom('%m') | float(default=0)) + 1) | int(default=0)}}
        {% endif %}
      unit_of_measurement: Monate

It worked well until switching to 2025. Now I only get 1 as result.

The input.datetime is 01.12.2024. So the result should be 13.

Any ideas?

Thanks.

Do you mean 1 Dec 2024 or 12 Jan 2024; or perhaps 1 Dec 2023 with a typo? Suggest using internationally unambiguous date descriptions like those, or ISO8601 yyyy-mm-dd format.

Simple way is int(days / (365.25 / 12)); but if you need to be exact on calendar months that might give the wrong answer. With my guess that you mean 1 Dec 2023:

(86400 seconds in a day)

If you want to count “all calendar months that have happened since the timestamp including the start and current months”, something like this should do it:

{% set t0 = ("2024-01-12"|as_datetime) %}
{% set t1 = now() %}
{% set y0 = t0.year %}
{% set m0 = t0.month %}
{% set y1 = t1.year %}
{% set m1 = t1.month %}
{{ (13 - m0) + (12 * (y1 - y0 - 1)) + m1 }}
  • (13-m0) is months in the timestamp’s year
  • (12 * (y1 - y0 - 1)) counts months in any full years between the two dates
  • m1 is the number of months in the current year

Here, you get 13 for 12 Jan 2024, as it includes two Januarys plus all the other 2024 months.

tbh i am not understanding clearly your math :slight_smile:
but here is example

{% set entity_id = 'input_datetime.test_datetime' %}
{% set time_left = (now().timestamp() - as_timestamp(states(entity_id))) | int %}

{%- set years = time_left // 31536000 -%}
{%- set months = (time_left % 31536000) // 2592000 -%} 
{%- set days = (time_left % 2592000) // 86400 -%} 
{%- set hours = (time_left % 86400) // 3600 -%} 
{%- set minutes = (time_left % 3600) // 60 -%} 
{%- set seconds = (time_left % 60) -%} 

{{ years ~ 'y ' ~ months ~ 'm ' ~ days ~ 'd ' ~ ' ' ~ '%02d' % hours~':'~ '%02d' % minutes~':'~ '%02d' % seconds }} 


image

Oh my bad. My input datetime is the 1st January 2024. So my result should be 13 months (and 6 days) by now. But I only want the months to be shown.

No it shouldn’t. It’s 12 months and 5 days.

6-Jan-2024 is 0 months and 5 days from 1-Jan-2024.
6-Feb-2024 is 1 month and 5 days.
⋮
6-Dec-2024 is 11 months and 5 days
6-Jan-2025 is 12 months and 5 days

Only if you’re doing “inclusive counting” like my example above, which ignores days altogether, would you be on 13 months by now. In that example, 31-Jan-2024 to 1-Feb-2024 would be 2 months even though the actual timespan could be a few seconds:

image

1 Like

If you are not wanting calendar months:

{{ (now() - as_datetime("2024-01-01 00:00Z")).days / 30.0 }}
12.366666666666667
1 Like

This is what I want. Could you please show me, how to define the start date by input_datetime?

When I replace the date in set t0 by a sensor I only get

UndefinedError: ‘str object’ has no attribute ‘month’

{% set t0 = states('input_datetime.stromvertrag_vertragsbeginn_aktuell')|as_datetime %}

Entity states are always strings, even input_datetimes.

1 Like