diff --git a/esphome/components/time/posix_tz.cpp b/esphome/components/time/posix_tz.cpp index 315216b09c..bbceb057a0 100644 --- a/esphome/components/time/posix_tz.cpp +++ b/esphome/components/time/posix_tz.cpp @@ -327,18 +327,20 @@ time_t __attribute__((noinline)) calculate_dst_transition(int year, const DSTRul return days * 86400 + rule.time_seconds + base_offset_seconds; } +} // namespace internal + bool __attribute__((noinline)) is_in_dst(time_t utc_epoch, const ParsedTimezone &tz) { if (!tz.has_dst) { return false; } - int year = epoch_to_year(utc_epoch); + int year = internal::epoch_to_year(utc_epoch); // Calculate DST start and end for this year // DST start transition happens in standard time - time_t dst_start = calculate_dst_transition(year, tz.dst_start, tz.std_offset_seconds); + time_t dst_start = internal::calculate_dst_transition(year, tz.dst_start, tz.std_offset_seconds); // DST end transition happens in daylight time - time_t dst_end = calculate_dst_transition(year, tz.dst_end, tz.dst_offset_seconds); + time_t dst_end = internal::calculate_dst_transition(year, tz.dst_end, tz.dst_offset_seconds); if (dst_start < dst_end) { // Northern hemisphere: DST is between start and end @@ -349,8 +351,6 @@ bool __attribute__((noinline)) is_in_dst(time_t utc_epoch, const ParsedTimezone } } -} // namespace internal - bool parse_posix_tz(const char *tz_string, ParsedTimezone &result) { if (!tz_string || !*tz_string) { return false; @@ -435,7 +435,7 @@ bool epoch_to_local_tm(time_t utc_epoch, const ParsedTimezone &tz, struct tm *ou } // Determine DST status once (avoids duplicate is_in_dst calculation) - bool in_dst = internal::is_in_dst(utc_epoch, tz); + bool in_dst = is_in_dst(utc_epoch, tz); int32_t offset = in_dst ? tz.dst_offset_seconds : tz.std_offset_seconds; // Apply offset (POSIX offset is positive west, so subtract to get local) diff --git a/esphome/components/time/posix_tz.h b/esphome/components/time/posix_tz.h index 27e51e7519..d44c611fe8 100644 --- a/esphome/components/time/posix_tz.h +++ b/esphome/components/time/posix_tz.h @@ -61,6 +61,12 @@ void set_global_tz(const ParsedTimezone &tz); /// Get the global timezone. const ParsedTimezone &get_global_tz(); +/// Check if a given UTC epoch falls within DST for the parsed timezone. +/// @param utc_epoch Unix timestamp in UTC +/// @param tz The parsed timezone +/// @return true if DST is in effect at the given time +bool is_in_dst(time_t utc_epoch, const ParsedTimezone &tz); + // Internal helper functions exposed for testing namespace internal { @@ -114,12 +120,6 @@ void epoch_to_tm_utc(time_t epoch, struct tm *out_tm); /// @return Unix epoch timestamp of the transition time_t calculate_dst_transition(int year, const DSTRule &rule, int32_t base_offset_seconds); -/// Check if a given UTC epoch falls within DST for the parsed timezone. -/// @param utc_epoch Unix timestamp in UTC -/// @param tz The parsed timezone -/// @return true if DST is in effect at the given time -bool is_in_dst(time_t utc_epoch, const ParsedTimezone &tz); - } // namespace internal } // namespace esphome::time diff --git a/esphome/core/time.cpp b/esphome/core/time.cpp index 918c3c1ffb..aa8dba4b6f 100644 --- a/esphome/core/time.cpp +++ b/esphome/core/time.cpp @@ -272,7 +272,7 @@ void ESPTime::recalc_timestamp_local() { time_t approx_utc = this->timestamp + tz.std_offset_seconds; // Check if DST is in effect and apply the appropriate offset - if (time::internal::is_in_dst(approx_utc, tz)) { + if (time::is_in_dst(approx_utc, tz)) { this->timestamp += tz.dst_offset_seconds; } else { this->timestamp += tz.std_offset_seconds; @@ -289,7 +289,7 @@ int32_t ESPTime::timezone_offset() { const auto &tz = time::get_global_tz(); // POSIX offset is positive west, but we return offset to add to UTC to get local // So we negate the POSIX offset - if (time::internal::is_in_dst(now, tz)) { + if (time::is_in_dst(now, tz)) { return -tz.dst_offset_seconds; } return -tz.std_offset_seconds;