PROGRAM CADTND;
{$nomain}
{$nowalkback}

{ 
  File: [22,310]CADTND.PAS       

  Last Edit: 23-JUN-1988 22:04:15 

  History:  2-Jun-87.  Bob Thomas.	 Created.
	 23-JUN-1988 21:55:20  - JMB PA3UTL upgrade.

}


%include PAS$EXT:General.typ;
%include PAS$EXT:Slen.ext;


Procedure CADTND(var A_date:PACKED ARRAY [lo..Hi:integer] OF char;
	        { 9 char DEC style date DD-MMM-YY }
		 var I_date: Int_date
                { 3 integer date YY MM DD }
                ); external;


{*USER*

.hl 2 CADTND - Convert Ascii Date To Numeric Date

The CADTND routine will convert a  DEC format ascii date (DD-MMM-YY) into 
a numeric (3 integer) date.  It can also be used to validate an Ascii date,
as the conversion will fail for invalid dates.  The date array I_DATE 
will be returned as all zeros if an invalid Ascii date is supplied.

}

{*TECH*

The ascii date variable A_date can be any type 0 or type 1 string with length
= 9 and a DEC style Ascii date in characters 1-9.

The MMM (month) portion of the ascii date must consist of a three letters
that can be of upper or lower (or mixed ) case (e.g. MAY, Jun, jul ). 

Single digit days or years must be preceded with a zero (ie. 06-May-09).  DEC
date conversion routines suppress the zero and shift the date string left
one character for single digit days, however the DTR date conversion routines 
like the leading zero.  So we went with the DTR convention.

If the date is valid, a nonzero integer date array will be returned. If the 
date is invalid, a zero filled date array will be returned.

}

PROCEDURE CADTND;

type
  month_table_type = packed array [1..12] of ch3;

const
  month_table = month_table_type ('JAN','FEB','MAR','APR','MAY','JUN',
                                  'JUL','AUG','SEP','OCT','NOV','DEC');

Var
 Temp_date: int_date;
 valid: boolean;
 i: integer;
 month: ch3;

Begin

{First validate the form of A_DATE, insure that it contains two digits,
a hyphen, three letters, a hyphen and two digits }

valid:=true;

{check the string length}
If Slen(A_date)<>9 then valid:=false;

{check that positions 1 and 2 contain a digit}
If (A_date[1]<'0') OR (A_date[1]>'9') then valid:=false;
If (A_date[2]<'0') OR (A_date[2]>'9') then valid:=false;


{check that positions 3 and 7 contain a hyphen}
If (A_date[3]<>'-') OR (A_date[7]<>'-') then valid:=false;

{check that positions 4-6 contain a upper or lower case letter and put them
into the variable "month" as upper case leters}
For i:=4 to 6 Do begin
   If (A_date[i]<'A') OR (A_date[i]>'z') then valid:=false;
   If (A_date[i]>'Z') AND (A_date[i]<'a') then valid:=false;
   If (A_date[i]>='A') AND (A_date[i]<='Z') then month[i-3]:=A_date[i];
   If (A_date[i]>='a') AND (A_date[i]<='z') then 
	month[i-3]:=chr(ord(A_date[i])-40b);
End;


{check that positions 8 and 9 contain a digit}
If (A_date[8]<'0') OR (A_date[8]>'9') then valid:=false;
If (A_date[9]<'0') OR (A_date[9]>'9') then valid:=false;

{if valid so far convert the day and year into integers}
If valid then begin
   temp_date.day:=(ord(A_date[1])-60b)*10+ord(A_date[2])-60b;
   temp_date.year:=(ord(A_date[8])-60b)*10+ord(A_date[9])-60b;
End;

{if valid so far convert the month into an integer}
If valid then begin
  valid:=false;
  For i:=1 to 12 Do begin
      If (month=month_table[i]) then begin
	valid:=true;
	Temp_date.month:=i;
      End;{if}
  End;{for}
End;{if}

{if valid so far check that the day of the month is valid}
if valid then begin
  Case Temp_date.month of
   1,3,5,7,8,10,12:
	Begin
	If (temp_date.day>31) OR (temp_date.day<1) then valid:=false;
	End;
   4,6,9,11:
	Begin
	If (temp_date.day>30) OR (temp_date.day<1) then valid:=false;
	End;
   2:
	Begin
	If (temp_date.day>29) OR (temp_date.day<1) OR
		((Temp_date.day=29) AND (NOT(temp_date.year MOD 4=0)))
		{this is valid until the year 2100}
	   then valid:=false;
	End;
   Otherwise
	Begin
	valid:=false;
	end;
  End;{case}
End;{if}
	
{If valid, transfer contents of temp_date to output var I_date. Otherwise
set it to zero}

if valid
  then I_date:= temp_date
  else begin
	I_date.day:=0;
	I_date.month:=0;
	I_date.year:=0;
  End;{else}
End;{if}

