c Date conversion function (part of DTC), derived from DATMUN,
c except decodes the values directly into DEFDAT and shrinks LINE,
c rather than schlep LINE back and forth to kingdom come.
c
c Modified 850422, CG, to restrict values of month/day/year
c
c modified 850325, 850726 & 850731, CG, to allow any of the following:
c	d{d}/m{m}/{y}y, d, dd, dmm, ddmm, dmmyy, ddmmyy, dmmyyyy, ddmmyyyy
c							for D or W functions
c	m{m}/{y}y, m, mm, myy, mmyy, mmyyyy, myyyy	for M
c	y, yy, yyy, yyyy				for Y
c
c plus dd-mon-yy, dd-mm-yy, dd-xii-yy formats
c
c function:
c  Convert a line starting with a date of form
c	mmddyy OR mm/dd/yy OR dd-mon-yy OR dd-romn-yy
c  to binary equivalents, and remove from line, copying binary values
c  to DEFDAT in common.
c
c  Leaves whatever follows the date alone.
c  Added for DTC to not have to use such a crock date
c  format as the original; too hard to use otherwise.

	Subroutine dtcdatcvt (nf)		! (line,nf)
c
	implicit none
c
	integer nf				! Number of fields expected
c
	include 'comdtc.inc/nolist'
c
	byte nb, l1, l2, l3, l4, lxx(4), work(icmln), tb6(6), ln1  !,
c
	integer lm(12)		! lengths of months (30 days hath Sept ...)
	1 /31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/
c
	integer minln(12)	! Min chars to recognize month names
	1 /2, 1, 3, 2, 3, 3, 3, 2, 1, 1, 1, 1/

	character*4 rch, ! Decode month names, or European style w/ Roman months
	1 mab(12) / 'JANU', 'FEBR', 'MARC', 'APRI', 'MAY ', 'JUNE',
	2	    'JULY', 'AUGU', 'SEPT', 'OCTO', 'NOVE', 'DECE'/,
	3 rom(12) / 'I   ', 'II  ', 'III ', 'IV  ', 'V   ', 'VI  ',
	4	    'VII ', 'VIII', 'IX  ', 'X   ', 'XI  ', 'XII '/

	integer i, k, kkk, n, nn, ix, ixyr, ixmo, ixdy, nfd,
	1	ifnb, lnb, lcount

	logical longyr			! If year entered as 3 chars or more

	integer*2 iwk(42), lw1		! 2 chars at a time
c
	integer*4 ll1

	equivalence (line, ln1, lw1),
	1 (ll1, rch, lxx), (work, iwk)
c
	integer icvt10, icur
	byte ich

	include 'stmtfunc.for/nolist'

	icvt10(icur, ich) = (icur * 10) + icvtbn1(ich) ! conversion function stage

c Begin code

	longyr = .false.		! set default of century calculation

c Initialize default values for omitted fields

	ixyr = ibigyr			! Copy current values
	ixmo = idmo			! from common
	ixdy = iddy

	if (numeric(ln1)) then		! Dates must start with number

	    work(1) = ln1		! Copy first character
	    ix = icvtbn1(ln1)		! Compute value on the fly
c
	    do n = 2, (nf * 2) + 2	! Allow [mm][dd][yyyy]
