Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
character(len=*), | intent(in) | :: | timestring |
pure function parse_time(timestring) result(fields) character(len=*), intent(in) :: timestring type(time_fields) :: fields integer, parameter :: LENGTH = 6 character, parameter :: TIME_PREFIX = 'T' ! debug character, parameter :: DELIMITER = ':' character, parameter :: DECIMAL_POINT = '.' integer, parameter :: FIELDWIDTH = 2 integer, parameter :: MS_WIDTH = 3 integer, parameter :: PSTART = 1 integer, parameter :: HSTART = 1 integer, parameter :: HSTOP = 2 integer, parameter :: MSTART = 3 integer, parameter :: MSTOP = 4 integer, parameter :: SSTART = 5 integer, parameter :: SSTOP = 6 integer, parameter :: MS_START = 7 integer, parameter :: MS_STOP = 9 logical :: has_millisecond integer :: pos character(len=len(timestring)) :: undelimited character :: c character(len=LENGTH) :: offset integer :: offset_minutes integer :: undelimited_length integer :: signum has_millisecond = .FALSE. offset_minutes = INVALID fields = time_fields(-1, -1, -1, -1, -1) ! Check for mandatory Time prefix pos = PSTART if(.not. timestring(pos:pos) == 'T') then fields%is_valid_ = .FALSE. return end if ! Find timezone portion pos = scan(timestring, '-Z+') if(.not. pos > 0) then fields%is_valid_ = .FALSE. return end if c = timestring(pos:pos) ! Check first character of timezone portion select case(c) case('Z') signum = 0 case('-') signum = -1 case('+') signum = +1 case default fields%is_valid_ = .FALSE. return end select ! Set timezone offset if(signum == 0) then fields%timezone_offset_ = Z fields%is_valid_ = pos == len(timestring) else offset = undelimit(timestring(pos+1:len_trim(timestring)), DELIMITER) offset_minutes = parse_timezone_offset(offset, FIELDWIDTH) fields%timezone_offset_ = signum * offset_minutes fields%is_valid_ = is_whole_number(offset_minutes) end if if(.not. fields%is_valid_) return ! Select portion starting at fields%hour and ending before timezone undelimited = adjustl(timestring(PSTART+1:pos-1)) ! Remove delimiter and decimal point undelimited=undelimit(undelimit(undelimited, DELIMITER), DECIMAL_POINT) undelimited_length = len_trim(undelimited) ! Check length of undelimited string with or without milliseconds if(undelimited_length == LENGTH) then fields%is_valid_ = .TRUE. elseif(undelimited_length == LENGTH+MS_WIDTH) then has_millisecond = .TRUE. fields%is_valid_ = .TRUE. else fields%is_valid_ = .FALSE. end if if(.not. fields%is_valid_) return ! Read time fields fields%hour_ = read_whole_number(undelimited(HSTART:HSTOP)) fields%minute_ = read_whole_number(undelimited(MSTART:MSTOP)) fields%second_ = read_whole_number(undelimited(SSTART:SSTOP)) if(has_millisecond) then fields%millisecond_ = read_whole_number(undelimited(MS_START:MS_STOP)) else fields%millisecond_ = 0 end if fields%is_valid_ = is_valid_time(fields) end function parse_time