	SUBROUTINE DATEPARSE(dates,comp_date)
	IMPLICIT INTEGER(A-Z)
	parameter CLI$_PRESENT_G   = '0003FD19'X
	parameter CLI$_PRESENT_L   = '0003FD31'X

	INTEGER*4 str$position, beg_pos, end_pos, dash_pos
	INTEGER*4 cli$present, cli$get_value, icode, plus_day
	INTEGER*4 bin_date, idate(3), iopt, last_day, week_day
	CHARACTER run_input*84, run_check*15, run_range*15, char_date*11
	CHARACTER dash*1, comp_date*17
	CHARACTER*2 date_name(31)
	CHARACTER*15 run_dates(32)
	LOGICAL dates(31), exclude

	DATA date_name /'1','2','3','4','5','6','7','8','9',
     &                  '10','11','12','13','14','15','16','17',
     &                  '18','19','20','21','22','23','24','25',
     &                  '26','27','28','29','30','31'/

	index = 0
	comp_date = ' '

C
C	Get RUN_DAY information from the Command Language Interface.
C
	icode = cli$present('RUN_DATES')
	if (icode) then
	  do while (cli$get_value('RUN_DATES', run_input))
	    index = index + 1
	    icode = str$trim(run_dates(index),run_input,run_lth)
	    call str$upcase(run_dates(index),run_dates(index))
	  enddo
	else
	index = 1
	run_dates(index) = 'ALL'
	end if

	run_dates(index+1) = 'DONE'

	do 50 I = 1,31
	dates(I) = .FALSE.
50	continue
C
C	Get current date (both INTEGER and BINARY), AND last_day
C

	index = 0
100	index = index + 1
	idate(1) = 0
	bin_date = 0
	iopt     = 1
	CALL CVDATE(idate,bin_date,char_date,iopt)
	iopt     = 3
	CALL CVDATE(idate,bin_date,char_date,iopt)
	CALL ENDDATE(bin_date,last_day)

C
C	Now let's find out which month dates are acceptable.

	if  (run_dates(index).eq.'DONE') goto 1000
	run_check = run_dates(index)

C
C	Check to see if date requested is a delta.
C

	if (run_check(1:1).EQ.'+') then
	end_pos = str$position(run_check(1:LEN(run_check)),' ')
	end_pos = end_pos - 1
	comp_date = run_check(2:end_pos)
	goto 1000
	end if
C
C	CR says TODAY is acceptable. Also check for TODAY or TOMMOROW.
C

	if (run_check(1:3).eq.'TOD') then
	dates(idate(1)) = .TRUE.
	goto 100
	end if !RUN_DATES check for TODAY.

	if (run_check(1:3).EQ.'TOM') then
	 if (idate(1).EQ.last_day) then
	 dates(1) = .TRUE.
	 else
	 dates(idate(1)+1) = .TRUE.
	 end if  !RUN_DATES last_day check.
	goto 100
	end if  !RUN_DATES TOMORROW check.

C
C	Did they specify ANY or ALL ?
C

	if ((run_check(1:3).EQ.'ALL').OR.(run_check(1:3).EQ.'ANY')) then
	do 200 I = 1,last_day
	dates(i) = .TRUE.
200	continue
	goto 100
	end if !RUN_DATES check for ANY/ALL.

C
C	Did they select FIRST (and optionally with +N days).
C

	if ( (run_check(1:5).EQ.'FIRST').AND.(run_check(6:6).NE.'+') ) then
	dates(1) = .TRUE.
	goto 100
	end if !RUN_DATES check and no +days.

	if ( (run_check(1:5).EQ.'FIRST').AND.(run_check(6:6).EQ.'+') ) then
	 if (run_check(8:8).NE.' ') then
	 read(run_check(7:8),300) plus_day
300	 format(I)
	 else
	 read(run_check(7:7),300) plus_day
	 end if !PLUS_DAY integer check.

	  if (plus_day.GT.last_day) then
	  STOP '%DATEPARSE-F-PLUS FIRST+N cannot be > end-of-month'
	  end if !ERROR_CHECK for + > EOM.

	 dates(1+plus_day) = .TRUE.
	 goto 100
	 end if  !RUN_DATES FIRST+n check.

C
C	Did they select LAST (and optionally with -N days).
C

	if ( (run_check(1:4).EQ.'LAST').AND.(run_check(5:5).NE.'-') ) then
	dates(last_day) = .TRUE.
	goto 100
	end if !RUN_DATES LAST check and no +days.

	if ( (run_check(1:4).EQ.'LAST').AND.(run_check(5:5).EQ.'-') ) then
	if (run_check(7:7).NE.' ') then
	read(run_check(6:7),300) plus_day
	else
	read(run_check(6:6),300) plus_day
	end if !PLUS_DAY integer check.

	  if (last_day-plus_day.LT.1) then
	  STOP '%DATEPARSE-F-PLUS LAST-N cannot be < first-of-month'
	  end if !ERROR_CHECK for + < FOM.

	 dates(last_day-plus_day) = .TRUE.
	 goto 100
	 end if  !RUN_DATES LAST+n check.

