ItemizedDelta¶
- class whenever.ItemizedDelta(
- *,
- years: int = ...,
- months: int = ...,
- weeks: int = ...,
- days: int = ...,
- hours: int = ...,
- minutes: int = ...,
- seconds: int = ...,
- nanoseconds: int = ...,
A delta that preserves the components it was given. It closely models the ISO 8601 duration format.
>>> d = ItemizedDelta(weeks=2, days=3, hours=14) ItemizedDelta("P2w3dT14h") >>> d = ItemizedDelta("P2w3dT14h") >>> str(d) 'P2W3DT14H'
It behaves like a mapping where the keys are the unit names and the values are the amounts. Items are ordered from largest to smallest unit.
>>> d['weeks'] 2 >>> print(d.get('minutes')) None >>> dict(d) {"weeks": 2, "days": 3, "hours": 14} >>> list(d.keys()) ["weeks", "days", "hours"] >>> weeks, days, hours = d.values() (2, 3, 14)
ItemizedDeltaalso supports other dictionary-like operations:>>> "months" in d # check for presence of a component False >>> len(d) # number of components present 3
An explicit zero is a present component, distinct from an absent one:
>>> d2 = ItemizedDelta(years=2, weeks=3, hours=0) >>> dict(d2) {"years": 2, "weeks": 3, "hours": 0}
Additionally, no normalization is performed. Months are not rolled into years, minutes into hours, etc.
>>> d3 = ItemizedDelta(months=24, minutes=90) ItemizedDelta("P24mT90m")
Seconds and nanoseconds are one quantity in two components:
nanosecondsis bounded to 999,999,999, and setting it also setsseconds. There are no millisecond or microsecond components; usetotal()for those units. See the subsecond rules.An empty delta is not allowed: at least one component must be present, but it may be zero:
>>> ItemizedDelta() ValueError: at least one component must be present >>> ItemizedDelta(seconds=0) ItemizedDelta("PT0s")
Negative deltas are supported, but all components must have the same sign:
>>> d4 = ItemizedDelta(years=-1, weeks=-2, days=0) ItemizedDelta("-P1y2w0d") >>> ItemizedDelta(years=1, days=-3) ValueError: mixed sign in delta
Note
Unlike
TimeDelta,ItemizedDeltadoes not normalize its components. This means thatItemizedDelta(hours=90)andItemizedDelta(days=3, hours=18)are considered different values. To convert to a normalized form, usein_units(). See also the delta documentation.- classmethod parse_iso(s: str, /) ItemizedDelta[source]¶
Parse the popular interpretation of the ISO 8601 duration format. Does not parse all possible ISO 8601 durations. See here for more information.
P4D # 4 days PT4H # 4 hours PT0M # 0 minutes PT3M40.5S # 3 minutes and 40.5 seconds P1W11DT90M # 1 week, 11 days, and 90 minutes -PT7H400M # -7 hours and -400 minutes +PT7H4M # 7 hours and 4 minutes (7:04:00)
Inverse of
format_iso()>>> ItemizedDelta.parse_iso("-P1W11DT4H") ItemizedDelta("-P1w11dT4h")
- __abs__() ItemizedDelta[source]¶
If the components are negative, return the positive version
>>> d = ItemizedDelta(weeks=-2, days=-3) >>> abs(d) ItemizedDelta("P2w3d")
- __add__(
- other: ItemizedDelta | ItemizedDateDelta | ZonedDateTime | PlainDateTime | OffsetDateTime,
- /,
Compose component-wise with another itemized delta, or shift a datetime by this delta.
>>> ItemizedDelta(hours=1) + ItemizedDelta(minutes=30) ItemizedDelta("PT1h30m") >>> ItemizedDelta(hours=1) + ZonedDateTime(2023, 1, 1, tz="UTC") ZonedDateTime("2023-01-01 01:00:00+00:00[UTC]")
Nonzero
yearsormonthsin either operand emitMonthCompositionWarning, whichadd()accepts withmonth_composition_ok=True.
- __bool__() bool[source]¶
An ItemizedDelta is considered False if its sign is 0.
>>> bool(ItemizedDelta(weeks=0)) False >>> bool(ItemizedDelta(weeks=1)) True
- __contains__(key: object, /) bool[source]¶
Whether a specific component is present.
>>> d = ItemizedDelta(weeks=1, days=3) >>> "weeks" in d True >>> "hours" in d False
- __eq__(other: object, /) bool[source]¶
Compare for equality. Each component is individually compared. No normalization is performed. An explicit zero is equivalent to an absent component.
Thus,
ItemizedDelta(weeks=1, seconds=0) == ItemizedDelta(weeks=1)>>> d = ItemizedDelta(weeks=2, minutes=90) >>> d == ItemizedDelta(weeks=2, minutes=90) True >>> d == ItemizedDelta(weeks=2, minutes=91) False
An
ItemizedDateDeltawith the same components is equal:>>> ItemizedDelta(weeks=2, hours=0) == ItemizedDateDelta(weeks=2) True
If you want strict equality (including presence of components and the type), use
strict_eq().
- __getitem__(key: str, /) int[source]¶
Get the value of a specific component by name.
>>> d = ItemizedDelta(weeks=1, days=3) >>> d["weeks"] 1 >>> d["days"] 3 >>> d["hours"] KeyError: 'hours'
- __iter__() Iterator[DeltaUnitStr][source]¶
Iterate over the present components, ordered from largest to smallest unit.
- __len__() int[source]¶
The number of present components.
>>> d = ItemizedDelta(weeks=1, days=3) >>> len(d) 2
- __neg__() ItemizedDelta[source]¶
Invert the sign of the components
>>> d = ItemizedDelta(weeks=2, days=3) >>> -d ItemizedDelta("-P2w3d") >>> --d ItemizedDelta("P2w3d")
- __sub__(other: ItemizedDelta | ItemizedDateDelta, /) ItemizedDelta[source]¶
Compose component-wise by subtracting another itemized delta.
>>> ItemizedDelta(hours=2, minutes=30) - ItemizedDelta(minutes=30) ItemizedDelta("PT2h0m")
The same rules apply as for
__add__().
- add(
- delta: ItemizedDelta | ItemizedDateDelta = ...,
- /,
- *,
- years: int = ...,
- months: int = ...,
- weeks: int = ...,
- days: int = ...,
- hours: int = ...,
- minutes: int = ...,
- seconds: int = ...,
- nanoseconds: int = ...,
- month_composition_ok: bool = ...,
- **kwargs: Any,
Add a delta to this one component-wise, returning a new delta.
Pass either a delta or its components as keywords, not both.
The result isn’t balanced:
1 hourplus90 minutesis1 hour 90 minutes, and1 monthplus30 daysis1 month 30 days. To balance it, callin_units()on the result.Deprecated since version 0.11:
relative_to=, within_units=,round_mode=,round_increment=,naive_arithmetic_ok=, andstale_offset_ok=. Callin_units()on the result instead.cal_unit_composition_ok=is nowmonth_composition_ok=.>>> ItemizedDelta(hours=1).add(minutes=30) ItemizedDelta("PT1h30m") >>> ItemizedDelta(months=1, hours=5).add(hours=3, month_composition_ok=True) ItemizedDelta("P1mT8h")
- Parameters:
delta – The delta to add, or else its components as keywords, named as in the constructor.
month_composition_ok – Accepts the
MonthCompositionWarningthat nonzeroyearsormonthsin either operand emits.
- date_and_time_parts() tuple[ItemizedDateDelta | None, TimeDelta | None][source]¶
Split into the date part and the time part.
The date part is an
ItemizedDateDelta; the time part is a normalizedTimeDelta, since no itemized time-only type exists. A half with no component present isNone, while a half given only as zero is a present zero. At least one half is present, since at least one component is.>>> d = ItemizedDelta( ... years=1, ... months=2, ... weeks=3, ... days=4, ... hours=5, ... minutes=6, ... seconds=7, ... nanoseconds=8, ... ) >>> date_part, time_part = d.date_and_time_parts() >>> date_part ItemizedDateDelta("P1y2m3w4d") >>> time_part TimeDelta("PT5h6m7.000000008s") >>> ItemizedDelta(weeks=2).date_and_time_parts() (ItemizedDateDelta("P2w"), None)
- exact_eq(other: ItemizedDelta, /) bool[source]¶
Deprecated alias for
strict_eq().Deprecated since version 0.11: Use
strict_eq()instead.
- format_iso(*, lowercase_units: bool = False) str[source]¶
Format as the popular interpretation of the ISO 8601 duration format. May not strictly adhere to (all versions of) the standard. See here for more information.
Inverse of
parse_iso().The format is:
P(nY)(nM)(nW)(nD)T(nH)(nM)(nS)
>>> d = ItemizedDelta( ... weeks=1, ... days=11, ... hours=4, ... seconds=1, ... nanoseconds=12_000, ... ) >>> d.format_iso() 'P1W11DT4H1.000012S'
- Parameters:
lowercase_units – Write the unit designators in lowercase, as
repr()does;parse_iso()reads both cases.
- get(key: DeltaUnitStr, /) int | None[source]¶
- get(key: DeltaUnitStr, default: int, /) int
Get the value of a specific component by name, or return default if absent.
Part of the mapping protocol
- in_units(
- units: Sequence[DeltaUnitStr],
- /,
- *,
- relative_to: ZonedDateTime | PlainDateTime | OffsetDateTime,
- round_mode: RoundModeStr = 'trunc',
- round_increment: int = 1,
- naive_arithmetic_ok: bool = ...,
- stale_offset_ok: bool = ...,
Convert this delta into the given units.
>>> d = ItemizedDelta(years=1, months=8, minutes=1000) >>> d.in_units(["weeks", "hours"], relative_to=ZonedDateTime(2020, 6, 30, 12, tz="Asia/Tokyo")) ItemizedDelta("P86wT160h")
- Parameters:
units – The units of the result, largest first.
relative_to – The reference the calendar units are resolved against. A
ZonedDateTimeemits no warning. APlainDateTimeignores time zone transitions, and emitsNaiveArithmeticWarningwhen the computation crosses the calendar/exact boundary. AnOffsetDateTimeholds its offset fixed for the whole calculation, and emitsStaleOffsetWarningwhen calendar units are involved.round_mode – The rounding mode for the smallest unit in
units, as onsince().round_increment – The rounding increment for that unit.
naive_arithmetic_ok – Accepts the
NaiveArithmeticWarningof aPlainDateTimereference.stale_offset_ok – Accepts the
StaleOffsetWarningof anOffsetDateTimereference.
- items() ItemsView[DeltaUnitStr, int][source]¶
The present components as (unit, value) pairs, ordered from largest to smallest unit.
>>> d = ItemizedDelta(years=3, hours=12, days=0) >>> list(d.items()) [('years', 3), ('days', 0), ('hours', 12)]
Part of the mapping protocol
- keys() KeysView[DeltaUnitStr][source]¶
The names of the present components, in order of largest to smallest unit.
Part of the mapping protocol
- replace(
- *,
- years: int | None = ...,
- months: int | None = ...,
- weeks: int | None = ...,
- days: int | None = ...,
- hours: int | None = ...,
- minutes: int | None = ...,
- seconds: int | None = ...,
- nanoseconds: int | None = ...,
Create a new delta with the given components replaced
A component given as
Noneis removed. Removing the last one raisesValueError, as does a mixed sign.>>> d = ItemizedDelta(years=1, months=2, hours=3) >>> d.replace(months=None, hours=2) ItemizedDelta("P1yT2h")
- sign() Literal[1, 0, -1][source]¶
The sign of the delta, whether it’s positive, negative, or zero.
>>> ItemizedDelta(weeks=2).sign() 1 >>> ItemizedDelta(hours=-3).sign() -1 >>> ItemizedDelta(weeks=0).sign() 0
- strict_eq(other: ItemizedDelta, /) bool[source]¶
Compare two deltas, including what
==ignores.==equates anItemizedDeltawith anItemizedDateDeltaof the same components, and ignores whether a component was given explicitly as zero.strict_eq()takes only anItemizedDelta: another type raisesTypeError.>>> d = ItemizedDelta(weeks=2, hours=3) >>> d == ItemizedDelta(weeks=2, hours=3, months=0) True >>> d.strict_eq(ItemizedDelta(weeks=2, hours=3, months=0)) False
See Strict equality for the rules on every type.
- subtract(
- delta: ItemizedDelta | ItemizedDateDelta = ...,
- /,
- *,
- years: int = ...,
- months: int = ...,
- weeks: int = ...,
- days: int = ...,
- hours: int = ...,
- minutes: int = ...,
- seconds: int = ...,
- nanoseconds: int = ...,
- month_composition_ok: bool = ...,
- **kwargs: Any,
Subtract a delta from this one component-wise, returning a new delta.
The inverse of
add(), with the same parameters and rules.>>> ItemizedDelta(months=1, hours=5).subtract(hours=3, month_composition_ok=True) ItemizedDelta("P1mT2h")
- total(
- unit: DeltaTotalUnitStr,
- /,
- *,
- relative_to: ZonedDateTime | PlainDateTime | OffsetDateTime,
- naive_arithmetic_ok: bool = ...,
- stale_offset_ok: bool = ...,
The total duration in the given unit.
>>> d = ItemizedDelta(months=1, hours=6) >>> d.total("days", relative_to=ZonedDateTime(2023, 1, 1, tz="UTC")) 31.25 >>> d.total("nanoseconds", relative_to=ZonedDateTime(2023, 1, 1, tz="UTC")) 2700000000000000
- Parameters:
unit – The unit to sum into.
"nanoseconds"gives anint, any other unit afloat.relative_to – The reference the calendar units are resolved against. A
ZonedDateTimeemits no warning. APlainDateTimeignores time zone transitions, and emitsNaiveArithmeticWarningwhen the computation crosses the calendar/exact boundary. AnOffsetDateTimeholds its offset fixed for the whole calculation, and emitsStaleOffsetWarningwhen calendar units are involved.naive_arithmetic_ok – Accepts the
NaiveArithmeticWarningof aPlainDateTimereference.stale_offset_ok – Accepts the
StaleOffsetWarningof anOffsetDateTimereference.
- values() ValuesView[int][source]¶
The values of the present components, in order of largest to smallest unit.
>>> d = ItemizedDelta(years=3, hours=12, days=0) >>> years, days, hours = d.values() (3, 0, 12) >>> list(d.values()) [3, 0, 12]
Part of the mapping protocol