-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix recorder "year" period in leap year #132167
Fix recorder "year" period in leap year #132167
Conversation
Hey there @home-assistant/core, mind taking a look at this pull request as it has been labeled with an integration ( Code owner commandsCode owners of
|
9a03f0d
to
f3cf0f6
Compare
@peteh Can you please give some more details about the fix? You mention:
Could you give an example with and without your fix please? |
Set to draft until this is covered by tests, I'll update the PR with tests shortly |
Sure thing, When you set period to "Year" in a statistic card, it does not take December into the statistic anymore if the year is a leap year. Broken Setting (Year setting does not take values from this December into account during a leap year - 2024 is a leap year): Workaround: use fixed_period setting in card When fixing the bug, both period "year" and fixed period show the same: It's easier to understand when you walk through this part of the code... ... actually when doing that to answer your question I stumbled on another issue in the same lines of code. One could argue positive offsets are pointless though, as you cannot make statistics for the future, for negative offset the code works well enough for several hundred years as the original comment suggests. else: # calendar_period = "year"
start_time = start_of_day.replace(month=12, day=31) # take current day of year and set the date to the end of the year
# This works for 100+ years of offset
start_time = (start_time + timedelta(days=cal_offset * 366)).replace(
month=1, day=1
) # here actually seems to be another bug - adding 366 will overshoot by 1 in the first year if offset = 1
end_time = (start_time + timedelta(days=366)).replace(day=1) # here we replaced 365 by 366 as the fix Looks like I just identified another bug. I didn't want to rewrite it completely because I don't know how to develop properly for homeassistant. I just fixed my original issue and mounted the file into my docker container to test it. I don't know how to write proper tests for homeassistant to cover the change. In hindsight I believe the approach to this problem for all periods in the original code is very error prone and partly incorrect. |
The reason the code doesn't do that is that Python stdlib does not support timedeltas specified as weeks, months or years, probably because the meaning of that would not always be clear. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot @peteh 👍
We should fix that, but it's not crucial because positive periods are not useful for statistics. I'll do it in a follow-up PR. @peteh Are you active on Discord? |
@emontnemery saw your comment a bit late. I updated the PR with a proper fix. I'm in discord but irregularly. My profile name there should be async or asyncpt if you want to reach out. |
82a1bd2
to
06aba46
Compare
Your latest commit is not correct, the year now ends at midnight December 31st instead of at midnight January 1st. |
This reverts commit 06aba46.
* FIX: make "year" period work in leap year * Add test * Set second and microsecond to non-zero in test start times * FIX: better fix for leap year problem * Revert "FIX: better fix for leap year problem" This reverts commit 06aba46. --------- Co-authored-by: Erik <erik@montnemery.com>
* FIX: make "year" period work in leap year * Add test * Set second and microsecond to non-zero in test start times * FIX: better fix for leap year problem * Revert "FIX: better fix for leap year problem" This reverts commit 06aba46. --------- Co-authored-by: Erik <erik@montnemery.com>
Proposed change
In leap years the statistic card is omitting December from the data.
Type of change
Additional information
The calculation for the end data is wrong in leap years when using a statistic card with period set to "year".
The algorithm gets the 01.01. of the year, then adds 365 days and replaces the day with the 1st again.
Thus in a leap year we would add 365 days resulting in the 31st of December in the current year rather than the 1st of January of the next year. In leap years this always results in 01.12.CURRENT_YEAR instead of 01.01.NEXTYEAR.
There might be better solutions to fix it, e.g. calculating current year and then just create an actual period by hard setting day, month and year as a period but I think this should work reliably too.
For 2024
Before the fix:
start: 2024-01-01
end: 2024-12-01
After fix:
start: 2024-01-01
end: 2025-01-01
Checklist
ruff format homeassistant tests
)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest
.requirements_all.txt
.Updated by running
python3 -m script.gen_requirements_all
.To help with the load of incoming pull requests: