Всегда переводили часы весной и осенью и тут появляется @Компoт и наводит тень на плетень.... работаете в центре управления полетами приднестровских ракет и космических спутников?
А мне лень было добавлять в программу домашних часов автоматический перевод времени , писать таблицу по годам и датам , да и места было мало в микроконтроллере. Но вот увидел уже и плюс , в виде протирки пыли , когда полезу переключать время. Таким образом , переключение времени , имеет свои плюсы , - протирание полугодовой пыли на часах каждые пол года.
Ну дык год,число,месяц Формулой их не описать. Поэтому таблично массивом или тупо условием типа - если две последние цифры года такие-то , и , месяц такой-то , и , число такое-то и час такой-то , произвести запись в микроконтроллере времени дс3231 нового значения часов , а во флешь микроконтроллера записать , что время перевели , чтобы при аыключении-включении не переводить снова. Там ещё есть нюансы , надо подумать.
Я правильно понял, Вам надо рассчитать дату, когда наступит последнее воскресенье октября (и воскресенье марта)? Можно обойтись таблицей дней в месяцах и таблицей дня недели 1 января для каждого года, начиная с некоего начального (например, 2020). А дальше всё считается просто. Если последние 2 бита в номере года равны нулю, то год високосный, к февралю прибавляем 1 день. Для облегчения расчетов можно сделать еще таблицу количества дней с начала года на первое число каждого месяца.
Да , все верно ... Одну таблицу можно упростить другой , типа более простой. Преимущество таблиц (массивов констант в ПЗУ) в том , что оне не нагружают оперативку. Но кроме этого , нужно предусмотреть момент гепланового отключения питания во время перевода , и потом перевода однократного после включения питания . Причем если после перевода времени питание включать выключать несколько раз , то это уже не должно переводить время. Я же писал выше , не хотелось заморачиваться. Но когда-нибудь может заморочусь на это дело. Наверняка в интернете есть куча идей на такую тематику. Но и вы , товарищ @Vladm , вижу разбираетесь неплохо и очень рационально в плане улавливания сути для оптимизации
У меня где-то лежат надерганные флешки 24-серии , как раз на шину микроконтроллера часов можно надеть. А туда тупо загнать таблицу до 2099 года , так как до этого года дс3231 по моему. Лень просто заморачиваться но можно будет потом как-нибудь
Можно обойтись и без таблиц, вполне всё укладывается в формулу Например формула получает год в виде четырехзначного числа начиная от 2000 года, и отдает число последнего воскресения марта Nday = 31 - ((YYYY - 1999) * 365 + (YYYY - 2000) \ 4 - 269) % 7 где: \ - деление без остатка % - целый остаток от деления
Для проверки этой формулы , все равно нужно составить предварительную таблицу на бумаге , куда надергать из интернета готовые даты перевода времени. Затем выборочно , подставляя года из диапазона 2000-2099 проверить все ли правильно сработает по формуле. Я когда-то то себе на самодельный тренажёр заморочился с календарем , ну типа , чтобы каждый день фиксировать сколько накручено. И в качестве системы координат выбрал как и в приведенной вами формуле , номера дня (суток) в году. НО для расшифровки номера дня на число и месяц , все равно пришлось использовать ТАБЛИЦУ дней месяцев , так как формулой их описать не получится.
Ну если сильно хочется таблицу то зачем от руки можно забить в Excel и проверить каждый год. Там желтая строка это вычисленное по формуле число, вторая формирует полную дату, а третья уже проверяет какой день недели эта дата средствами самого Excel. Таки формула действует до 2099 года, так как в 2100 году высокосный год отменяется, хотя это тоже в принципе можно учесть в формуле при желании, если кто-то собрался жить так долго ))
Вы все верно сообщаете и просто прекрасно , что приводите одну из формул перевода. Вполне возможно , что есть и вторая формула для обратного перевода , ну типа зимнее-летнее время. Но микроконтроллер , который я применил , НЕ умеет считать дни ... Он умеет только считать время и дату с учётом высокосных лет. Поэтому вычислять номер дня нужно будет в основном контроллере , а это уже таблица чисел в месяце. И суммирование до текущей даты. Потом , когда контроллер вычислит какой на текущую дату по счету день , нужно контроллеру рассчитать по вашим приведенным формулам номера дней для перевода времени (зимнее или летнее) Ну и сравнить текущий номер дня с двумя расчётными. Если совпадет что-то , то произвести перевод времени вперёд или назад , в зависимости что совпало. Это всё будет работать. Но при условии , что питание контроллера не выключалось ... А вот если выключалось , то нужна доработка программы , которая переведет время , и сделает отметку во флешке (энергонезависимой памяти контроллера или отдельной микры) Это нужно для того , чтобы при ещё каких-то выключений включений время больше не переводилось. Надо заморочился немного с алгоритмом
А вот по приколу , посчитаю , сколько памяти примерно займет таблица по формулам с 00 до 99 года. Март - это меньше 255 влазием в один байт. Октябрь - это уже больше 255 Значит в один байт не влазием. Получатся 2 байта на 100 + 100 дат равно 400 байт. Тогда делаем двумерный массив-таблицу с адресами 0-99 и строками 0-1. К этой памяти нужно прибавить таблицу-массив чисел месяцев , одномерный массив с адресами 0-11 размер строки один байт. Итого два массива таблицы в сумме (100 + 100)*2 + 12 = 412 байт. Влезет с большим запасом во флешку 24 серии
Я пару лет назад реализовывал арифметику DateTime (вычитание, сложение, сравнение) для микроконтроллера в ИБП. Там была задача включения нагрузки через определенный длительный промежуток времени (до нескольких суток). При этом сам ИБП, в течение этого промежутка, может неоднократно включаться и выключаться. Для этого, в I2C EEPROM записываются требуемые дата и время включения. При запуске (включении) ИБП текущая дата и время читаются из I2C RTC (часы реального времени с батарейкой), сравниваются с меткой даты времени из EEPROM. Если время истекло - нагрузка включается, метка стирается. Если нет - запускается таймер обратного отсчета. Всё сделано на "голом" ассемблере, ибо микроконтроллер "напихан" по самые "ой-не могу" различными процедурами realtime, с детерминированным временем выполнения. Минимум таблиц, минимум операций деления (много времени кушает).
Писать на асм , тем более несколько лет назад , когда микроконтроллера были ещё не дорогими , может вынудить либо срочная доработка уже изготовленных собранных плат , либо иная невозможность просто поменять контроллер на более сильный. Цена на них была когда не существенная. С другой стороны , переносимость кода на асм на другое железо , бывает сложней чем написание нового кода. На асм также пишут любители аттини , особенно где нет аппаратного И2С и Уарта , а оне нужны. Одно время аттини были такими недорогими , что их ставили даже в китайские фонарики для вкл-выкл , ступенчатой яркости и мигания. В спячке оне экономичны. Про флеш и метку я писал выше , 24 серия как раз работает по вашей шине часов . Чтобы не заморачиваться асм , так как у меня часы собраны и на аттини и на атмегах , с разной переферией и индикацией матричной и снмисегментной , а так же датчиках давления влажности температуры , мне легче писать на си. И переносимость проще на контроллеры.