From 3377080272ea4b6a201cda35e1d97e504d16b247 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 27 Oct 2025 17:16:09 -0500 Subject: [PATCH] [core] Simplify ESPTime::strftime() and save 20 bytes flash (#11539) --- esphome/core/time.cpp | 22 ++++++++-------------- esphome/core/time.h | 12 +++++++----- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/esphome/core/time.cpp b/esphome/core/time.cpp index 1285ec6448..d30dac4394 100644 --- a/esphome/core/time.cpp +++ b/esphome/core/time.cpp @@ -46,24 +46,18 @@ struct tm ESPTime::to_c_tm() { return c_tm; } -std::string ESPTime::strftime(const std::string &format) { - std::string timestr; - timestr.resize(format.size() * 4); +std::string ESPTime::strftime(const char *format) { struct tm c_tm = this->to_c_tm(); - size_t len = ::strftime(×tr[0], timestr.size(), format.c_str(), &c_tm); - while (len == 0) { - if (timestr.size() >= 128) { - // strftime has failed for reasons unrelated to the size of the buffer - // so return a formatting error - return "ERROR"; - } - timestr.resize(timestr.size() * 2); - len = ::strftime(×tr[0], timestr.size(), format.c_str(), &c_tm); + char buf[128]; + size_t len = ::strftime(buf, sizeof(buf), format, &c_tm); + if (len > 0) { + return std::string(buf, len); } - timestr.resize(len); - return timestr; + return "ERROR"; } +std::string ESPTime::strftime(const std::string &format) { return this->strftime(format.c_str()); } + bool ESPTime::strptime(const std::string &time_to_parse, ESPTime &esp_time) { uint16_t year; uint8_t month; diff --git a/esphome/core/time.h b/esphome/core/time.h index a53fca2346..ffcfced418 100644 --- a/esphome/core/time.h +++ b/esphome/core/time.h @@ -44,17 +44,19 @@ struct ESPTime { size_t strftime(char *buffer, size_t buffer_len, const char *format); /** Convert this ESPTime struct to a string as specified by the format argument. - * @see https://www.gnu.org/software/libc/manual/html_node/Formatting-Calendar-Time.html#index-strftime + * @see https://en.cppreference.com/w/c/chrono/strftime * - * @warning This method uses dynamically allocated strings which can cause heap fragmentation with some + * @warning This method returns a dynamically allocated string which can cause heap fragmentation with some * microcontrollers. * - * @warning This method can return "ERROR" when the underlying strftime() call fails, e.g. when the - * format string contains unsupported specifiers or when the format string doesn't produce any - * output. + * @warning This method can return "ERROR" when the underlying strftime() call fails or when the + * output exceeds 128 bytes. */ std::string strftime(const std::string &format); + /// @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) bool is_valid() const { return this->year >= 2019 && this->fields_in_range(); }