parse_time Function

public pure function parse_time(timestring) result(fields)

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: timestring

Return Value type(time_fields)


Calls

proc~~parse_time~~CallsGraph proc~parse_time parse_time proc~is_valid_time~2 is_valid_time proc~parse_time->proc~is_valid_time~2 proc~is_whole_number is_whole_number proc~parse_time->proc~is_whole_number proc~parse_timezone_offset parse_timezone_offset proc~parse_time->proc~parse_timezone_offset proc~read_whole_number read_whole_number proc~parse_time->proc~read_whole_number proc~undelimit undelimit proc~parse_time->proc~undelimit proc~is_valid_hour is_valid_hour proc~is_valid_time~2->proc~is_valid_hour proc~is_valid_millisecond is_valid_millisecond proc~is_valid_time~2->proc~is_valid_millisecond proc~is_valid_minute is_valid_minute proc~is_valid_time~2->proc~is_valid_minute proc~is_valid_second is_valid_second proc~is_valid_time~2->proc~is_valid_second proc~is_valid_timezone_offset is_valid_timezone_offset proc~is_valid_time~2->proc~is_valid_timezone_offset proc~parse_timezone_offset->proc~is_whole_number proc~parse_timezone_offset->proc~read_whole_number proc~read_whole_number_indexed read_whole_number_indexed proc~read_whole_number->proc~read_whole_number_indexed proc~is_between is_between proc~is_valid_hour->proc~is_between proc~is_valid_millisecond->proc~is_between proc~is_valid_minute->proc~is_between proc~is_valid_second->proc~is_between proc~read_whole_number_indexed->proc~is_whole_number proc~get_integer_digit_from_string get_integer_digit_from_string proc~read_whole_number_indexed->proc~get_integer_digit_from_string proc~get_integer_digit get_integer_digit proc~get_integer_digit_from_string->proc~get_integer_digit

Called by

proc~~parse_time~~CalledByGraph proc~parse_time parse_time proc~construct_iso8601time construct_ISO8601Time proc~construct_iso8601time->proc~parse_time proc~test_parse_time~2 test_parse_time proc~test_parse_time~2->proc~parse_time interface~iso8601time ISO8601Time interface~iso8601time->proc~construct_iso8601time proc~test_construct_iso8601time test_construct_ISO8601Time proc~test_construct_iso8601time->proc~construct_iso8601time

Source Code

   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