docs: def _timestamp_handler(c, ctx):
      """Handles timestamp values. Entered after the year component has been completed; tokenizes the remaining
      components.
      """
      assert c in _TIMESTAMP_YEAR_DELIMITERS
      ctx.set_ion_type(IonType.TIMESTAMP)
      if len(ctx.value) != 4:
          _illegal_character(c, ctx, 'Timestamp year is %d digits; expected 4.' % (len(ctx.value),))
      prev = c
      c, self = yield
      trans = ctx.immediate_transition(self)
      state = _TimestampState.YEAR
      nxt = _DIGITS
      tokens = _TimestampTokens(ctx.value)
      val = None
      can_terminate = False
      if prev == _T:
          nxt += _VALUE_TERMINATORS
          can_terminate = True
      while True:
          is_eof = can_terminate and BufferQueue.is_eof(c)
          if c not in nxt and not is_eof:
              _illegal_character(c, ctx, 'Expected %r in state %r.' % ([_chr(x) for x in nxt], state))
          if c in _VALUE_TERMINATORS or is_eof:
              if not can_terminate:
                  _illegal_character(c, ctx, 'Unexpected termination of timestamp.')
              trans = ctx.event_transition(IonThunkEvent, IonEventType.SCALAR, ctx.ion_type, _parse_timestamp(tokens))
              if c == _SLASH:
                  trans = ctx.immediate_transition(_number_slash_end_handler(c, ctx, trans))
          else:
              can_terminate = False
              if c == _Z:
                  # Z implies UTC, i.e. +00:00 local offset.
                  tokens.transition(_TimestampState.OFF_HOUR).append(_ZERO)
                  tokens.transition(_TimestampState.OFF_MINUTE).append(_ZERO)
                  nxt = _VALUE_TERMINATORS
                  can_terminate = True
              elif c == _T:
                  nxt = _VALUE_TERMINATORS + _DIGITS
                  can_terminate = True
              elif c in _TIMESTAMP_DELIMITERS:
                  nxt = _DIGITS
              elif c in _DIGITS:
                  if prev == _PLUS or (state > _TimestampState.MONTH and prev == _HYPHEN):
                      state = _TimestampState.OFF_HOUR
                      val = tokens.transition(state)
                      if prev == _HYPHEN:
                          val.append(prev)
                  elif prev in (_TIMESTAMP_DELIMITERS + (_T,)):
                      state = _TimestampState[state + 1]
                      val = tokens.transition(state)
                      if state == _TimestampState.FRACTIONAL:
                          nxt = _DIGITS + _TIMESTAMP_OFFSET_INDICATORS
                  elif prev in _DIGITS:
                      if state == _TimestampState.MONTH:
                          nxt = _TIMESTAMP_YEAR_DELIMITERS
                      elif state == _TimestampState.DAY:
                          nxt = (_T,) + _VALUE_TERMINATORS
                          can_terminate = True
                      elif state == _TimestampState.HOUR:
                          nxt = (_COLON,)
                      elif state == _TimestampState.MINUTE:
                          nxt = _TIMESTAMP_OFFSET_INDICATORS + (_COLON,)
                      elif state == _TimestampState.SECOND:
                          nxt = _TIMESTAMP_OFFSET_INDICATORS + (_DOT,)
                      elif state == _TimestampState.FRACTIONAL:
                          nxt = _DIGITS + _TIMESTAMP_OFFSET_INDICATORS
                      elif state == _TimestampState.OFF_HOUR:
                          nxt = (_COLON,)
                      elif state == _TimestampState.OFF_MINUTE:
                          nxt = _VALUE_TERMINATORS
                          can_terminate = True
                      else:
                          raise ValueError('Unknown timestamp state %r.' % (state,))
                  else:
                      # Reaching this branch would be indicative of a programming error within this state machine.
                      raise ValueError('Digit following %s in timestamp state %r.' % (_chr(prev), state))
                  val.append(c)
          prev = c
          c, _ = yield trans