-- Эта программа получает в качестве параметров командной строки дату ISO в -- формате ГГГГ ММ ДД, где: -- -- * ГГГГ это число в диапазоне от 1983 до 2019 -- * ММ 1 до 12 -- * ДД 1 до 31 -- -- и распечатывает соответствующюю ей дату по старому стилю -- Программа также печатает поздравление со "старым новым годом" в -- соответствующих случаях. -- Алгоритм прост: поскольку в выбранный период (если быть точным, в период -- с 1900 по 2100 годы) разница между старым и новым стилем составляет 13 -- дней, мы просто переводим одну дату в другую используя функции из -- пакета Ada.Calendar.Arithmetic. with Ada.Calendar.Arithmetic; use Ada.Calendar, Ada.Calendar.Arithmetic; with Ada.Characters.Conversions; use Ada.Characters.Conversions; with Ada.Command_Line; with Ada.Wide_Text_IO; use Ada.Wide_Text_IO; -- Замечание: можно было бы воспользоваться для печати функции языка -- Ада 2005 из пакета Ada.Calendar.Formatting procedure Happy_New_Year_RU_RU is Выдать_Подсказку_И_Выйти : exception; -- Возбуждается когда входные параметры не соответствуют формату -- ДДДД ММ ГГ. function Печать_Числа (Число : Integer) return Wide_String; -- Возвращает текстовое представление числа function Число (Строка : String; Низ, Верх : Positive) return Positive; -- На основе строки Строка и двух положительных пределов Низ и Верх, -- возвращает положительное число, соответствующее его текстовому -- представлению в Строка. Если Строка не содержит числа, или число -- не принадлежит интервалу [Низ .. Верх], печатается сообщение и -- возбуждается исключение Выдать_Подсказку_И_Выйти. ------------------ -- Печать_Числа -- ------------------ function Печать_Числа (Число : Integer) return Wide_String is begin return To_Wide_String (Число'Img); end Печать_Числа; ----------- -- Число -- ----------- function Число (Строка : String; Низ, Верх : Positive) return Positive is Результат : Integer; begin Результат := Integer'Value (Строка); if Результат in Низ .. Верх then return Результат; else Put_Line ("'" & To_Wide_String (Строка) & "': значение не принадлежит диапазону" & Positive'Wide_Image (Низ) & " .." & Positive'Wide_Image(Верх)); raise Выдать_Подсказку_И_Выйти; end if; exception when Constraint_Error => Put_Line ("'" & To_Wide_String (Строка) & "': неверный формат данных"); raise Выдать_Подсказку_И_Выйти; end Число; subtype Год is Positive range 1982 .. 2019; subtype Месяц is Positive range 1 .. 12; subtype День is Positive range 1 .. 31; Г : Год; М : Месяц; Д : День; С : Duration; Т : Time; Разница_Старый_Новый : constant := 13; type Наименование_Месяца is (Января, Февраля, Марта, Апреля, Мая, Июня, Июля, Августа, Сентября, Октября, Ноября, Декабря); begin if Ada.Command_Line.Argument_Count /= 3 then raise Выдать_Подсказку_И_Выйти; end if; Г := Число (Ada.Command_Line.Argument (1), Год'First, Год'Last); М := Число (Ada.Command_Line.Argument (2), Месяц'First, Месяц'Last); Д := Число (Ada.Command_Line.Argument (3), День'First, День'Last); -- Переводим дату ISO в старый стиль и проверяем на начало года. Т := Time_Of (Г, М, Д); Т := Т - Разница_Старый_Новый; Split (Т, Г, М, Д, С); Put (Печать_Числа (Д) & " " & Наименование_Месяца'Wide_Image (Наименование_Месяца'Val (М - 1)) & Печать_Числа (Г) & " ГОДА"); if М = 1 and Д = 1 then Put_Line (" - со Старым Новым Годом, Россия!"); else New_Line; end if; exception when Выдать_Подсказку_И_Выйти => Put_Line ("Параметры: " & To_Wide_String (Ada.Command_Line.Command_Name) & " ГГГГ ММ ДД"); Put_Line (" ГГГГ: " & Печать_Числа (Год'First) & " .. " & Печать_Числа (Год'Last)); Put_Line (" ММ : " & Печать_Числа (Месяц'First) & " .. " & Печать_Числа (Месяц'Last)); Put_Line (" ДД : " & Печать_Числа (День'First) & " .. " & Печать_Числа (День'Last)); end Happy_New_Year_RU_RU;