Код Arduino для определения, находимся ли мы в летнем времени (DST) или нет

Вопрос или проблема

Я пишу код на C для ESP32C3, то есть для устройства типа Arduino. У него нет внутреннего часового механизма, поэтому для получения времени я обращаюсь к NTP-серверу в интернете.

Я также общаюсь с погодным сервером, чтобы получить локальную погоду, включая время восхода и захода солнца.

Сейчас всё в порядке, за исключением того факта, что погодный сервер, похоже, не учитывает переход на летнее время, поэтому он дает мне значения, которые на один час не соответствуют.

Поэтому я написал эту процедуру, чтобы попытаться выяснить, нужно ли мне корректировать ответ на восход/заход солнца [это на Arduino C]

Вот определение, да, я в Европе.

Переход на летнее время всегда начинается в воскресенье, второе в марте, и заканчивается в первое воскресенье ноября в Соединенных Штатах. Это контрастирует с Великобританией и Европейским Союзом, где летнее время начинается в последнее воскресенье марта и заканчивается в последнее воскресенье октября.

char dayName[10];
char dayMonth[2];
char monthYear[2];

strftime(dayName,64,"%A", &timeinfo); // день недели
strftime(dayMonth,64,"%d", &timeinfo); // день месяца
strftime(monthYear,64,"%B", &timeinfo); // месяц года

if (!strcmp(dayName, "Sunday")) {
  if (atoi(monthYear) == 10) {
    if (atoi(dayMonth) > 31 - 7) {
    // последнее воскресенье октября, ПЛВ = ложь
      DST = false;
    }
  }
  if (atoi(monthYear) == 3) {
    if (atoi(dayMonth) > 31 - 7) {
      // последнее воскресенье марта, ПЛВ = истина
      DST = true;
    }
  }
}

Вопросы;

  1. Этот код выглядит разумно?
  2. Есть ли лучший способ сделать это, помните, что это не компьютер, это ESP32C3; так что вы не получаете дату, например – у него нет понятия о дате/времени.

Выглядит хорошо, но вы могли бы просто уменьшить 64 до 10 для dayName и до 30 для dayMonth и monthYear, чтобы оптимизировать хранение (помните, это ESP, который не является очень мощным чипом, поэтому оптимизация использования памяти необходима), а также вы могли бы добавить лог-сообщение, чтобы оставаться в курсе, например ESP_LOGI(TAG, "DST: %s", DST ? "true" : "false");.

Ответ или решение

Код Arduino для определения, находимся ли мы в режиме перехода на летнее/зимнее время (DST)

Ваша задача включает в себя проверку, находится ли ваше устройство ESP32C3 в режиме перехода на летнее/зимнее время, используя данные о времени, полученные с NTP-сервера, и данные о восходе и закате солнца с погодного сервера. Поскольку ваше устройство не имеет внутренних часов, вам необходимо правильно обработать переход на летнее/зимнее время, особенно учитывая, что заданные данные о восходе/закате могут не учитывать DST.

1. Анализ вашего текущего кода

Ваш код использует strftime для получения дня недели, дня месяца и месяца, и условные операторы для определения перехода на летнее/зимнее время на основе данных о текущей дате. Однако есть несколько моментов, которые следует улучшить:

  • Оптимизация памяти: Вы можете уменьшить размеры массивов. Например, замените char dayName[10] на char dayName[10] и сокращение размерностей для других переменных.
  • Улучшение логирования: Добавление лог-сообщений может помочь в отладке состояния вашего приложения. Использование такой конструкции, как ESP_LOGI(TAG, "DST: %s", DST ? "true" : "false");, позволит вам видеть текущее состояние DST в реальном времени.

2. Улучшенная версия кода

Ниже представлена доработанная версия кода с учетом предложенных улучшений:

#include <time.h>
#include <WiFi.h>
#include <ESP_LOG.h> // Подключите библиотеку для логирования

bool isDST(struct tm timeinfo) {
    // Определим переменные для хранения дня, месяца и дня недели
    char dayName[10];
    char dayMonth[3];
    char monthYear[10];

    strftime(dayName, sizeof(dayName), "%A", &timeinfo); // Получаем день недели
    strftime(dayMonth, sizeof(dayMonth), "%d", &timeinfo); // Получаем день месяца
    strftime(monthYear, sizeof(monthYear), "%m", &timeinfo); // Получаем месяц

    int month = atoi(monthYear);
    int day = atoi(dayMonth);
    bool DST = false;

    if (strcmp(dayName, "Sunday") == 0) {
        if (month == 10) {
            // Проверка на последнюю воскресенье октября
            if (day > (31 - 7)) {
                DST = false; // Зима
            }
        } else if (month == 3) {
            // Проверка на последнее воскресенье марта
            if (day > (31 - 7)) {
                DST = true; // Лето
            }
        }
    }

    // Записываем текущее состояние DST в лог
    ESP_LOGI("DST_CHECK", "DST: %s", DST ? "true" : "false");

    return DST;
}

3. Объяснение логики кода

В данной версии кода мы:

  • Оптимизировали структуру хранения данных, уменьшив размеры массивов.
  • Внедрили логику, которая проверяет неделю и месяц, чтобы правильно определить DST.
  • Использовали функции для логирования состояния DST.

Заключение

Ваша исходная логика была правильной, но целесообразно оптимизировать код, чтобы уменьшить потребление памяти и улучшить отладку. Использование NTP-сервера обеспечивает точность времени, что критично для корректного определения перехода на летнее/зимнее время. Надеюсь, предложенные изменения помогут вам сделать код более эффективным и понятным.

Оцените материал
Добавить комментарий

Капча загружается...