def parse()

in src/pycalendar/duration.py [0:0]


    def parse(self, data):
        # parse format ([+]/-) "P" (dur-date / dur-time / dur-week)

        try:
            offset = 0
            maxoffset = len(data)

            # Look for +/-
            self.mForward = True
            if data[offset] in ('-', '+'):
                self.mForward = data[offset] == '+'
                offset += 1

            # Must have a 'P'
            if data[offset] != "P":
                raise ValueError("Duration: missing 'P'")
            offset += 1

            # Look for time
            if data[offset] != "T":
                # Must have a number
                num, offset = strtoul(data, offset)

                # Now look at character
                if data[offset] == "W":
                    # Have a number of weeks
                    self.mWeeks = num
                    offset += 1

                    # There cannot be anything else after this so just exit
                    if offset != maxoffset:
                        if ParserContext.INVALID_DURATION_VALUE != ParserContext.PARSER_RAISE:
                            return
                        raise ValueError("Duration: extra data after 'W'")
                    return
                elif data[offset] == "D":
                    # Have a number of days
                    self.mDays = num
                    offset += 1

                    # Look for more data - exit if none
                    if offset == maxoffset:
                        return

                    # Look for time - exit if none
                    if data[offset] != "T":
                        raise ValueError("Duration: no 'T' after 'D'")
                else:
                    # Error in format
                    raise ValueError("Duration: need 'D' or 'W'")

            # Have time
            offset += 1

            # Strictly speaking T must always be followed by time values, but some clients
            # send T with no additional text
            if offset == maxoffset:
                if ParserContext.INVALID_DURATION_VALUE == ParserContext.PARSER_RAISE:
                    raise ValueError("Duration: need number after 'T'")
                else:
                    return
            num, offset = strtoul(data, offset)

            # Look for hour
            if data[offset] == "H":
                # Get hours
                self.mHours = num
                offset += 1

                # Look for more data - exit if none
                if offset == maxoffset:
                    return

                # Parse the next number
                num, offset = strtoul(data, offset)

            # Look for minute
            if data[offset] == "M":
                # Get hours
                self.mMinutes = num
                offset += 1

                # Look for more data - exit if none
                if offset == maxoffset:
                    return

                # Parse the next number
                num, offset = strtoul(data, offset)

            # Look for seconds
            if data[offset] == "S":
                # Get hours
                self.mSeconds = num
                offset += 1

                # No more data - exit
                if offset == maxoffset:
                    return

            raise ValueError("Duration: invalid data after 'T'")

        except IndexError:
            raise ValueError("Duration: index error")