From ede8235aaee8467be33dd33fd8c25c39957063e3 Mon Sep 17 00:00:00 2001 From: Thomas Rupprecht Date: Wed, 25 Feb 2026 17:46:28 +0100 Subject: [PATCH] [core] more accurate check for leap year and valid day_of_month (#14197) Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- esphome/core/time.cpp | 2 +- esphome/core/time.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome/core/time.cpp b/esphome/core/time.cpp index 554431c63..1aea18ac8 100644 --- a/esphome/core/time.cpp +++ b/esphome/core/time.cpp @@ -8,7 +8,7 @@ namespace esphome { uint8_t days_in_month(uint8_t month, uint16_t year) { static const uint8_t DAYS_IN_MONTH[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - if (month == 2 && (year % 4 == 0)) + if (month == 2 && (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0)) return 29; return DAYS_IN_MONTH[month]; } diff --git a/esphome/core/time.h b/esphome/core/time.h index 87ebb5c22..d9ce86131 100644 --- a/esphome/core/time.h +++ b/esphome/core/time.h @@ -70,14 +70,14 @@ struct ESPTime { /// @copydoc strftime(const std::string &format) std::string strftime(const char *format); - /// Check if this ESPTime is valid (all fields in range and year is greater than 2018) + /// Check if this ESPTime is valid (all fields in range and year is greater than or equal to 2019) bool is_valid() const { return this->year >= 2019 && this->fields_in_range(); } /// Check if all time fields of this ESPTime are in range. bool fields_in_range() const { return this->second < 61 && this->minute < 60 && this->hour < 24 && this->day_of_week > 0 && - this->day_of_week < 8 && this->day_of_month > 0 && this->day_of_month < 32 && this->day_of_year > 0 && - this->day_of_year < 367 && this->month > 0 && this->month < 13; + this->day_of_week < 8 && this->day_of_year > 0 && this->day_of_year < 367 && this->month > 0 && + this->month < 13 && this->day_of_month > 0 && this->day_of_month <= days_in_month(this->month, this->year); } /** Convert a string to ESPTime struct as specified by the format argument.