Calendar: Difference between revisions
Content added Content deleted
Line 15: | Line 15: | ||
For economy of size, do not actually include Snoopy generation in either the code or the output, instead just output a place-holder. |
For economy of size, do not actually include Snoopy generation in either the code or the output, instead just output a place-holder. |
||
=={{header|Ada}}== |
|||
Specification of a "Printable_Calendar" package (printable_calendar.ads): |
|||
<lang Ada>with Ada.Calendar.Formatting; |
|||
package Printable_Calendar is |
|||
subtype String20 is String(1 .. 20); |
|||
type Month_Rep_Type is array (Ada.Calendar.Month_Number) of String20; |
|||
type Description is record |
|||
Weekday_Rep: String20; |
|||
Month_Rep: Month_Rep_Type; |
|||
end record; |
|||
-- for internationalization, you only need to define a new description |
|||
Default_Description: constant Description := |
|||
(Weekday_Rep => |
|||
"Mo Tu We Th Fr Sa So", |
|||
Month_Rep => |
|||
(" January ", " February ", " March ", |
|||
" April ", " May ", " June ", |
|||
" July ", " August ", " September ", |
|||
" October ", " November ", " December ")); |
|||
type Calendar (<>) is tagged private; |
|||
-- Initialize a calendar for devices with 80- or 132-characters per row |
|||
function Init_80(Des: Description := Default_Description) return Calendar; |
|||
function Init_132(Des: Description := Default_Description) return Calendar; |
|||
-- the following procedures output to standard IO; override if neccessary |
|||
procedure New_Line(Cal: Calendar); |
|||
procedure Put_String(Cal: Calendar; S: String); |
|||
-- the following procedures do the real stuff |
|||
procedure Print_Line_Centered(Cal: Calendar'Class; Line: String); |
|||
procedure Print(Cal: Calendar'Class; |
|||
Year: Ada.Calendar.Year_Number; |
|||
Year_String: String); -- this is the main Thing |
|||
private |
|||
type Calendar is tagged record |
|||
Columns, Rows, Space_Between_Columns: Positive; |
|||
Left_Space: Natural; |
|||
Weekday_Rep: String20; |
|||
Month_Rep: Month_Rep_Type; |
|||
end record; |
|||
end Printable_Calendar;</lang> |
|||
Next the implementation (printable_calendar.ads): |
|||
<lang Ada>with Ada.Text_IO; |
|||
package body Printable_Calendar is |
|||
use Ada.Calendar; |
|||
package F renames Ada.Calendar.Formatting; |
|||
function Days_Per_Month(Year: Year_Number; Month: Month_Number) |
|||
return Day_Number is |
|||
begin |
|||
case Month is |
|||
when 1 | 3 | 5 | 7 | 8 | 10 | 12 => return 31; |
|||
when 4 | 6 | 9 | 11 => return 30; |
|||
when 2 => |
|||
if Year mod 4 /= 0 then |
|||
return 28; |
|||
elsif Year mod 100 /= 0 then |
|||
return 29; |
|||
elsif Year mod 400 /= 0 then |
|||
return 28; |
|||
else |
|||
return 29; |
|||
end if; |
|||
end case; |
|||
end Days_Per_Month; |
|||
type Full_Month_Rep is array (1 .. 6) of String20; |
|||
function Generate_Printable_Month (Y: Ada.Calendar.Year_Number; |
|||
M: Ada.Calendar.Month_Number) |
|||
return Full_Month_Rep is |
|||
X: Full_Month_Rep := (others => " "); |
|||
-- If X=Generate_Printable_Month(2011, 01), the result could be |
|||
-- " January ", -- Month_Rep(01) |
|||
-- "Mo Tu We Th Fr Sa Su" -- Weekday_Rep |
|||
-- " 1 2" -- X(1) |
|||
-- " 3 4 5 6 7 8 9" -- X(2) |
|||
-- "10 11 12 13 14 15 16" -- X(3) |
|||
-- "17 18 19 20 21 22 23" -- X(4) |
|||
-- "24 25 26 27 28 29 30" -- X(5) |
|||
-- "31 " -- X(6) |
|||
Row: Integer range 1 .. 6 := 1; |
|||
Day_Index: constant array(F.Day_Name) of Positive |
|||
:= (1, 4, 7, 10, 13, 16, 19); |
|||
begin |
|||
for I in 1 .. Days_Per_Month(Y, M) loop |
|||
declare |
|||
Weekday: constant F.Day_Name := F.Day_Of_Week(F.Time_Of(Y, M, I)); |
|||
Pos: constant Positive := Day_Index(Weekday); |
|||
Cleartext_Name: constant String := Day_Number'Image(I); |
|||
L: constant Positive := Cleartext_Name'Last; |
|||
begin |
|||
X(Row)(Pos .. Pos+1) := Cleartext_Name(L-1 .. L); |
|||
if F."="(Weekday, F.Sunday) then |
|||
Row := Row + 1; |
|||
end if; |
|||
end; |
|||
end loop; |
|||
return X; |
|||
end Generate_Printable_Month; |
|||
procedure Print(Cal: Calendar'class; |
|||
Year: Ada.Calendar.Year_Number; |
|||
Year_String: String) is |
|||
The_Month: Month_Number := Month_Number'First; |
|||
procedure Write_Space(Length: Natural) is |
|||
begin |
|||
for I in 1 .. Length loop |
|||
Cal.Put_String(" "); |
|||
end loop; |
|||
end Write_Space; |
|||
Year_Rep: array(Month_Number) of Full_Month_Rep; |
|||
begin |
|||
-- print the year |
|||
Cal.Print_Line_Centered(Year_String); |
|||
-- generate a printable form for all the months |
|||
for Month in Month_Number loop |
|||
Year_Rep(Month) := Generate_Printable_Month(Year, Month); |
|||
end loop; |
|||
begin |
|||
while True loop |
|||
-- new line |
|||
Cal.New_Line; |
|||
-- write month names |
|||
Write_Space(Cal.Left_Space); |
|||
for Month in The_Month .. The_Month+Cal.Columns-2 loop |
|||
Cal.Put_String(Cal.Month_Rep(Month)); |
|||
Write_Space(Cal.Space_Between_Columns); |
|||
end loop; |
|||
Cal.Put_String(Cal.Month_Rep(The_Month+Cal.Columns-1)); |
|||
Cal.New_Line; |
|||
-- write "Mo Tu .. So" - or whatever is defined by Weekday_Rep |
|||
Write_Space(Cal.Left_Space); |
|||
for Month in The_Month .. The_Month+Cal.Columns-2 loop |
|||
Cal.Put_String(Cal.Weekday_Rep); |
|||
Write_Space(Cal.Space_Between_Columns); |
|||
end loop; |
|||
Cal.Put_String(Cal.Weekday_Rep); |
|||
Cal.New_Line; |
|||
-- write the dates |
|||
for I in 1 .. 6 loop |
|||
Write_Space(Cal.Left_Space); |
|||
for Month in The_Month .. The_Month+Cal.Columns-2 loop |
|||
Cal.Put_String(Year_Rep(Month)(I)); |
|||
Write_Space(Cal.Space_Between_Columns); |
|||
end loop; |
|||
Cal.Put_String(Year_Rep(The_Month+Cal.Columns-1)(I)); |
|||
Cal.New_Line; |
|||
end loop; |
|||
The_Month := The_Month + Cal.Columns; |
|||
-- this will eventually raise Constraint_Error to terminate the loop |
|||
end loop; |
|||
exception |
|||
when Constraint_Error => null; |
|||
end; |
|||
end Print; |
|||
procedure New_Line(Cal: Calendar) is |
|||
begin |
|||
Ada.Text_IO.New_Line; |
|||
end New_Line; |
|||
procedure Put_String(Cal: Calendar; S: String) is |
|||
begin |
|||
Ada.Text_IO.Put(S); |
|||
end Put_String; |
|||
procedure Print_Line_Centered(Cal: Calendar'Class; Line: String) is |
|||
Width : constant Positive := Cal.Columns*20 |
|||
+ (Cal.Columns-1)*Cal.Space_Between_Columns |
|||
+ Cal.Left_Space; |
|||
begin |
|||
if Line'Length >= Width-1 then |
|||
Cal.Put_String(Line); |
|||
Cal.New_Line; |
|||
else |
|||
Print_Line_Centered(Cal, " " & Line & " "); |
|||
end if; |
|||
end Print_Line_Centered; |
|||
function Init_80(Des: Description := Default_Description) return Calendar is |
|||
X: Calendar:= |
|||
(Columns => 3, Rows => 4, Space_Between_Columns => 4, |
|||
Left_Space => 1, |
|||
Weekday_Rep => Des.Weekday_Rep, |
|||
Month_Rep => Des.Month_Rep |
|||
); |
|||
begin |
|||
return X; |
|||
end Init_80; |
|||
function Init_132(Des: Description := Default_Description) return Calendar is |
|||
X: Calendar:= |
|||
(Columns => 6, Rows => 2, Space_Between_Columns => 2, |
|||
Left_Space => 1, |
|||
Weekday_Rep => Des.Weekday_Rep, |
|||
Month_Rep => Des.Month_Rep |
|||
); |
|||
begin |
|||
return X; |
|||
end Init_132; |
|||
end Printable_Calendar;</lang> |
|||
The main program is not extremely simple: |
|||
<lang Ada>with Printable_Calendar; |
|||
procedure Cal is |
|||
C: Printable_Calendar.Calendar := Printable_Calendar.Init_80; |
|||
begin |
|||
C.Print_Line_Centered("[reserved for Snoopy]"); |
|||
C.New_Line; |
|||
C.Print(1969, "Nineteen-Sixty-Nine"); |
|||
end Cal;</lang> |
|||
Here is the output: |
|||
<pre> [reserved for Snoopy] |
|||
Nineteen-Sixty-Nine |
|||
January February March |
|||
Mo Tu We Th Fr Sa So Mo Tu We Th Fr Sa So Mo Tu We Th Fr Sa So |
|||
1 2 3 4 5 1 2 1 2 |
|||
6 7 8 9 10 11 12 3 4 5 6 7 8 9 3 4 5 6 7 8 9 |
|||
13 14 15 16 17 18 19 10 11 12 13 14 15 16 10 11 12 13 14 15 16 |
|||
20 21 22 23 24 25 26 17 18 19 20 21 22 23 17 18 19 20 21 22 23 |
|||
27 28 29 30 31 24 25 26 27 28 24 25 26 27 28 29 30 |
|||
31 |
|||
April May June |
|||
Mo Tu We Th Fr Sa So Mo Tu We Th Fr Sa So Mo Tu We Th Fr Sa So |
|||
1 2 3 4 5 6 1 2 3 4 1 |
|||
7 8 9 10 11 12 13 5 6 7 8 9 10 11 2 3 4 5 6 7 8 |
|||
14 15 16 17 18 19 20 12 13 14 15 16 17 18 9 10 11 12 13 14 15 |
|||
21 22 23 24 25 26 27 19 20 21 22 23 24 25 16 17 18 19 20 21 22 |
|||
28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29 |
|||
30 |
|||
July August September |
|||
Mo Tu We Th Fr Sa So Mo Tu We Th Fr Sa So Mo Tu We Th Fr Sa So |
|||
1 2 3 4 5 6 1 2 3 1 2 3 4 5 6 7 |
|||
7 8 9 10 11 12 13 4 5 6 7 8 9 10 8 9 10 11 12 13 14 |
|||
14 15 16 17 18 19 20 11 12 13 14 15 16 17 15 16 17 18 19 20 21 |
|||
21 22 23 24 25 26 27 18 19 20 21 22 23 24 22 23 24 25 26 27 28 |
|||
28 29 30 31 25 26 27 28 29 30 31 29 30 |
|||
October November December |
|||
Mo Tu We Th Fr Sa So Mo Tu We Th Fr Sa So Mo Tu We Th Fr Sa So |
|||
1 2 3 4 5 1 2 1 2 3 4 5 6 7 |
|||
6 7 8 9 10 11 12 3 4 5 6 7 8 9 8 9 10 11 12 13 14 |
|||
13 14 15 16 17 18 19 10 11 12 13 14 15 16 15 16 17 18 19 20 21 |
|||
20 21 22 23 24 25 26 17 18 19 20 21 22 23 22 23 24 25 26 27 28 |
|||
27 28 29 30 31 24 25 26 27 28 29 30 29 30 31 </pre> |
|||
To get a 132-character-wide output, you just have to replace "Init_80" by "Init_132" in the main program. |
|||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |