Attepmt to parse an ISO8601 formatted duration based on a start datetime.

    Accepts a ``duration`` and a start ``datetime``. ``duration`` must be
    an ISO8601 formatted string.

    Returns a ``datetime.timedelta`` object.
1668
def parse_duration_with_start(start, duration):
    
    elements = _parse_duration_string(_clean(duration))
    year, month = _year_month_delta_from_elements(elements)

    end = start.replace(
        year=start.year + year,
        month=start.month + month
    )

    del elements['years']
    del elements['months']

    end += _timedelta_from_elements(elements)

    return start, end - start
90730
def _get_minutes(self, duration):
        
        if isinstance(duration, datetime.datetime):
            from_now = (duration - datetime.datetime.now()).total_seconds()
            from_now = math.ceil(from_now / 60)

            if from_now > 0:
                return from_now

            return

        return duration
1113054
def fromISO(cls, iso_string):

        ''' 
        '''

    # validate input
        title = 'ISO time input for labDT.fromISO'
        isopattern = re.compile('\d{4}-?\d{2}-?\d{2}[\s|T].*')
        if not isopattern.search(iso_string):
            raise ValueError('\n%s is not a valid ISO string.' % title)
        python_datetime = dTparser.parse(iso_string)
        if not python_datetime.tzinfo:
            raise ValueError('\n%s must have timezone info.' % title)

    # construct labDT from parsed string
        dT = python_datetime.astimezone(pytz.utc)
        dt_kwargs = {
            'year': dT.year,
            'month': dT.month,
            'day': dT.day,
            'hour': dT.hour,
            'minute': dT.minute,
            'second': dT.second,
            'microsecond': dT.microsecond,
            'tzinfo': dT.tzinfo
        }
        return labDT(**dt_kwargs)
1344236
def from_str(duration):
    """"""

    if duration in ("0", "+0", "-0"):
        return datetime.timedelta()

    pattern = re.compile('([\d\.]+)([a-zµμ]+)')
    total = 0
    sign = -1 if duration[0] == '-' else 1
    matches = pattern.findall(duration)

    if not len(matches):
        raise Exception("Invalid duration {}".format(duration))

    for (value, unit) in matches:
        if unit not in units:
            raise Exception(
                "Unknown unit {} in duration {}".format(unit, duration))
        try:
            total += float(value) * units[unit]
        except:
            raise Exception(
                "Invalid value {} in duration {}".format(value, duration))

    microseconds = total / _microsecond_size
    return datetime.timedelta(microseconds=sign * microseconds)
28822
def parse_duration(duration):
    
    duration = str(duration).upper().strip()

    elements = ELEMENTS.copy()

    for pattern in (SIMPLE_DURATION, COMBINED_DURATION):
        if pattern.match(duration):
            found = pattern.match(duration).groupdict()
            del found['time']

            elements.update(dict((k, int(v or 0))
                                 for k, v
                                 in found.items()))

            return datetime.timedelta(days=(elements['days'] +
                                            _months_to_days(elements['months']) +
                                            _years_to_days(elements['years'])),
                                      hours=elements['hours'],
                                      minutes=elements['minutes'],
                                      seconds=elements['seconds'])            
    
    return ParseError()
1031074
def from_iso_time(timestring, use_dateutil=True):
    
    if not _iso8601_time_re.match(timestring):
        raise ValueError('Not a valid ISO8601-formatted time string')
    if dateutil_available and use_dateutil:
        return parser.parse(timestring).time()
    else:
        if len(timestring) > 8:  # has microseconds
            fmt = '%H:%M:%S.%f'
        else:
            fmt = '%H:%M:%S'
        return datetime.datetime.strptime(timestring, fmt).time()
84353
private static Interval parseStartExtended(CharSequence startStr, CharSequence endStr) {
        Instant start = Instant.parse(startStr);
        if (endStr.length() > 0) {
            char c = endStr.charAt(0);
            if (c == 'P' || c == 'p') {
                PeriodDuration amount = PeriodDuration.parse(endStr);
                // addition of PeriodDuration only supported by OffsetDateTime,
                // but to make that work need to move point being added to closer to EPOCH
                long move = start.isBefore(Instant.EPOCH) ? 1000 * 86400 : -1000 * 86400;
                Instant end = start.plusSeconds(move).atOffset(ZoneOffset.UTC).plus(amount).toInstant().minusSeconds(move);
                return Interval.of(start, end);
            }
        }
        // infer offset from start if not specified by end
        return parseEndDateTime(start, ZoneOffset.UTC, endStr);
    }
