-- 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 chinese format. -- The date prints a "happy new year china" message when appropriate. -- We use 32-bit Wide_Wide_Strings in the following program. -- 16-bit Wide_Strings would have been sufficient. with Ada.Characters.Conversions; use Ada.Characters.Conversions; with Ada.Command_Line; with Ada.Wide_Wide_Text_IO; use Ada.Wide_Wide_Text_IO; procedure Happy_New_Year_Cn_En is Print_Usage_And_Exit : exception; -- Raised when the input format on the command line is not of the form -- YYYY MM DD. subtype String_Cn is Wide_Wide_String; -- Convenient renaming for a Wide_Wide_String. function To_String_Cn (Item : String) return String_Cn renames To_Wide_Wide_String; -- Convenient renaming of To_Wide_Wide_String. function Img (Value : Integer) return String_Cn; -- Given an integer Value, returns the corresponding -- String_Cn representation. 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. --------- -- Img -- --------- function Img (Value : Integer) return String_Cn is begin return To_String_Cn (Value'Img); end Img; --------------- -- 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 ("'" & To_String_Cn (Chars) & "': number not in range " & Img (Lo) & " .. " & Img (Hi)); raise Print_Usage_And_Exit; end if; exception when Constraint_Error => Put_Line ("'" & To_String_Cn (Chars) & "': Bad number format"); raise Print_Usage_And_Exit; end Get_Value; subtype Year is Positive range 1983 .. 2019; subtype Month is Positive range 1 .. 12; subtype Day is Positive range 1 .. 31; Y : Year; M : Month; D : Day; type Year_Start is record M : Month; D : Day; end record; Chinese_New_Year : constant array (Year) of Year_Start := (1983 => (02, 13), 1984 => (02, 02), 1985 => (02, 20), 1986 => (02, 09), 1987 => (01, 29), 1988 => (02, 17), 1989 => (02, 06), 1990 => (01, 27), 1991 => (02, 15), 1992 => (02, 04), 1993 => (01, 23), 1994 => (02, 10), 1995 => (01, 31), 1996 => (02, 19), 1997 => (02, 07), 1998 => (01, 28), 1999 => (02, 16), 2000 => (02, 05), 2001 => (01, 24), 2002 => (02, 12), 2003 => (02, 01), 2004 => (01, 22), 2005 => (02, 09), 2006 => (01, 29), 2007 => (02, 18), 2008 => (02, 07), 2009 => (01, 26), 2010 => (02, 14), 2011 => (02, 03), 2012 => (01, 23), 2013 => (02, 10), 2014 => (01, 31), 2015 => (02, 19), 2016 => (02, 08), 2017 => (01, 28), 2018 => (02, 16), 2019 => (02, 05)); 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 chinese format and -- check for the beginning of the year. Put (Img (Y) & " " & Img (M) & " " & Img (D)); if M = Chinese_New_Year (Y).M and D = Chinese_New_Year (Y).D then Put_Line (" - Happy New Year China"); else New_Line; end if; exception when Print_Usage_And_Exit => Put_Line ("Usage: " & To_String_Cn (Ada.Command_Line.Command_Name) & " YYYY MM DD"); Put_Line (" YYYY: " & Img(Year'First) & " .. " & Img (Year'Last)); Put_Line (" MM : " & Img (Month'First) & " .. " & Img (Month'Last)); Put_Line (" DD : " & Img (Day'First) & " .. " & Img (Day'Last)); end Happy_New_Year_Cn_En;