c
		l1 = line(n)		! Copy current character

		if (l1 .eq. '/')	! Field separators: slash
	1	    go to 100		! for mm/dd/yy form

		if (l1 .eq. '-')	! .. dash
	1	    go to 200		! for dd-mmm-yy form

		if ((l1 .eq. ':') .or. (l1 .eq. '>'))
	1	    go to 999		! hour-string first, return default values

		if (.not. numeric(l1))	! anything else:
	1	    go to 300		! mmddyy, minus some characters, fake whatever is required

		work(n) = l1		! Don't recopy
		ix = icvt10(ix, l1)	! continue conversion 

	    end do

	    n = (nf * 2) + 3		! Set shrink value if no delimiter

	    go to 300			! Go convert it

	else if ((ln1 .eq. '+') .or. (ln1 .eq. '-')) then
	    k = incmod			! Save current value
	    call dtcdatinc		! Convert incremental date
	    incmod = k			! Restore
	else if (ln1 .eq. '=') then
	    kkk = 1			! Place holder, strip only, date n/c
	    go to 950
	end if				! (don't want to reformat whole file)

	go to 999			! All done here

c handle mm/dd or mm/dd/yy{yy} (for D, W, M or Y)
c or mm/yy{yy} (for M or Y)

 100	continue	! Here for '/' encountered in first scan loop

	k = n + 1	! next character to look at
	l1 = line(k)
	if (.not. numeric(l1)) go to 300	! nnnn/x ???

	ixmo = ix		! First field is always month in "/" notation

	ix = icvtbn1(l1)	! Start 2nd conversion

	do n = k + 1, 20	! should be plenty

	    l1 = line(n)	! get character
	    if (l1 .eq. '/') go to 110	! Found second /
	    if (.not. numeric(l1)) go to 120	! End of scan
	    ix = icvt10(ix, l1)	! convert

	end do

	n = 21			! Set it

 120	if (nf .eq. 3) then
	    ixdy = ix		! 2nd field is day
	else
	    ixyr = ix		! .. year
	    longyr = ((n - k) .gt. 2)
	end if	

	go to 900

 110	l1 = line(n+1)		! Found 2nd slash, check for third field
	if (.not. numeric(l1)) go to 120	! left field!

	k = n + 1

	ixdy = ix			! 2nd has to be day

	ixyr = icvtbn1(l1)		! Start 3rd conversion (year)

	do n = k + 1, 20		! get more numerics

	    l1 = line(n)
	    if (.not. numeric(l1)) go to 910
	    ixyr = icvt10(ixyr, l1)

	end do

	n = 21				! mark next character

	go to 910			! set for SHRINK

c handle dd-mon-yy, dd-mm-yy, or dd-roman-yy

 200	continue	! Here for '-' in first scan loop

	ixdy = ix	! Copy converted day field

	rch = '    '	! initialize for alpha month name, or Roman numerals

	k = n + 1	! next char after "-"

	l1 = line(k)

	if (numeric(l1)) then		! European format dd-mm-yy

	    ixmo = icvtbn1(l1)		! go for it directly

	    do n = k + 1, 20

		l1 = line(n)

		if (.not. numeric(l1)) go to 210

		ixmo = icvt10(ixmo, l1)

	    end do

	    n = 21

	else if (alpha(l1)) then

	    lxx(1) = l1 .and. '5F'X	! Set first char for name or roman

	    lcount = 1

	    do nn = k + 1, k + 6		! should find "-" by then

		l1 = line(nn)
		if (l1 .eq. '-') go to 230	! Start search
		if (.not. alpha(l1)) go to 230	! also terminate
		if (lcount .lt. 4) then		! room for at least one more
		    lcount = lcount + 1
		    lxx(lcount) = l1 .and. '5F'X ! Copy character
		end if
	    end do

	    nn = k + 6

 230	    continue

	    do i = 1, 12			! Loop over months
		if (rch .eq. rom(i)) go to 250	! Found match in roman set
		if (lcount .ge. minln(i)) then
		    if (rch(1:lcount) .eq. mab(i)(1:lcount))
	1		go to 250		! Found match in alpha names
		end if

C Note: last two IF statements above replace original horrendous sequence of
c IF-THEN-ELSEs to see if month was J then A, or F, or M then A then R, etc !

	    end do

c Fell out of loop, leave current month

	    go to 300		! Unknown month or roman seq, back up before "-"

 250	    ixmo = i		! iwk(1) = icvtbcd(i)
	    n = nn		! Accept characters

	else			! "-" followed by non alphanumeric
	    go to 300

	end if

 210	if (l1 .ne. '-') go to 900	! See if year follows

	k = n + 1
	l1 = line (k)

	if (.not. numeric(l1)) go to 910	! First dash is left
	ixyr = icvtbn1(l1)

	do n = k + 1, 30

	    l1 = line (n)

	    if (.not. numeric(l1)) go to 910

	    ixyr = icvt10(ixyr, l1)

	end do

	n = 31

 910	longyr = ((n - k) .gt. 2)	! Set logic value

	go to 900

 300	continue			! Short string found, fix it up

	nfd = n/2			! Number of 2-char groups found

	longyr = (nfd .gt. nf)		! check for default or forced century

	if ((n .and. 1) .eq. 0) then	! Example: n = 5 for 4 chars found (0 mod 2)
	    work(1) = '0'		! Force even number of characters
	    do i = 2, n
		work(i) = line(i - 1)	! Shift line over by 1
	    end do
	end if

	go to (310, 320, 330) nf	! Dispatch on # expected fields
	go to 900			! Bad value ???

 310	ixyr = ix			! take year: Y [yy]
	go to 900			! End case

 320	ixmo = icvtbin(iwk(1))		! M mm
	if (nfd .eq. 2) ixyr = icvtbin(iwk(2))	! M {m}myy
	if (nfd .eq. 3) ixyr = mod(ix, 10000)	! M {m}myyyy
	go to 900			! End case

 330	if (nfd .eq. 1) ixdy = icvtbin(iwk(1)) ! D {d}d {only}

	if (nfd .ge. 2) then		! D [mm]dd[yy]
	    ixmo = icvtbin(iwk(1))	! D {m}mdd
	    ixdy = icvtbin(iwk(2))	! D {m}mdd
	end if

	if (nfd .eq. 3) ixyr = icvtbin(iwk(3))	! D {m}mddyy
	if (nfd .eq. 4) ixyr = mod(ix, 10000)	! D {m}mddyyyy

 900	continue			! common clean-up & return

	if ((ixyr .lt. 100) .and. (.not. longyr)) ! Check for 1-99 AD
	1   ixyr = ixyr + ((ibigyr/100)*100)	! add "current" century

	if (islpyr(ixyr))
	1 then
	    lm(2) = 29	! Set for Leap Years
	  else
	    lm(2) = 28	! reset for "common" years
	end if

	ibigyr = ixyr				! Explicit year
	idmo = min0(max0(ixmo, 1), 12)		! Limit values
	iddy = min0(max0(ixdy, 1), lm(idmo))	! ..

	kkk = n - 1			! Change index of next char to count

 950	idyr = mod(ibigyr, 100)			! Set value

	if (kkk .gt. 0)
	1 call shrink (kkk, ifnb, lnb)	! Unload the stuff we used

 999	return				! Miscellaneous exits

	end
