{ This is a complete collection of the various date routines,
set up for separate compilation under Pascal/Z, ver 3.2 or
later.
DATE.LIB contains the necessary subprogram calls for inclusion
in the main program.
Note that <progname> has to be substituted with the name of the
main program to be separately compiled.
The following global declarations must be made in the main
program:
TYPE string0 = string 0;
string255 = string 255;
byte = 0..255;
PROCEDURE setlength;
FUNCTION length;
}
PROCEDURE prompt (msg : string255);
CONST msglength = 12; { should be longer than longest message }
leader = '.'; { could be a space if desire }
endprompt = ' => ';
VAR count : integer;
esc : char;
begin
append (msg,' ');
if length(msg) < msglength then
for count := succ(length(msg)) to msglength do
append (msg,leader);
write (msg,endprompt)
end;
PROCEDURE getdate (msg : string255; VAR mo, da, yr : byte);
CONST yrspan = 89;
yrbase = 10;
VAR ch : char;
good : boolean;
temp : integer;
begin
repeat
good := true;
prompt (msg);
readln (mo,ch,da,ch,temp);
temp := temp mod 100 - yrbase;
if (da < 1) or (da > 31) or (mo < 1) or (mo >12)
or (temp < 0) or (temp > yrspan) then
begin
good := false;
writeln (' *** Bad date ***')
end
until good;
yr := temp
end;
FUNCTION makedate (msg : string255) : integer;
CONST yrbase = 10;
VAR days : integer;
da, mo, yr : byte;
str : string255;
begin
getdate (msg,mo,da,yr);
case mo of
1 : days := 0;
2 : days := 31;
3 : days := 59;
4 : days := 90;
5 : days := 120;
6 : days := 151;
7 : days := 181;
8 : days := 212;
9 : days := 243;
10 : days := 273;
11 : days := 304;
12 : days := 334;
end;
days := days + (yr*365) + (yr div 4) + da;
if ((yr + yrbase) mod 4 = 0) and (mo > 2) then days := days + 1;
makedate := days
end;
PROCEDURE rgetdate (msg : string255; minyr, maxyr : byte;
VAR mo, da, yr : byte);
CONST yrspan = 89;
yrbase = 10;
VAR ch : char;
good : boolean;
temp : integer;
begin
repeat
good := true;
prompt (msg);
readln (mo,ch,da,ch,temp);
temp := temp mod 100;
if (da < 1) or (da > 31) or (mo < 1) or (mo >12)
or (temp < minyr) or (temp > maxyr) then
begin
good := false;
writeln (' *** Bad date ***')
end
until good;
yr := temp - yrbase
end;
VAR days : integer;
da, mo, yr : byte;
str : string255;
begin
rgetdate (msg,minyr,maxyr,mo,da,yr);
case mo of
1 : days := 0;
2 : days := 31;
3 : days := 59;
4 : days := 90;
5 : days := 120;
6 : days := 151;
7 : days := 181;
8 : days := 212;
9 : days := 243;
10 : days := 273;
11 : days := 304;
12 : days := 334;
end;
days := days + (yr*365) + (yr div 4) + da;
if ((yr + yrbase) mod 4 = 0) and (mo > 2) then days := days + 1;
rmakedate := days
end;
PROCEDURE brkdate (days : integer; VAR mo, da, yr, weekday : byte);
CONST yrbase = 10;
yrfix = yrbase - 1;
VAR data, temp, adjust, yradj : integer;
begin
adjust := 1 + yrfix mod 4 + (((yrfix mod 28) div 4) * 5);
yradj := (yrbase mod 4) * 365;
weekday := (days + adjust) mod 7;
data := trunc((days + yradj) / 365.25) - yrbase mod 4;
yr := data + yrbase;
temp := days - (365 * data) - (data + yrfix mod 4) div 4;
mo := 0;
data := 0;
repeat
if (data < temp) then
begin
mo := mo + 1;
temp := temp - data
end;
case mo of
1,3,5,7,8,10,12 : data := 31;
4,6,9,11 : data := 30;
2 : if (yr mod 4 = 0) then data := 29
else data := 28
end
until (data >= temp) or (mo = 12);
da := temp
end;
FUNCTION dastrlong (days : integer; withday : boolean) : string255;
CONST zero = 48;
VAR day, mo, date, yr : byte;
str, str2 : string255;
begin
brkdate (days,mo,date,yr,day);
if withday then
begin
case day of
0 : str := 'Sunday';
********************************************************************************************************************************;
6 : str := 'Saturday'
end;
append (str,', ')
end
else setlength (str,0);
case mo of
1 : str2 := 'January';
2 : str2 := 'February';
3 : str2 := 'March';
4 : str2 := 'April';
5 : str2 := 'May';
6 : str2 := 'June';
7 : str2 := 'July';
8 : str2 := 'August';
9 : str2 := 'September';
10 : str2 := 'October';
11 : str2 := 'November';
12 : str2 := 'December'
end;
append (str,str2);
append (str,' ');
if (date > 9) then append (str,chr((date div 10) + zero));
append (str,chr((date mod 10) + zero));
append (str,', 19');
append (str,chr((yr div 10) + zero));
append (str,chr((yr mod 10) + zero));
dastrlong := str
end;
FUNCTION dastrshort (days : integer; withday : boolean) : string255;
CONST zero = 48;
VAR day, mo, date, yr : byte;
str, str2 : string255;
begin
brkdate (days,mo,date,yr,day);
if withday then
begin
case day of
0 : str := 'Sun';
1 : str := 'Mon';
2 : str := 'Tues';
3 : str := 'Wed';
4 : str := 'Thurs';
5 : str := 'Fri';
6 : str := 'Sat'
end;
append (str,', ')
end
else setlength (str,0);
case mo of
1 : str2 := 'Jan';
2 : str2 := 'Feb';
3 : str2 := 'Mar';
4 : str2 := 'Apr';
5 : str2 := 'May';
6 : str2 := 'June';
7 : str2 := 'July';
8 : str2 := 'Aug';
9 : str2 := 'Sept';
10 : str2 := 'Oct';
11 : str2 := 'Nov';
12 : str2 := 'Dec'
end;
append (str,str2);
append (str,' ');
if (date > 9) then append (str,chr((date div 10) +********************************************************************************************************************************chr((yr mod 10) + zero));
dastrshort := str
end;
FUNCTION strbyte (val : byte; withspace : boolean) : string255;
CONST zero = 48;
VAR ch : char;
str : string255;
begin
setlength (str,0);
if (val div 10 = 0) and withspace
then str := ' '
else str := chr (val div 10 + zero);
append (str,chr(val mod 10 + zero));
strbyte := str
end;
FUNCTION dastrfixed (days : integer; spaces : boolean) : string255;