-- This program takes an ISO date specified in the command line as -- YYYY MM DD, where: -- -- * YYYY is a number between 1983 and 2019 -- * MM 1 and 12 -- * DD 1 and 31 -- -- and outputs the date in Julian Calendar (referred to as "Old Style" -- in Russia, and hence New Year in Old Style is jokingly called "Old -- New Year" in Russia) -- The program prints a "happy old new year Russia" message when appropriate. -- The algorithm is simple: since in the chosen period (in fact, from 1900 -- until 2100) the difference between Julian and Gregorian calendars is 13 -- days, we simply convert one to the other using Ada.Calendar.Arithmetic. with Ada.Calendar.Arithmetic; use Ada.Calendar, Ada.Calendar.Arithmetic; with Ada.Command_Line; with Ada.Text_IO; use Ada.Text_IO; -- Note: we could have also used Ada 2005 Ada.Calendar.Formatting procedure Happy_New_Year_RU is Print_Usage_And_Exit : exception; -- Raised when the input format on the command line is not of the form -- YYYY MM DD. function Get_Value (Chars : String; Lo, Hi : Positive) return Positive; -- Given a string of characters Chars, and two positive bounds -- Lo and Hi, returns the positive number corresponding to its -- textual representation specified in Chars. If Chars does not -- correspond to an integer, or is not in the interval [Lo .. Hi] -- a message is printed and exception Print_Usage_And_Exit is raised. --------------- -- Get_Value -- --------------- function Get_Value (Chars : String; Lo, Hi : Positive) return Positive is Value : Integer; begin Value := Integer'Value (Chars); if Value in Lo .. Hi then return Value; else Put_Line ("'" & Chars & "': number not in range " & Lo'Img & " .. " & Hi'Img); raise Print_Usage_And_Exit; end if; exception when Constraint_Error => Put_Line ("'" & Chars & "': Bad number format"); raise Print_Usage_And_Exit; end Get_Value; subtype Year is Positive range 1982 .. 2019; subtype Month is Positive range 1 .. 12; subtype Day is Positive range 1 .. 31; Y : Year; M : Month; D : Day; S : Duration; T : Time; Julian_Gregorian_Difference : constant := 13; type Month_Name is (January, February, March, April, May, June, July, August, September, October, November, December); begin if Ada.Command_Line.Argument_Count /= 3 then raise Print_Usage_And_Exit; end if; Y := Get_Value (Ada.Command_Line.Argument (1), Year'First, Year'Last); M := Get_Value (Ada.Command_Line.Argument (2), Month'First, Month'Last); D := Get_Value (Ada.Command_Line.Argument (3), Day'First, Day'Last); -- Convert the ISO date to the Julian calendar and -- check for the beginning of the year. T := Time_Of (Y, M, D); T := T - Julian_Gregorian_Difference; Split (T, Y, M, D, S); Put (Month_Name'Val (M - 1)'Img & D'Img & "," & Y'Img); if M = 1 and D = 1 then Put_Line (" - Happy Old New Year Russia"); else New_Line; end if; exception when Print_Usage_And_Exit => Put_Line ("Usage: " & Ada.Command_Line.Command_Name & " YYYY MM DD"); Put_Line (" YYYY: " & Year'First'Img & " .. " & Year'Last'Img); Put_Line (" MM : " & Month'First'Img & " .. " & Month'Last'Img); Put_Line (" DD : " & Day'First'Img & " .. " & Day'Last'Img); end Happy_New_Year_RU;