Module datetimecalc.timedelta

utilities for working with timedeltas

Functions

def duration_to_string(td: datetime.timedelta, localize: bool = True) ‑> str
Expand source code
def duration_to_string(td: timedelta, localize: bool = True) -> str:
    """
    return the given timedelta in a verbose, human-readable string format
    """

    # working my way down this list:
    # https://en.wikipedia.org/wiki/List_of_languages_by_number_of_native_speakers
    handlers: Dict[str, DurationFormatter] = {
        "zh": duration_to_string_zh,  # Chinese (zh) - 1.3 billion speakers
        "es": duration_to_string_es,  # Spanish (es) - 442 million speakers
        "en": duration_to_string_en,  # English (en) - 372 million speakers
        "hi": duration_to_string_hi,  # Hindi (hi) - 341 million speakers
        "pt": duration_to_string_pt,  # Portuguese (pt) - 234 million speakers
        "bn": duration_to_string_bn,  # Bengali (bn) - 228 million speakers
        "ru": duration_to_string_ru,  # Russian (ru) - 153 million speakers
        "ja": duration_to_string_ja,  # Japanese (ja) - 128 million speakers
        "vi": duration_to_string_vi,  # Vietnamese (vi) - 85 million speakers
        "tr": duration_to_string_tr,  # Turkish (tr) - 84 million speakers
        "mr": duration_to_string_mr,  # Marathi (mr) - 83 million speakers
    }
    handler = handlers.get(locale_dict().get("lang_code", "en") if localize else "en")
    if handler is None:
        raise RuntimeError("encountered an issue with the locale")
    return handler(td)

return the given timedelta in a verbose, human-readable string format

def duration_to_string_bn(td: datetime.timedelta) ‑> str
Expand source code
def duration_to_string_bn(td: timedelta) -> str:
    """
    Convert a timedelta to a string representation in Bengali.

    Args:
        td: The timedelta object to convert

    Returns:
        A string containing the representation in Bengali

    Example:
        >>> from datetime import timedelta
        >>> td = timedelta(days=2, hours=3)
        >>> duration_to_string_bn(td)
        '2 দিন, 3 ঘণ্টা'
    """
    return _format_standard(TDC(td), LABELS_BN)

Convert a timedelta to a string representation in Bengali.

Args

td
The timedelta object to convert

Returns

A string containing the representation in Bengali

Example

>>> from datetime import timedelta
>>> td = timedelta(days=2, hours=3)
>>> duration_to_string_bn(td)
'2 দিন, 3 ঘণ্টা'
def duration_to_string_en(td: datetime.timedelta) ‑> str
Expand source code
def duration_to_string_en(td: timedelta) -> str:
    """
    Convert a timedelta to an English string representation.

    Args:
        td: The timedelta object to convert

    Returns:
        A string containing the English representation

    Example:
        >>> from datetime import timedelta
        >>> td = timedelta(days=2, hours=3)
        >>> duration_to_string_en(td)
        '2 days, 3 hours'
    """
    return _format_standard(TDC(td), LABELS_EN)

Convert a timedelta to an English string representation.

Args

td
The timedelta object to convert

Returns

A string containing the English representation

Example

>>> from datetime import timedelta
>>> td = timedelta(days=2, hours=3)
>>> duration_to_string_en(td)
'2 days, 3 hours'
def duration_to_string_es(td: datetime.timedelta) ‑> str
Expand source code
def duration_to_string_es(td: timedelta) -> str:
    """
    Convert a timedelta object to a string in Spanish.

    Args:
        td: The timedelta object to convert

    Returns:
        A string with the representation in Spanish

    Example:
        >>> from datetime import timedelta
        >>> td = timedelta(days=2, hours=3)
        >>> duration_to_string_es(td)
        '2 días, 3 horas'
    """
    return _format_standard(TDC(td), LABELS_ES)

Convert a timedelta object to a string in Spanish.

Args

td
The timedelta object to convert

Returns

A string with the representation in Spanish

Example

>>> from datetime import timedelta
>>> td = timedelta(days=2, hours=3)
>>> duration_to_string_es(td)
'2 días, 3 horas'
def duration_to_string_hi(td: datetime.timedelta) ‑> str
Expand source code
def duration_to_string_hi(td: timedelta) -> str:
    """
    Convert a timedelta to a string representation in Hindi.

    Args:
        td: The timedelta object to convert

    Returns:
        A string containing the representation in Hindi

    Example:
        >>> from datetime import timedelta
        >>> td = timedelta(days=2, hours=3)
        >>> duration_to_string_hi(td)
        '2 दिन, 3 घंटे'
    """
    return _format_standard(TDC(td), LABELS_HI)

Convert a timedelta to a string representation in Hindi.

Args

td
The timedelta object to convert

Returns

A string containing the representation in Hindi

Example

>>> from datetime import timedelta
>>> td = timedelta(days=2, hours=3)
>>> duration_to_string_hi(td)
'2 दिन, 3 घंटे'
def duration_to_string_ja(td: datetime.timedelta) ‑> str
Expand source code
def duration_to_string_ja(td: timedelta) -> str:
    """Convert a timedelta object to a string in Japanese.

    Args:
        td: The timedelta object to convert

    Returns:
        A string containing the representation in Japanese

    Example:
        >>> from datetime import timedelta
        >>> td = timedelta(days=2, hours=3)
        >>> duration_to_string_ja(td)
        '2日、3時間'
    """
    return _format_no_space(TDC(td), LABELS_JA, "、")

Convert a timedelta object to a string in Japanese.

Args

td
The timedelta object to convert

Returns

A string containing the representation in Japanese

Example

>>> from datetime import timedelta
>>> td = timedelta(days=2, hours=3)
>>> duration_to_string_ja(td)
'2日、3時間'
def duration_to_string_mr(td: datetime.timedelta) ‑> str
Expand source code
def duration_to_string_mr(td: timedelta) -> str:
    """
    Convert a timedelta object to a string in Marathi.

    Args:
        td: The timedelta object to convert

    Returns:
        A string containing the representation in Marathi

    Example:
        >>> from datetime import timedelta
        >>> td = timedelta(days=2, hours=3)
        >>> duration_to_string_mr(td)
        '2 दिवस, 3 तास'
    """
    return _format_with_space(TDC(td), LABELS_MR)

Convert a timedelta object to a string in Marathi.

Args

td
The timedelta object to convert

Returns

A string containing the representation in Marathi

Example

>>> from datetime import timedelta
>>> td = timedelta(days=2, hours=3)
>>> duration_to_string_mr(td)
'2 दिवस, 3 तास'
def duration_to_string_pt(td: datetime.timedelta) ‑> str
Expand source code
def duration_to_string_pt(td: timedelta) -> str:
    """
    Convert a timedelta object to a string in Portuguese.

    Args:
        td: The timedelta object to convert

    Returns:
        A string containing the representation in Portuguese

    Example:
        >>> from datetime import timedelta
        >>> td = timedelta(days=2, hours=3)
        >>> duration_to_string_pt(td)
        '2 dias, 3 horas'
    """
    return _format_standard(TDC(td), LABELS_PT)

Convert a timedelta object to a string in Portuguese.

Args

td
The timedelta object to convert

Returns

A string containing the representation in Portuguese

Example

>>> from datetime import timedelta
>>> td = timedelta(days=2, hours=3)
>>> duration_to_string_pt(td)
'2 dias, 3 horas'
def duration_to_string_ru(td: datetime.timedelta) ‑> str
Expand source code
def duration_to_string_ru(td: timedelta) -> str:
    """
    Convert a timedelta object to a string in Russian.

    Args:
        td: The timedelta object to convert

    Returns:
        A string containing the representation in Russian

    Example:
        >>> from datetime import timedelta
        >>> td = timedelta(days=2, hours=3)
        >>> duration_to_string_ru(td)
        '2 дня, 3 часа'
    """
    return _format_russian(TDC(td), LABELS_RU)

Convert a timedelta object to a string in Russian.

Args

td
The timedelta object to convert

Returns

A string containing the representation in Russian

Example

>>> from datetime import timedelta
>>> td = timedelta(days=2, hours=3)
>>> duration_to_string_ru(td)
'2 дня, 3 часа'
def duration_to_string_tr(td: datetime.timedelta) ‑> str
Expand source code
def duration_to_string_tr(td: timedelta) -> str:
    """
    Convert a timedelta object to a string in Turkish.

    Args:
        td: The timedelta object to convert

    Returns:
        A string containing the representation in Turkish

    Example:
        >>> from datetime import timedelta
        >>> td = timedelta(days=2, hours=3)
        >>> duration_to_string_tr(td)
        '2 gün, 3 saat'
    """
    return _format_standard(TDC(td), LABELS_TR)

Convert a timedelta object to a string in Turkish.

Args

td
The timedelta object to convert

Returns

A string containing the representation in Turkish

Example

>>> from datetime import timedelta
>>> td = timedelta(days=2, hours=3)
>>> duration_to_string_tr(td)
'2 gün, 3 saat'
def duration_to_string_vi(td: datetime.timedelta) ‑> str
Expand source code
def duration_to_string_vi(td: timedelta) -> str:
    """
    Convert a timedelta object to a string in Vietnamese.

    Args:
        td: The timedelta object to convert

    Returns:
       A string containing the representation in Vietnamese

    Example:
        >>> from datetime import timedelta
        >>> td = timedelta(days=2, hours=3)
        >>> duration_to_string_vi(td)
        '2 ngày, 3 giờ'
    """
    return _format_with_space(TDC(td), LABELS_VI)

Convert a timedelta object to a string in Vietnamese.

Args

td
The timedelta object to convert

Returns

A string containing the representation in Vietnamese

Example

>>> from datetime import timedelta
>>> td = timedelta(days=2, hours=3)
>>> duration_to_string_vi(td)
'2 ngày, 3 giờ'
def duration_to_string_zh(td: datetime.timedelta) ‑> str
Expand source code
def duration_to_string_zh(td: timedelta) -> str:
    """
    Convert a timedelta to a Chinese string representation.

    Args:
      td: The timedelta to convert

    Returns:
      A string containing the Chinese representation

    Example:
      >>> from datetime import timedelta
      >>> td = timedelta(days=2, hours=3)
      >>> duration_to_string_zh(td)
      '2天, 3小时'
    """
    # joining with full-width comma then space
    return _format_no_space(TDC(td), LABELS_ZH, "\uff0c ")

Convert a timedelta to a Chinese string representation.

Args

td
The timedelta to convert

Returns

A string containing the Chinese representation

Example

>>> from datetime import timedelta
>>> td = timedelta(days=2, hours=3)
>>> duration_to_string_zh(td)
'2天, 3小时'
def locale_dict() ‑> Dict[str, str]
Expand source code
def locale_dict() -> Dict[str, str]:
    """Return a dictionary with locale information.

    Returns:
        dict: Locale info with keys:
            - locale_name: Full locale name string
            - encoding: Locale encoding
            - lang_code: ISO 639 language code
            - territory_code: ISO 3166 territory code

    Example:
        >>> locale_dict()['lang_code']
        'en'
    """
    locale_name, encoding = locale.getlocale()

    if locale_name and "_" in locale_name:
        lang_code, territory_code = locale_name.split("_", 1)
    elif locale_name:
        lang_code = locale_name
        territory_code = ""
    else:
        lang_code = ""
        territory_code = ""

    return {
        "locale_name": locale_name if locale_name else "",
        "encoding": encoding if encoding else "",
        "lang_code": lang_code,
        "territory_code": territory_code,
    }

Return a dictionary with locale information.

Returns

dict
Locale info with keys: - locale_name: Full locale name string - encoding: Locale encoding - lang_code: ISO 639 language code - territory_code: ISO 3166 territory code

Example

>>> locale_dict()['lang_code']
'en'

Classes

class TDC (td: datetime.timedelta)
Expand source code
class TDC:
    """TDC: timedelta components"""

    year: int
    month: int
    week: int
    day: int
    hour: int
    minute: int
    second: int
    microsecond: int
    millisecond: int

    keys: Sequence[TDCKey] = (
        "year",
        "month",
        "week",
        "day",
        "hour",
        "minute",
        "second",
        "microsecond",
        "millisecond",
    )

    def __init__(self, td: timedelta):
        for k, v in self.extract_components(td).items():
            setattr(self, k, v)

    def __getitem__(self, key: str) -> int:
        """
        Allow index access to the namedtuple

        Usage:
        >>> t = TDC(timedelta(days=365))
        >>> t['year']
        1
        >>> t['z']
        Traceback (most recent call last):
        ...
        KeyError: 'z'
        """

        try:
            return getattr(self, key)
        except AttributeError:
            raise KeyError(key) from None

    @staticmethod
    def extract_components(td: Union[timedelta, int, float]) -> Dict[str, int]:
        """
        Extracts time components from a timedelta, int, or float.

        Args:
            td: A timedelta object, or an int/float number of seconds.

        Returns:
            A dictionary with keys for years, months, weeks, days, hours,
            minutes, seconds, milliseconds, and microseconds, and values
            representing the number of each in the input timedelta.


        Examples:
            >>> extract_components = TDC.extract_components
            >>> extract_components(timedelta(days=2, seconds=3723))
            {'year': 0, 'month': 0, 'week': 0, 'day': 2, 'hour': 1,
            'minute': 2, 'second': 3, 'millisecond': 0, 'microsecond': 0}
            >>> extract_components(7200)
            {'year': 0, 'month': 0, 'week': 0, 'day': 0, 'hour': 2,
            'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
            >>> extract_components(timedelta(days=365))
            {'year': 1, 'month': 0, 'week': 0, 'day': 0, 'hour': 0,
            'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
            >>> extract_components(timedelta(days=30))
            {'year': 0, 'month': 1, 'week': 0, 'day': 0, 'hour': 0,
            'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
            >>> extract_components(timedelta(hours=48))
            {'year': 0, 'month': 0, 'week': 0, 'day': 2, 'hour': 0,
            'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
            >>> extract_components(3600000)
            {'year': 0, 'month': 1, 'week': 1, 'day': 4, 'hour': 16,
            'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
            >>> extract_components(timedelta(days=403, seconds=3661, \
            microseconds=1001))
            {'year': 1, 'month': 1, 'week': 1, 'day': 1, 'hour': 1,
            'minute': 1, 'second': 1, 'millisecond': 1, 'microsecond': 1}
        """

        if isinstance(td, (int, float)):
            td = timedelta(seconds=td)

        total_seconds = td.total_seconds()
        sign = -1 if total_seconds < 0 else 1
        total_seconds = abs(total_seconds)

        # define the units and their respective lengths in seconds
        units = (
            ("year", 31_536_000),  # 60 * 60 * 24 * 365
            ("month", 2_592_000),  # 60 * 60 * 24 * 30
            ("week", 604_800),  # 60 * 60 * 24 * 7
            ("day", 86_400),  # 60 * 60 * 24
            ("hour", 3_600),  # 60 * 60
            ("minute", 60),
            ("second", 1),
            ("millisecond", 1e-3),
            ("microsecond", 1e-6),
        )

        components = {}

        for unit, length_in_seconds in units:
            # calculate the number of whole units
            units_total = total_seconds // length_in_seconds

            # add the number of units to the components dict
            components[unit] = sign * int(units_total)

            # subtract the units from the total seconds
            total_seconds -= units_total * length_in_seconds

        return components

    def labeled_values(self, labels: Dict[TDCKey, Tuple[str, str]]) -> Sequence[str]:
        """helper function for languages with a 2-element singular/plural tuple"""
        return [
            f"{self[key]} {labels[key][0] if abs(self[key]) == 1 else labels[key][1]}"
            for key in self.keys
            if self[key]
        ]

TDC: timedelta components

Class variables

var day : int

The type of the None singleton.

var hour : int

The type of the None singleton.

var keys : Sequence[Literal['year'] | Literal['month'] | Literal['week'] | Literal['day'] | Literal['hour'] | Literal['minute'] | Literal['second'] | Literal['microsecond'] | Literal['millisecond']]

The type of the None singleton.

var microsecond : int

The type of the None singleton.

var millisecond : int

The type of the None singleton.

var minute : int

The type of the None singleton.

var month : int

The type of the None singleton.

var second : int

The type of the None singleton.

var week : int

The type of the None singleton.

var year : int

The type of the None singleton.

Static methods

