For the sake of interest I want to convert video durations from YouTubes ISO 8601
to seconds. To future proof my solution, I picked a really long video to test it a
Extending on 9000's answer, apparently Youtube's format is using weeks, but not months which means total seconds can be easily computed.
Not using named groups here because I initially needed this to work with PySpark.
from operator import mul
from itertools import accumulate
import re
from typing import Pattern, List
SECONDS_PER_SECOND: int = 1
SECONDS_PER_MINUTE: int = 60
MINUTES_PER_HOUR: int = 60
HOURS_PER_DAY: int = 24
DAYS_PER_WEEK: int = 7
WEEKS_PER_YEAR: int = 52
ISO8601_PATTERN: Pattern = re.compile(
r"P(?:(\d+)Y)?(?:(\d+)W)?(?:(\d+)D)?"
r"T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?"
)
def extract_total_seconds_from_ISO8601(iso8601_duration: str) -> int:
"""Compute duration in seconds from a Youtube ISO8601 duration format. """
MULTIPLIERS: List[int] = (
SECONDS_PER_SECOND, SECONDS_PER_MINUTE, MINUTES_PER_HOUR,
HOURS_PER_DAY, DAYS_PER_WEEK, WEEKS_PER_YEAR
)
groups: List[int] = [int(g) if g is not None else 0 for g in
ISO8601_PATTERN.match(iso8601_duration).groups()]
return sum(g * multiplier for g, multiplier in
zip(reversed(groups), accumulate(MULTIPLIERS, mul)))