FUNCTION STR2UTC, UTC, EXTERNAL=EXTERNAL, DMY=DMY, MDY=MDY, $ ERRMSG=ERRMSG ; ON_ERROR, 2 ; Return to the caller of this procedure if error occurs. MESSAGE='' ; Error message that is returned if ERRMSG keyword set. MONTHS = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', $ 'SEP', 'OCT', 'NOV', 'DEC'] ; ; Check the input array. ; IF N_PARAMS() NE 1 THEN BEGIN MESSAGE = 'Syntax: Result = STR2UTC( UTC )' ENDIF ELSE BEGIN IF DATATYPE(UTC,1) NE 'String' THEN MESSAGE = $ 'Input parameter to STR2UTC must be of type string.' ENDELSE IF MESSAGE NE '' THEN GOTO, HANDLE_ERROR ; ; Form the structure to be returned. ; DATE = {CDS_EXT_TIME, $ YEAR: 0, $ MONTH: 0, $ DAY: 0, $ HOUR: 0, $ MINUTE: 0, $ SECOND: 0, $ MILLISECOND: 0} ; ; If UTC is an array, then call this routine recursively to interpret each ; element individually. ; SZ = SIZE(UTC) IF SZ(0) GE 1 THEN BEGIN DATE = REPLICATE(DATE, N_ELEMENTS(UTC)) FOR I=0,N_ELEMENTS(UTC)-1 DO BEGIN DT = STR2UTC(UTC(I), /EXTERNAL, DMY=DMY, MDY=MDY, $ ERRMSG=ERRMSG) IF N_ELEMENTS(ERRMSG) NE 0 THEN $ IF ERRMSG(0) NE '' THEN RETURN, -1 DATE(I).YEAR = DT.YEAR DATE(I).MONTH = DT.MONTH DATE(I).DAY = DT.DAY DATE(I).HOUR = DT.HOUR DATE(I).MINUTE = DT.MINUTE DATE(I).SECOND = DT.SECOND DATE(I).MILLISECOND = DT.MILLISECOND ENDFOR DATE = REFORM(DATE, SZ(1:SZ(0))) GOTO, FINISH ENDIF ; ; Separate the input string into the date and time parts. Make sure not to ; confuse the "T" in "OCT" for the separator between the date and time parts ; in a CCSDS formatted string. ; UT = STRTRIM(UTC,2) START = STRPOS(UT,'OCT') IF START GE 0 THEN START = START + 3 ELSE START = 0 SEP = STRPOS(UT,'T',START) > STRPOS(UT,' ',START) IF SEP LT 0 THEN BEGIN DTSEP = STRPOS(UT,'-') > STRPOS(UT,'/') IF DTSEP GE 0 THEN BEGIN DT = UT TIME = '' END ELSE BEGIN DT = '' TIME = UT ENDELSE END ELSE BEGIN DT = STRMID(UT,0,SEP) TIME = STRTRIM(STRMID(UT,SEP+1,STRLEN(UT)-SEP-1),2) ENDELSE ; ; If the date contains the colon ":" character, then the date and time are ; reversed. ; IF STRPOS(DT,':') GE 0 THEN BEGIN TEMP = DT DT = TIME TIME = TEMP ENDIF ; ; Decide whether or not the date is given as year, month, day or as year, ; day-of-year. If the latter, calculate the month and day from the Modified ; Julian Day number. ; IF STRPOS(DT,'-') GE 0 THEN DTSEP = '-' ELSE DTSEP='/' DT = STR_SEP(DT,DTSEP) ; ; Day-of-year variation. ; IF N_ELEMENTS(DT) EQ 2 THEN BEGIN IF NOT (VALID_NUM(DT(0)) AND VALID_NUM(DT(1))) THEN BEGIN MESSAGE ='Unrecognizable date format - Year/DOY variation.' GOTO, HANDLE_ERROR ENDIF YEAR = FIX(DT(0)) DOY = FIX(DT(1)) IF DOY GE 1000 THEN BEGIN YEAR = FIX(DT(1)) DOY = FIX(DT(0)) ENDIF ; ; If the year is only two digits, then assume that the year is between 1950 ; and 2049. ; IF YEAR LT 100 THEN YEAR = ((YEAR + 50) MOD 100) + 1950 MJD = DATE2MJD(YEAR,DOY,ERRMSG=ERRMSG) IF N_ELEMENTS(ERRMSG) NE 0 THEN $ IF ERRMSG(0) NE '' THEN RETURN, -1 MJD2DATE,MJD,YEAR,MONTH,DAY,ERRMSG=ERRMSG IF N_ELEMENTS(ERRMSG) NE 0 THEN $ IF ERRMSG(0) NE '' THEN RETURN, -1 ; ; Year, month, and day variation. First select out the three components ; depending on the settings of the keywords. ; END ELSE IF N_ELEMENTS(DT) EQ 3 THEN BEGIN IF KEYWORD_SET(DMY) THEN BEGIN YEAR = DT(2) MONTH = DT(1) DAY = DT(0) END ELSE IF KEYWORD_SET(MDY) THEN BEGIN YEAR = DT(2) MONTH = DT(0) DAY = DT(1) END ELSE BEGIN YEAR = DT(0) MONTH = DT(1) DAY = DT(2) ; ; If the day field is four digits, and the month field has three characters, ; then assume that the VMS-style variation (DD-MMM-YYYY) is being used. ; IF (STRLEN(DAY) EQ 4) AND (STRLEN(MONTH) EQ 3) THEN $ BEGIN YEAR = DT(2) DAY = DT(0) ; ; Or if the day field is four digits, and the year field has three characters, ; then assume that the date is in MMM-DD-YYYY format. ; END ELSE IF (STRLEN(DAY) EQ 4) AND $ (STRLEN(YEAR) EQ 3) THEN BEGIN YEAR = DT(2) MONTH = DT(0) DAY = DT(1) ENDIF ENDELSE ; ; Convert the day to a number. ; IF NOT VALID_NUM(DAY) THEN BEGIN MESSAGE = 'Unrecognizable date format - day.' GOTO, HANDLE_ERROR END ELSE DAY = FIX(DAY) ; ; If the year is only two digits, then assume that the year is between 1950 ; and 2049. ; IF NOT VALID_NUM(YEAR) THEN BEGIN MESSAGE = 'Unrecognizable date format - year.' GOTO, HANDLE_ERROR END ELSE YEAR = FIX(YEAR) IF YEAR LT 100 THEN YEAR = ((YEAR + 50) MOD 100) + 1950 ; ; If the month is not a number, then assume that it is a month string. ; IF NOT VALID_NUM(MONTH) THEN BEGIN MONTH = STRUPCASE(STRMID(MONTH,0,3)) MONTH = (WHERE(MONTH EQ MONTHS) + 1)(0) IF MONTH EQ 0 THEN BEGIN MESSAGE = 'Unrecognizable date format - month.' GOTO, HANDLE_ERROR ENDIF END ELSE MONTH = FIX(MONTH) ; ; No date. ; END ELSE IF TOTAL(STRLEN(DT)) EQ 0 THEN BEGIN YEAR = 0 MONTH = 0 DAY = 0 END ELSE BEGIN MESSAGE = 'Unrecognizable date format.' GOTO, HANDLE_ERROR ENDELSE ; ; Parse the time. First remove any trailing Z characters. ; Z = STRPOS(TIME,'Z') IF Z GT 0 THEN TIME = STRMID(TIME,0,Z) TM = STRARR(3) TM(0) = STR_SEP(TIME,':') IF (STRLEN(TM(0)) GT 0) AND NOT VALID_NUM(TM(0)) THEN BEGIN MESSAGE = 'Unrecognizable date format - hour.' GOTO, HANDLE_ERROR END ELSE HOUR = FIX(TM(0)) IF (STRLEN(TM(1)) GT 0) AND NOT VALID_NUM(TM(1)) THEN BEGIN MESSAGE = 'Unrecognizable date format - minute.' GOTO, HANDLE_ERROR END ELSE MINUTE = FIX(TM(1)) IF (STRLEN(TM(2)) GT 0) AND NOT VALID_NUM(TM(2)) THEN BEGIN MESSAGE = 'Unrecognizable date format - second.' GOTO, HANDLE_ERROR END ELSE SECOND = DOUBLE(TM(2)) ; ; Store everything in the structure variable, and return. ; DATE.YEAR = YEAR DATE.MONTH = MONTH DATE.DAY = DAY DATE.HOUR = HOUR DATE.MINUTE = MINUTE MILLISECOND = ROUND(1000*SECOND) DATE.SECOND = MILLISECOND / 1000 DATE.MILLISECOND = MILLISECOND MOD 1000 ; ; If the EXTERNAL keyword is not set, then convert the date into the CDS ; internal format. ; FINISH: IF NOT KEYWORD_SET(EXTERNAL) THEN DATE = UTC2INT(DATE,ERRMSG=ERRMSG) IF N_ELEMENTS(ERRMSG) NE 0 THEN $ IF ERRMSG(0) EQ '' THEN ERRMSG = MESSAGE RETURN, DATE ; ; Error handling point. ; HANDLE_ERROR: IF N_ELEMENTS(ERRMSG) EQ 0 THEN MESSAGE, MESSAGE ERRMSG = MESSAGE RETURN, -1 ; END