590421
function parse_isodur(s) {
	var sec = 0, mt = 0, time = false;
	var m = s.match(/P([0-9\.]+Y)?([0-9\.]+M)?([0-9\.]+D)?T([0-9\.]+H)?([0-9\.]+M)?([0-9\.]+S)?/);
	if(!m) throw new Error("|" + s + "| is not an ISO8601 Duration");
	for(var i = 1; i != m.length; ++i) {
		if(!m[i]) continue;
		mt = 1;
		if(i > 3) time = true;
		switch(m[i].substr(m[i].length-1)) {
			case 'Y':
				throw new Error("Unsupported ISO Duration Field: " + m[i].substr(m[i].length-1));
			case 'D': mt *= 24;
				/* falls through */
			case 'H': mt *= 60;
				/* falls through */
			case 'M':
				if(!time) throw new Error("Unsupported ISO Duration Field: M");
				else mt *= 60;
				/* falls through */
			case 'S': break;
		}
		sec += mt * parseInt(m[i], 10);
	}
	return sec;
}
287860
def _iso8601_to_localized_time(date_string):
    
    parsed_date = datetime.strptime(date_string, '%Y-%m-%dT%H:%M:%S.%fZ')
    localized_time = pytz.utc.localize(parsed_date)
    return localized_time
876274
def _parse_record(data, duration_format='seconds'):
    

    def _map_duration(s):
        if s == '':
            return None
        elif duration_format.lower() == 'seconds':
            return int(s)
        else:
            t = time.strptime(s, duration_format)
            return 3600 * t.tm_hour + 60 * t.tm_min + t.tm_sec

    def _map_position(data):
        antenna = Position()

        if 'antenna_id' in data and data['antenna_id']:
            antenna.antenna = data['antenna_id']

        if 'place_id' in data:
            raise NameError("Use field name 'antenna_id' in input files. "
                            "'place_id' is deprecated.")

        if 'latitude' in data and 'longitude' in data:
            latitude = data['latitude']
            longitude = data['longitude']
            # latitude and longitude should not be empty strings.
            if latitude and longitude:
                antenna.location = float(latitude), float(longitude)

        return antenna

    return Record(interaction=data['interaction'] if data['interaction'] else None,
                  direction=data['direction'],
                  correspondent_id=data['correspondent_id'],
                  datetime=_tryto(
                      lambda x: datetime.strptime(x, "%Y-%m-%d %H:%M:%S"),
                      data['datetime']),
                  call_duration=_tryto(_map_duration, data['call_duration']),
                  position=_tryto(_map_position, data))
234370
def from_iso_datetime(datetimestring, use_dateutil=True):
    
    if not _iso8601_datetime_re.match(datetimestring):
        raise ValueError('Not a valid ISO8601-formatted datetime string')
    # Use dateutil's parser if possible
    if dateutil_available and use_dateutil:
        return parser.isoparse(datetimestring)
    else:
        # Strip off timezone info.
        return datetime.datetime.strptime(datetimestring[:19], '%Y-%m-%dT%H:%M:%S')
1147791
def get_duration(timestr1, timestr2, units='s'):
    
    valid_units = ['s', 'min', 'h']
    assert units in valid_units,\
      "Units must be one of {!s}".format(valid_units)

    duration = (
        gt.timestr_to_seconds(timestr2) - gt.timestr_to_seconds(timestr1)
    )

    if units == 's':
        return duration
    elif units == 'min':
        return duration/60
    else:
        return duration/3600
995704
def _parse_interval(value):
    
    try:
        return sorted(aniso8601.parse_interval(value))
    except ValueError:
        try:
            return aniso8601.parse_datetime(value), None
        except ValueError:
            return aniso8601.parse_date(value), None
558933
def fmt_duration(duration):
    
    try:
        return fmt.human_duration(float(duration), 0, 2, True)
    except (ValueError, TypeError):
        return "N/A".rjust(len(fmt.human_duration(0, 0, 2, True)))
1081209
def convert_duration(duration):
    '''
    
    '''

    # durations must be specified in days, weeks or hours

    if duration.endswith('h'):
        hours = int(duration.split('h'))

    elif duration.endswith('d'):
        days = duration.split('d')
        hours = int(days[0]) * 24

    elif duration.endswith('w'):
        weeks = duration.split('w')
        hours = int(weeks[0]) * 24 * 7

    duration_string = str(hours)+'h0m0s'
    return duration_string
148711
def timedelta_to_duration(dt):
    
    days, secs = dt.days, dt.seconds
    res = 'P'
    if days // 7:
        res += str(days // 7) + 'W'
        days %= 7
    if days:
        res += str(days) + 'D'
    if secs:
        res += 'T'
        if secs // 3600:
            res += str(secs // 3600) + 'H'
            secs %= 3600
        if secs // 60:
            res += str(secs // 60) + 'M'
            secs %= 60
        if secs:
            res += str(secs) + 'S'
    return res
904569
def compile_timedelta(rule):
    
    if isinstance(rule.value, datetime.timedelta):
        return rule
    try:
        # Try numeric type
        return TimedeltaRule(datetime.timedelta(seconds = int(rule.value)))
    except:
        pass
    # Try RFC3339 timestamp string
    res = DURATION_RE.match(str(rule.value))
    if res is not None:
        days, hours, minutes, seconds = (int(n or 0) for n in res.group('days','hrs','mins','secs'))
        return TimedeltaRule(datetime.timedelta(days = days, hours = hours, minutes = minutes, seconds = seconds))
    raise ValueError("Wrong timedelta format '{}'".format(rule.value))