code: def parse_datetime(value):
      if value is None:
          return None
      def _get_fixed_timezone(offset):
          if isinstance(offset, timedelta):
              offset = offset.seconds // 60
          sign = '-' if offset < 0 else '+'
          hhmm = '%02d%02d' % divmod(abs(offset), 60)
          name = sign + hhmm
          return pytz.FixedOffset(offset, name)
      DATETIME_RE = re.compile(
          r'(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})'
          r'[T ](?P<hour>\d{1,2}):(?P<minute>\d{1,2})'
          r'(?::(?P<second>\d{1,2})(?:\.(?P<microsecond>\d{1,6})\d{0,6})?)?'
          r'(?P<tzinfo>Z|[+-]\d{2}(?::?\d{2})?)?$'
      )
      match = DATETIME_RE.match(value)
      if match:
          kw = match.groupdict()
          if kw['microsecond']:
              kw['microsecond'] = kw['microsecond'].ljust(6, '0')
          tzinfo = kw.pop('tzinfo')
          if tzinfo == 'Z':
              tzinfo = pytz.UTC
          elif tzinfo is not None:
              offset_mins = int(tzinfo[-2:]) if len(tzinfo) > 3 else 0
              offset = 60 * int(tzinfo[1:3]) + offset_mins
              if tzinfo[0] == '-':
                  offset = -offset
              tzinfo = _get_fixed_timezone(offset)
          kw = {k: int(v) for k, v in six.iteritems(kw) if v is not None}
          kw['tzinfo'] = tzinfo
          return datetime(**kw)