CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      SUBROUTINE INPUT_TIME(START_OR_STOP,EPOCH,YEAR,DOY,MONTH,DAY,HOUR,MINUTE,SECOND)
C+
C
C FUNCTIONAL DESCRIPTION:
C
C    This routine prompts the user for a start or stop time in Gregorian units.
C    This time is converted to a SOHO epoch time (seconds since 1-JAN-1958) and
C    passed back to the calling routine along with the Gregorian time that the
C    user input.
C
C FORMAL ARGUMENTS:
C
C    START_OR_STOP:
C	CHAR(*)	  I	A string that is disaplyed along with the prompt to the
C			user.  This allows the caller to customize the prompt.
C			Typical values are 'Start' and 'Stop'.
C
C    EPOCH:
C	R*8	  O	Upon return will contain the time, as a REAL*8 floating
C			point number in SOHO Epoch format, that the user
C			entered. 
C
C    YEAR,DOY,MONTH,DAY,HOUR,MINUTE,SECOND:
C	I*4	  O	Upon return these will contain integer values
C			representing the time the user entered, in Gregorian
C			time format.
C
C INTERFACE:
C
!	INTERFACE
!	  SUBROUTINE INPUT_TIME(START_OR_STOP,EPOCH,YEAR,DOY,MONTH,DAY,HOUR,MINUTE,SECOND)
!	    CHARACTER(LEN=*), INTENT(IN) :: START_OR_STOP
!	    REAL(KIND=8), INTENT(OUT) :: EPOCH
!	    INTEGER, INTENT(OUT) :: YEAR,DOY,MONTH,DAY,HOUR,MINUTE,SECOND
!	  END SUBROUTINE INPUT_TIME
!	END INTERFACE
C
C COMMON BLOCKS:
C
C    None
C
C INCLUDE FILES:
C
C    None
C
C DESIGN:
C
C    Time make take one of two formats:
C	[yy]yy mmm dd [hhmm]
C	[yy]yy nnn [hhmm]
C    In the first format the three letter code mmm for the month is given
C    followed by the day of month.  In the second format the day of year is
C    specified after the year.  In both formats the year may be given as either
C    two or four digits; it is converted to the current century internally.
C    The brackets indicate optional parts.  If the time is not specified 0000
C    is used.
C
C    If an invalid date or time is entered a message will be displayed and
C    a STOP statement will be executed, halting the program.
C
C DETAIL DESIGN:
C
C    write prompt and read user response
C    scan input line, breaking into parts by spaces
C    convert parts into integers, allowing for two date/time formats
C    validate converted date/time components
C    convert date/time into Epoch format
C
C IMPLICIT INPUTS:
C
C    None
C
C IMPLICIT OUTPUTS:
C
C    None
C
C SIDE EFFECTS:
C
C    Writes a line to output stream.
C    Reads a line from input stream.
C    If time read is invallid STOPs program.
C
C CREATED:
C
C    28-MAR-1996     John Paquette
C
C This version:   2.1  2-APR-1996
C
C DEVELOPMENT HISTORY:
C 
C  Author       Date		Description of Change 
C  --------	-----------	--------------------- 
C  J. PAQUETTE  28-MAR-1996     Created (from INPUT_TIMES)
C  J. PAQUETTE   2-APR-1996     Reads dates/times in new format(s)
C  L. Bleau	 2-APR-1996     check for case where empty line is read; add
C				ERR= clause to READ statements
C  L. Bleau	30-APR-1999	added comments
C  L. Bleau	 5-NOV-1999	added comments
C-
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CDEC$ IDENT '2.1'
      IMPLICIT NONE
      INTEGER*4 YEAR,MONTH,DAY,HOUR,MINUTE,SECOND,DOY,NUMBER,NCH,NEXT
      INTEGER*4 DATEPARTS_LEN(4)
      REAL*8 EPOCH
      LOGICAL ERROR
      CHARACTER*1 DATEPARTS_TYPE(4)
      CHARACTER*3 ASCII_MONTH(12)/'JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC'/
      CHARACTER*4 DATEPARTS(4)
      CHARACTER*132 INSTRING
      CHARACTER*(*) START_OR_STOP
C
C Prompt for time
C
      WRITE(6, 100) START_OR_STOP
 100  FORMAT(3X, A,' Time (e.g. 96 FEB 29 1230  or  1996 60 1230):'$)
