Работа с датами
От Alexander Zabairatsky (2:5020/830.68) к Alexander Wolf
В ответ на Заголовок предыдущего сообщения в треде (Имя Автора)
Hello Alexander!
16 May 11 11:08, Alexander Wolf wrote to Nickita A Startcev:
NS>> Hу, вычесть нулевое января текущего года - это нетрудно.
AW> Меня все же интересуют алгоритмы, а не конкретные реализации в
AW> конкретных языках программировния.
А самому сообразить не ку? И на каком языке излагать эти алгоритмы? Блок-схему рисовать, да? :-)
Впрочем, такие простые алгоритмы достаточно просто описываются и без блок-схемы.
AW> Особенно меня интересует алгоритм вычисления даты по порядковому
AW> номеру дня в году.
Ладно. Сначала общая часть обоих алгоритмов. Берем массив, допустим ML из 12 элементов с индексами от 1 до 12, заполняем его количеством дней в месяцах для обычного года. Далее проверяем не високосный ли у нас год, если да, то меняем второй элемент этого массива с 28 на 29.
А теперь раздельно. Сначала номер дня по дате. Берем номер текущего месяца в качестве индекса в этот массив и меняем эту ячейку на сегодняшнее число. Таким образом получаем массив, в котором для каждого из месяцев, кроме текущего, в соответствующей ячейке лежит количество дней этого месяца, для текущего же лежит текущее число. Осталось просуммировать.
Обратная задача также примитивна. Эапускаешь цикл по индексу от 1 до 12, в цикле копируешь номер дня в рабочую переменную, вычитаешь из нее очередной элемент массива, если результат не больше нуля (ноль или минус), выходим из цикла нелюбимым GOTO, в номере дня будет число, в индексе - месяц. Если применяемый язык программирования не поддерживает GoTo, то придется оформить эту процедурку подпрограммой и вместо GOTO использовать RETURN. Если же рабочая переменная все еще больше нуля, копируем ее значение в номер дня и идем на следующую итерацию цикла. Если цикл закончился естественным образом, значит програмке подсунули номер больший, чем 365 (366), что есть ошибка.
Интереснее продумать варианты. Допустим, бывают случаи, когда требуется жесткая экономия памяти данных - это мы на писюках привыкли к гигабайтам, в крайнем случае - к сотням мегабайт оперативки, а бывают контроллеры с 1-2К байт флэш-памяти программы и 32 или 64 _байтами_ оперативной памяти для данных. Естественно, отдавать 16 байт из этих 32-64 под массив будет сильно жирно, массив следует делать константным, располагая его в памяти программы, а изменения (не февраль ли для проверки на високосный год и не текущий ли месяц для вычисления номера дня в году) делать внутри цикла. Что-то вроде такого
1. Пересылаем в регистр число дней в очередном месяце (по индексу).
2. Проверяем, а может сегодня февраль?
3. Если не февраль, то (7)
4. Смотрим, не високосный ли год?
5 Если нет, то (7)
6. Пересылаем в этот же регистр число 29
7. (Продолжение Содержимсое регистра используем в качестве числа дней в очередном месяце).
Все пронумерованный пункты, кроме 4-го и 7-го, скорее всего, будут реализованы одной ассемблерной командой.
А как определить, високосный год, или нет, оставляю тебе в качестве домашнего задания. :-)
Всего доброго!
А. Забайрацкий.
--- GoldED+/W32-MINGW 1.1.5 ... IP-point. Location: г. Караганда, Казахстан
* Origin: Кто мешает тебе выдумать порох непромокаемый? (2:5020/830.68)
Ответы на это письмо:
From: Username
Заголовок следующего сообщения в треде может быть длинным и его придется перенести на новую строку
From: Username
Или коротким