C
C	Did they select FWD, MWD, or LWD.
C

	if (run_check(1:3).EQ.'FWD') then
	  if (idate(1).gt.1) then
	  idate(2) = idate(2)+1
	    if (idate(2).EQ.13) then
	     idate(3) = idate(3)+1
	     idate(2) = 1
	    end if  !idate YEAR CROSS check.
	  end if !idate FIRST DAY check
	  idate(1) = 1
	  iopt = 3
	  bin_date = 0
	  CALL CVDATE(idate,bin_date,char_date,iopt)
	  CALL DAYOFWEEK(bin_date,week_day)
	  if ((week_day.GT.1).AND.(week_day.LT.7)) dates(1) = .TRUE.
	  if (week_day.EQ.1) dates(2) = .TRUE.
	  if (week_day.EQ.7) dates(3) = .TRUE.
	 goto 100
 	end if  !RUN_DATES FWD check.

	if (run_check(1:3).EQ.'MWD') then
	  if (idate(1).gt.15) then
	  idate(2) = idate(2)+1
	    if (idate(2).EQ.13) then
	     idate(3) = idate(3)+1
	     idate(2) = 1
	    end if  !idate(YEAR CROSS)
	  end if !idate FIFTEENTH DAY check
	  idate(1) = 15
	  iopt = 3
	  bin_date = 0
	  CALL CVDATE(idate,bin_date,char_date,iopt)
	  CALL DAYOFWEEK(bin_date,week_day)
	  if ((week_day.GT.1).AND.(week_day.LT.7)) dates(15) = .TRUE.
	  if (week_day.EQ.1) dates(16) = .TRUE.
	  if (week_day.EQ.7) dates(17) = .TRUE.
	 goto 100
 	end if  !RUN_DATES FWD check.

	if (run_check(1:3).EQ.'LWD') then
	  idate(1) = last_day
	  iopt = 3
	  bin_date = 0
	  CALL CVDATE(idate,bin_date,char_date,iopt)
	  CALL DAYOFWEEK(bin_date,week_day)
	  if ((week_day.GT.1).AND.(week_day.LT.7)) dates(last_day) = .TRUE.
	  if (week_day.EQ.1) dates(last_day-2) = .TRUE.
	  if (week_day.EQ.7) dates(last_day-1) = .TRUE.
	 goto 100
 	end if  !RUN_DATES FWD check.

C
C	Is there a "-" at the start of a line? If so, the user wants
C	the following dates to be excluded.
C

	if (run_check(1:1).EQ.'-') then
	exclude = .TRUE.
	 do 400 I = 1,31
	 dates(I) = .TRUE.
400	 continue
	index = index + 1
	goto 100
	end if

C
C	Individual days were passed, so let's parse the string.
C	Dashes (-) infer ranges.
C

	BEG_POS = 1
	END_POS = LEN(run_check)
	DASH    = '-'

	dash_pos  = str$position(run_check(BEG_POS:END_POS),DASH)

C
C	String has no DASH ranges. Matched DATEs will simply be set .TRUE.
C

	if (dash_pos .EQ.0) then
	end_pos  = str$position(run_check(BEG_POS:END_POS),' ')
	 if (run_check(2:2).NE.' ') end_pos = end_pos - 1
	DO 500 I = 1,31
	if (run_check(1:end_pos).EQ.date_name(I)) then
	if (.NOT.exclude) dates(I) = .TRUE.
	if (exclude) dates(I) = .FALSE.
	goto 600
	end if !RUN_DATES valid check.
500	continue
	STOP '%DATEPARSE-F-RUN_DATES Invalid date selected!'
600	continue
	goto 100
	end if

C
C	String has DASHed ranges. The selected DATE range
C	will simply be turned on, or off, depending on the exclude option.
C

	if (dash_pos .NE.0) then
	CALL str$pos_extr(run_range,run_check,dash_pos+1,dash_pos+2)
	CALL str$pos_extr(run_check,run_check,1,dash_pos-1)
	if (LEN(run_check).EQ.1) CALL str$append(run_check,' ')
	 if (run_range(2:2).NE.' ')  then
	end_pos = 2
	else
	end_pos = 1
	end if !RUN_RANGE integer check.
700	continue
	do 800 I = 1,31
	if  (run_check(1:LEN(run_check)).EQ.date_name(I)) then
	  if  (.NOT. exclude) dates(I) = .TRUE.
	  if  (exclude) dates(I) = .FALSE.
	  goto 900
	end if  !DATE valid check.
800	continue
	STOP '%DATEPARSE-F-RUN_DATES Invalid date range selected!'
900	run_check = date_name(i+1)
	if(run_check.EQ.run_range(1:end_pos)) then
	  if  (.NOT. exclude) dates(I+1) = .TRUE.
	  if  (exclude) dates(I+1) = .FALSE.
	 goto 100
	 else
	 goto 700
	 end if  !RUN_RANGE selection check.
	end if  !dash_pos true check.

	STOP '%DATEPARSE-F-RUN_DAY Invalid input!'
1000	CONTINUE
	RETURN
	END
