Period#

class isoperiod.Period[source]#

A repeating period of time, which splits the Gregorian timeline into consecutive, numbered intervals.

A Period divides all of time into intervals of one fixed size - every hour, every 15 minutes, every month - and numbers each interval with an integer “ordinal”. Two methods map between the two views:

ordinal(datetime) -> int

The ordinal of the interval containing that datetime.

datetime(ordinal) -> datetime

The first instant of that interval.

They are inverses, in the sense that period.ordinal(d) == n for every datetime where period.datetime(n) <= d < period.datetime(n + 1).

An offset shifts every one of those boundaries by a fixed amount, so intervals keep their size but start somewhere else - e.g. a hydrological day running 09:00 to 09:00, or a year starting in October. In string form it is written <duration>+<offset> ("P1D+T9H"), this package’s own extension of the ISO 8601 duration format. See Offsets and origins.

Period is abstract: build one with an of_* factory, then refine it with the with_* methods, each of which returns a new Period rather than mutating the original.

Instances are immutable and hashable, so they work in sets and as dict keys. They sort shortest first, with a calendar month taken as its mean Gregorian length so that calendar and fixed-length periods order against one another; comparing two Periods that differ only in their tzinfo raises TypeError, just as comparing a naive datetime with an aware one does.

Examples

>>> from datetime import datetime, timedelta
>>> from isoperiod import Period

Which hour is 09:47 in, and when did that hour start and end?

>>> pt1h = Period.of_hours(1)
>>> d = datetime(2024, 3, 1, 9, 47)
>>> n = pt1h.ordinal(d)
>>> pt1h.datetime(n)
datetime.datetime(2024, 3, 1, 9, 0)
>>> pt1h.datetime(n + 1)
datetime.datetime(2024, 3, 1, 10, 0)

Ordinals are consecutive integers, so interval arithmetic is integer arithmetic.

>>> pt1h.ordinal(d + timedelta(days=1)) - pt1h.ordinal(d)
24

Months work the same way, despite their varying length.

>>> Period.of_months(1).floor(datetime(2024, 3, 15))
datetime.datetime(2024, 3, 1, 0, 0)

An offset moves every boundary: a day running 09:00 -> 09:00.

>>> water_day = Period.of_days(1).with_hour_offset(9)
>>> water_day.floor(datetime(2024, 3, 15, 7, 30))
datetime.datetime(2024, 3, 14, 9, 0)
classmethod __new__(*args, **kwargs)#

Constructors#

From a named unit

of_years

Return a Period of no_of_years calendar years, each starting on January 1st.

of_months

Return a Period of no_of_months calendar months, each starting on the 1st.

of_days

Return a Period of no_of_days days, each starting at midnight.

of_hours

Return a Period of no_of_hours hours, each starting on the hour.

of_minutes

Return a Period of no_of_minutes minutes, each starting on the minute.

of_seconds

Return a Period of no_of_seconds whole seconds.

of_microseconds

Return a Period of no_of_microseconds microseconds, the finest resolution a Period can have.

From a string or timedelta

of

Return a Period from the supplied string.

of_iso_duration

Return a Period from a strict ISO 8601 duration string

of_duration

Return a Period from an (extended) ISO 8601 duration string

of_date_and_duration

Return a Period from date/duration string.

of_timedelta

Return a Period matching the duration of timedelta.

Attributes#

iso_duration

The standard ISO 8601 duration string of this period

verbose

This period's duration, offset and origin, spelled out in English words.

descriptive

This period's frequency, named where there is a common word or recognised name for it.

timedelta

A timedelta object that matches the duration of this period, or None if no such timedelta exists

tzinfo

Get the tzinfo property

offset

Return a string that captures the month and microsecond offsets of this period which conforms to the offset bit of the string required in a Period.of_duration string.

month_offset

The month offset of this period

microsecond_offset

The microsecond offset of this period

min_ordinal

Get the minimum valid ordinal of this Period.

max_ordinal

Get the maximum valid ordinal

pl_interval

A string that captures the step and multiplier of this period and which is suitable for use with Polars.

pl_offset

A string that captures the month and microsecond offsets of this period and which is suitable for use with Polars.

Methods#

Intervals and ordinals

ordinal

Return the ordinal of the interval that contains the supplied datetime.

datetime

Return the datetime at which the interval with the supplied ordinal starts.

floor

Return the first instant of the interval that contains the supplied datetime.

interval

Return the bounds of the interval containing the supplied datetime, as a (start, end) pair.

range

Yield the start of every interval overlapping the half-open window from start to end.

is_aligned

Return True if the supplied datetime is exactly the start of one of this period's intervals.

Builders

Every builder returns a new Period; none mutate the original.

with_year_offset

Return a copy of this Period with every boundary shifted by year_amount years.

with_month_offset

Return a copy of this Period with every boundary shifted by month_amount months.

with_day_offset

Return a copy of this Period with every boundary shifted by day_amount days.

with_hour_offset

Return a copy of this Period with every boundary shifted by hour_amount hours.

with_minute_offset

Return a copy of this Period with every boundary shifted by minute_amount minutes.

with_second_offset

Return a copy of this Period with every boundary shifted by second_amount seconds.

with_microsecond_offset

Return a copy of this Period with every boundary shifted by microsecond_amount microseconds.

with_origin

Return a Period derived from this one but with the origin set to the specified datetime.

with_tzinfo

Return a copy of this Period labelled with tzinfo.

without_offset

Return a Period derived from this one but with no date/time offset.

without_ordinal_shift

Return a Period derived from this one but with no ordinal shift.

base_period

Return this period stripped of any offset and origin, keeping only its step and multiplier.

Comparison

count

Return how many intervals of this period fit into each interval of other, or None if there is no constant number.

is_subperiod_of

Return True if every interval of this period falls entirely inside a single interval of other.

has_offset

Check if this period has an offset

is_epoch_agnostic

Return True if the way that this period splits the timeline does not depend on the epoch used to perform calculations.