C
C Read it in (as a character string)
C
      READ(5,200) NCH, INSTRING
 200  FORMAT(Q,A)
C
      IF(NCH.EQ.0)GOTO 900
C
C Call a routine to break the character string into pieces
C
      CALL SCANNER(INSTRING(1:NCH), ' ,', DATEPARTS, DATEPARTS_LEN, DATEPARTS_TYPE, 4, NUMBER)
C
C If there aren't at least 2 pieces in the date/time that they specified, they have made an error
C
      IF(NUMBER.LT.2)GOTO 900
C
C Get year
C      
      READ(DATEPARTS(1)(1:DATEPARTS_LEN(1)),210,ERR=900) YEAR
 210  FORMAT(I)
C
C Simple error checking
C
      IF(YEAR.LT.0 .OR. YEAR.GT.2030)THEN
        WRITE(6, 220)
 220    FORMAT(3X,'*** Error! One of your input values is out of range. Program terminated.***')
        STOP
      ENDIF 
C
C Allow for 2 or 4 digit years
C
      IF(YEAR.LT.30)THEN
        YEAR = YEAR + 2000
      ELSEIF(YEAR.LE.99)THEN
        YEAR = YEAR + 1900
      ENDIF
C
C Get month (if the second part of the date is alphabetic)
C
      IF(DATEPARTS_TYPE(2) .EQ. 'A')THEN
C
C Make sure that we have an uppercase month value
C
        CALL STR$UPCASE(DATEPARTS(2),DATEPARTS(2))
C
C Convert the ASCII 3-letter month to a number 
C
        MONTH = 1
        DO 230 WHILE(DATEPARTS(2)(1:3) .NE. ASCII_MONTH(MONTH))
          MONTH = MONTH + 1
C
C Simple error checking
C
          IF(MONTH .GT. 12)THEN
            WRITE(6,220)
            STOP
          ENDIF
  230   CONTINUE
C
C Get day
C
        READ(DATEPARTS(3)(1:DATEPARTS_LEN(3)),210,ERR=900) DAY
C
C Simple error checking
C
        IF(DAY.LT.1 .OR. DAY.GT.31)THEN
          WRITE(6,220)
          STOP
        ENDIF
C
C Convert month and day to DOY
C
        CALL CNVRT_YRMONDAY_TO_YEARDAY(YEAR, MONTH, DAY, DOY)       
        NEXT = 4
C
C Get day of year (if the second part of the date is an integer)
C
      ELSEIF(DATEPARTS_TYPE(2) .EQ. 'I')THEN
        READ(DATEPARTS(2)(1:DATEPARTS_LEN(2)),210,ERR=900) DOY
C
C Convert DOY to month and day 
C
        CALL CNVRT_YRDY_TO_YRMNDY(YEAR, DOY, MONTH, DAY)       
        NEXT = 3
      ELSE
C
C If we have neither an alphabetic nor an integer value for DATEPARTS(2), then
C we have an error.
C
        GOTO 900
      ENDIF
C
C Get the hour and minute. If they are absent, then set them both to 0
C
      IF(NUMBER .GE. NEXT)THEN
        READ(DATEPARTS(NEXT),240,ERR=900) HOUR,MINUTE
 240    FORMAT(2I2)
      ELSE
        HOUR = 0
        MINUTE = 0
      ENDIF
C
C Second is always 0
C
      SECOND = 0
C
C Simple error checking
C
      ERROR = .FALSE.
      IF(MONTH.LT.1 .OR. MONTH.GT.12)  ERROR = .TRUE.
      IF(DAY.LT.1 .OR. DAY.GT.31)      ERROR = .TRUE.
      IF(HOUR.LT.0 .OR. HOUR.GT.24)    ERROR = .TRUE.
      IF(MINUTE.LT.0 .OR. MINUTE.GT.59)ERROR = .TRUE.
      IF(ERROR)THEN
        WRITE(6, 220)
        STOP
      ENDIF 
C
C Convert this to an epoch time
C
      CALL SOHO_GREG_TO_EPOCH(YEAR,DOY,HOUR,MINUTE,SECOND,EPOCH)
C
C Finished. Pass it all back.
C
      RETURN
C
C Come here for errors
C
 900  WRITE(6,905)
 905  FORMAT(' ***Incorrect date. Execution Terminated.***')
      STOP
      END 