def extract_components(td: datetime.timedelta | int | float) ‑> Dict[str, int]
Expand source code
@staticmethod
def extract_components(td: Union[timedelta, int, float]) -> Dict[str, int]:
    """
    Extracts time components from a timedelta, int, or float.

    Args:
        td: A timedelta object, or an int/float number of seconds.

    Returns:
        A dictionary with keys for years, months, weeks, days, hours,
        minutes, seconds, milliseconds, and microseconds, and values
        representing the number of each in the input timedelta.


    Examples:
        >>> extract_components = TDC.extract_components
        >>> extract_components(timedelta(days=2, seconds=3723))
        {'year': 0, 'month': 0, 'week': 0, 'day': 2, 'hour': 1,
        'minute': 2, 'second': 3, 'millisecond': 0, 'microsecond': 0}
        >>> extract_components(7200)
        {'year': 0, 'month': 0, 'week': 0, 'day': 0, 'hour': 2,
        'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
        >>> extract_components(timedelta(days=365))
        {'year': 1, 'month': 0, 'week': 0, 'day': 0, 'hour': 0,
        'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
        >>> extract_components(timedelta(days=30))
        {'year': 0, 'month': 1, 'week': 0, 'day': 0, 'hour': 0,
        'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
        >>> extract_components(timedelta(hours=48))
        {'year': 0, 'month': 0, 'week': 0, 'day': 2, 'hour': 0,
        'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
        >>> extract_components(3600000)
        {'year': 0, 'month': 1, 'week': 1, 'day': 4, 'hour': 16,
        'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
        >>> extract_components(timedelta(days=403, seconds=3661, \
        microseconds=1001))
        {'year': 1, 'month': 1, 'week': 1, 'day': 1, 'hour': 1,
        'minute': 1, 'second': 1, 'millisecond': 1, 'microsecond': 1}
    """

    if isinstance(td, (int, float)):
        td = timedelta(seconds=td)

    total_seconds = td.total_seconds()
    sign = -1 if total_seconds < 0 else 1
    total_seconds = abs(total_seconds)

    # define the units and their respective lengths in seconds
    units = (
        ("year", 31_536_000),  # 60 * 60 * 24 * 365
        ("month", 2_592_000),  # 60 * 60 * 24 * 30
        ("week", 604_800),  # 60 * 60 * 24 * 7
        ("day", 86_400),  # 60 * 60 * 24
        ("hour", 3_600),  # 60 * 60
        ("minute", 60),
        ("second", 1),
        ("millisecond", 1e-3),
        ("microsecond", 1e-6),
    )

    components = {}

    for unit, length_in_seconds in units:
        # calculate the number of whole units
        units_total = total_seconds // length_in_seconds

        # add the number of units to the components dict
        components[unit] = sign * int(units_total)

        # subtract the units from the total seconds
        total_seconds -= units_total * length_in_seconds

    return components

Extracts time components from a timedelta, int, or float.

Args

td
A timedelta object, or an int/float number of seconds.

Returns

A dictionary with keys for years, months, weeks, days, hours, minutes, seconds, milliseconds, and microseconds, and values representing the number of each in the input timedelta.

Examples

>>> extract_components = TDC.extract_components
>>> extract_components(timedelta(days=2, seconds=3723))
{'year': 0, 'month': 0, 'week': 0, 'day': 2, 'hour': 1,
'minute': 2, 'second': 3, 'millisecond': 0, 'microsecond': 0}
>>> extract_components(7200)
{'year': 0, 'month': 0, 'week': 0, 'day': 0, 'hour': 2,
'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
>>> extract_components(timedelta(days=365))
{'year': 1, 'month': 0, 'week': 0, 'day': 0, 'hour': 0,
'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
>>> extract_components(timedelta(days=30))
{'year': 0, 'month': 1, 'week': 0, 'day': 0, 'hour': 0,
'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
>>> extract_components(timedelta(hours=48))
{'year': 0, 'month': 0, 'week': 0, 'day': 2, 'hour': 0,
'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
>>> extract_components(3600000)
{'year': 0, 'month': 1, 'week': 1, 'day': 4, 'hour': 16,
'minute': 0, 'second': 0, 'millisecond': 0, 'microsecond': 0}
>>> extract_components(timedelta(days=403, seconds=3661,             microseconds=1001))
{'year': 1, 'month': 1, 'week': 1, 'day': 1, 'hour': 1,
'minute': 1, 'second': 1, 'millisecond': 1, 'microsecond': 1}

Methods

def labeled_values(self,
labels: Dict[Literal['year'] | Literal['month'] | Literal['week'] | Literal['day'] | Literal['hour'] | Literal['minute'] | Literal['second'] | Literal['microsecond'] | Literal['millisecond'], Tuple[str, str]]) ‑> Sequence[str]
Expand source code
def labeled_values(self, labels: Dict[TDCKey, Tuple[str, str]]) -> Sequence[str]:
    """helper function for languages with a 2-element singular/plural tuple"""
    return [
        f"{self[key]} {labels[key][0] if abs(self[key]) == 1 else labels[key][1]}"
        for key in self.keys
        if self[key]
    ]

helper function for languages with a 2-element singular/plural tuple