π API referenceΒΆ
All classes are immutable.
DatetimesΒΆ
Common behaviorΒΆ
The following base classes encapsulate common behavior. They are not meant to be used directly.
- class whenever._BasicConversions[source]ΒΆ
Methods for types converting to/from the standard library and ISO8601:
(This base class class itself is not for public use.)
- abstract classmethod from_py_datetime(d: datetime, /) _T [source]ΒΆ
Create an instance from a
datetime
object. Inverse ofpy_datetime()
.Note
The datetime is checked for validity, raising similar exceptions to the constructor.
ValueError
is raised if the datetime doesnβt have the correct tzinfo matching the class. For example,ZonedDateTime
requires aZoneInfo
tzinfo.Warning
No exceptions are raised if the datetime is ambiguous. Its
fold
attribute is used to disambiguate.
- py_datetime() datetime [source]ΒΆ
Convert to a standard library
datetime
Note
Nanoseconds are truncated to microseconds. If you wish to customize the rounding behavior, use the
round()
method first.
- class whenever._KnowsInstantΒΆ
Bases:
_BasicConversions
Methods for types that represent a specific moment in time.
Implemented by:
(This base class class itself is not for public use.)
- __eq__(other: object) bool [source]ΒΆ
Check if two datetimes represent at the same moment in time
a == b
is equivalent toa.instant() == b.instant()
Note
If you want to exactly compare the values on their values instead, use
exact_eq()
.Example
>>> Instant.from_utc(2020, 8, 15, hour=23) == Instant.from_utc(2020, 8, 15, hour=23) True >>> OffsetDateTime(2020, 8, 15, hour=23, offset=1) == ( ... ZonedDateTime(2020, 8, 15, hour=18, tz="America/New_York") ... ) True
- __ge__(other: _KnowsInstant) bool [source]ΒΆ
Compare two datetimes by when they occur in time
a >= b
is equivalent toa.instant() >= b.instant()
Example
>>> OffsetDateTime(2020, 8, 15, hour=19, offset=-8) >= ( ... ZoneDateTime(2020, 8, 15, hour=20, tz="Europe/Amsterdam") ... ) True
- __gt__(other: _KnowsInstant) bool [source]ΒΆ
Compare two datetimes by when they occur in time
a > b
is equivalent toa.instant() > b.instant()
Example
>>> OffsetDateTime(2020, 8, 15, hour=19, offset=-8) > ( ... ZoneDateTime(2020, 8, 15, hour=20, tz="Europe/Amsterdam") ... ) True
- __le__(other: _KnowsInstant) bool [source]ΒΆ
Compare two datetimes by when they occur in time
a <= b
is equivalent toa.instant() <= b.instant()
Example
>>> OffsetDateTime(2020, 8, 15, hour=23, offset=8) <= ( ... ZoneDateTime(2020, 8, 15, hour=20, tz="Europe/Amsterdam") ... ) True
- __lt__(other: _KnowsInstant) bool [source]ΒΆ
Compare two datetimes by when they occur in time
a < b
is equivalent toa.instant() < b.instant()
Example
>>> OffsetDateTime(2020, 8, 15, hour=23, offset=8) < ( ... ZoneDateTime(2020, 8, 15, hour=20, tz="Europe/Amsterdam") ... ) True
- abstract __sub__(other: _KnowsInstant) TimeDelta [source]ΒΆ
Calculate the duration between two datetimes
a - b
is equivalent toa.instant() - b.instant()
Equivalent to
difference()
.See the docs on arithmetic for more information.
Example
>>> d = Instant.from_utc(2020, 8, 15, hour=23) >>> d - ZonedDateTime(2020, 8, 15, hour=20, tz="Europe/Amsterdam") TimeDelta(05:00:00)
- difference(other: Instant | OffsetDateTime | ZonedDateTime | SystemDateTime, /) TimeDelta [source]ΒΆ
Calculate the difference between two instants in time.
Equivalent to
__sub__()
.See the docs on arithmetic for more information.
- exact_eq(other: _T, /) bool [source]ΒΆ
Compare objects by their values (instead of whether they represent the same instant). Different types are never equal.
Note
If
a.exact_eq(b)
is true, thena == b
is also true, but the converse is not necessarily true.Examples
>>> a = OffsetDateTime(2020, 8, 15, hour=12, offset=1) >>> b = OffsetDateTime(2020, 8, 15, hour=13, offset=2) >>> a == b True # equivalent instants >>> a.exact_eq(b) False # different values (hour and offset) >>> a.exact_eq(Instant.now()) TypeError # different types
- classmethod from_timestamp(i: int | float, /, **kwargs) _T [source]ΒΆ
Create an instance from a UNIX timestamp. The inverse of
timestamp()
.ZonedDateTime
andOffsetDateTime
require atz=
andoffset=
kwarg, respectively.Note
from_timestamp()
also accepts floats, in order to ease migration from the standard library. Note however thattimestamp()
only returns integers. The reason is that floating point timestamps are not precise enough to represent all instants to nanosecond precision.Example
>>> Instant.from_timestamp(0) Instant(1970-01-01T00:00:00Z) >>> ZonedDateTime.from_timestamp(1_123_000_000, tz="America/New_York") ZonedDateTime(2005-08-02 12:26:40-04:00[America/New_York])
- classmethod from_timestamp_millis(i: int, /, **kwargs) _T [source]ΒΆ
Like
from_timestamp()
, but for milliseconds.
- classmethod from_timestamp_nanos(i: int, /, **kwargs) _T [source]ΒΆ
Like
from_timestamp()
, but for nanoseconds.
- classmethod now(**kwargs) _T [source]ΒΆ
Create an instance from the current time.
This method on
ZonedDateTime
andOffsetDateTime
requires atz=
andoffset=
kwarg, respectively.Example
>>> Instant.now() Instant(2021-08-15T22:12:00.49821Z) >>> ZonedDateTime.now(tz="Europe/London") ZonedDateTime(2021-08-15 23:12:00.50332+01:00[Europe/London])
- timestamp() int [source]ΒΆ
The UNIX timestamp for this datetime. Inverse of
from_timestamp()
.Note
In contrast to the standard library, this method always returns an integer, not a float. This is because floating point timestamps are not precise enough to represent all instants to nanosecond precision. This decision is consistent with other modern date-time libraries.
Example
>>> Instant.from_utc(1970, 1, 1).timestamp() 0 >>> ts = 1_123_000_000 >>> Instant.from_timestamp(ts).timestamp() == ts True
- timestamp_millis() int [source]ΒΆ
Like
timestamp()
, but with millisecond precision.
- timestamp_nanos() int [source]ΒΆ
Like
timestamp()
, but with nanosecond precision.
- to_fixed_offset(offset: int | TimeDelta | None = None, /) OffsetDateTime [source]ΒΆ
Convert to an OffsetDateTime that represents the same moment in time.
If not offset is given, the offset is taken from the original datetime.
- to_system_tz() SystemDateTime [source]ΒΆ
Convert to a SystemDateTime that represents the same moment in time.
- to_tz(tz: str, /) ZonedDateTime [source]ΒΆ
Convert to a ZonedDateTime that represents the same moment in time.
- Raises:
ZoneInfoNotFoundError β If the timezone ID is not found in the IANA database.
- class whenever._KnowsLocalΒΆ
Bases:
_BasicConversions
,ABC
Methods for types that know a local date and time:
(The class itself is not for public use.)
- abstract add(*, years: int = 0, months: int = 0, weeks: int = 0, days: int = 0, hours: float = 0, minutes: float = 0, seconds: float = 0, milliseconds: float = 0, microseconds: float = 0, nanoseconds: int = 0, **kwargs) _T [source]ΒΆ
Add date and time units to this datetime.
Arithmetic on datetimes is complicated. Additional keyword arguments
ignore_dst
anddisambiguate
may be relevant for certain types and situations. See the docs on arithmetic for more information and the reasoning behind it.
- date() Date [source]ΒΆ
The date part of the datetime
Example
>>> d = Instant.from_utc(2021, 1, 2, 3, 4, 5) >>> d.date() Date(2021-01-02)
To perform the inverse, use
Date.at()
and a method likeassume_utc()
orassume_tz()
:>>> date.at(time).assume_tz("Europe/London")
- abstract replace(**kwargs: Any) _T [source]ΒΆ
Construct a new instance with the given fields replaced.
Arguments are the same as the constructor, but only keyword arguments are allowed.
Note
If you need to shift the datetime by a duration, use the addition and subtraction operators instead. These account for daylight saving time and other complications.
Warning
The same exceptions as the constructor may be raised. For system and zoned datetimes, The
disambiguate
keyword argument is recommended to resolve ambiguities explicitly. For more information, see whenever.rtfd.io/en/latest/overview.html#ambiguity-in-timezonesExample
>>> d = LocalDateTime(2020, 8, 15, 23, 12) >>> d.replace(year=2021) LocalDateTime(2021-08-15 23:12:00) >>> >>> z = ZonedDateTime(2020, 8, 15, 23, 12, tz="Europe/London") >>> z.replace(year=2021) ZonedDateTime(2021-08-15T23:12:00+01:00)
- replace_date(date: Date, /, **kwargs) _T [source]ΒΆ
Create a new instance with the date replaced
Example
>>> d = LocalDateTime(2020, 8, 15, hour=4) >>> d.replace_date(Date(2021, 1, 1)) LocalDateTime(2021-01-01T04:00:00) >>> zdt = ZonedDateTime.now("Europe/London") >>> zdt.replace_date(Date(2021, 1, 1)) ZonedDateTime(2021-01-01T13:00:00.23439+00:00[Europe/London])
See
replace()
for more information.
- replace_time(time: Time, /, **kwargs) _T [source]ΒΆ
Create a new instance with the time replaced
Example
>>> d = LocalDateTime(2020, 8, 15, hour=4) >>> d.replace_time(Time(12, 30)) LocalDateTime(2020-08-15T12:30:00) >>> zdt = ZonedDateTime.now("Europe/London") >>> zdt.replace_time(Time(12, 30)) ZonedDateTime(2024-06-15T12:30:00+01:00[Europe/London])
See
replace()
for more information.
- round(unit: Literal['day', 'hour', 'minute', 'second', 'millisecond', 'microsecond', 'nanosecond'] = 'second', increment: int = 1, mode: Literal['ceil', 'floor', 'half_ceil', 'half_floor', 'half_even'] = 'half_even') _T [source]ΒΆ
Round the datetime to the specified unit and increment. Different rounding modes are available.
Examples
>>> d = ZonedDateTime(2020, 8, 15, 23, 24, 18, tz="Europe/Paris") >>> d.round("day") ZonedDateTime(2020-08-16 00:00:00+02:00[Europe/Paris]) >>> d.round("minute", increment=15, mode="floor") ZonedDateTime(2020-08-15 23:15:00+02:00[Europe/Paris])
Notes
In the rare case that rounding results in an ambiguous time, the offset is preserved if possible. Otherwise, the time is resolved according to the βcompatibleβ strategy.
Rounding in βdayβ mode may be affected by DST transitions. i.e. on 23-hour days, 11:31 AM is rounded up.
For
OffsetDateTime
, theignore_dst
parameter is required, because it is possible (though unlikely) that the rounded datetime will not have the same offset.This method has similar behavior to the
round()
method of Temporal objects in JavaScript.
- abstract subtract(*, years: int = 0, months: int = 0, weeks: int = 0, days: int = 0, hours: float = 0, minutes: float = 0, seconds: float = 0, milliseconds: float = 0, microseconds: float = 0, nanoseconds: int = 0, **kwargs) _T [source]ΒΆ
Inverse of
add()
.
- time() Time [source]ΒΆ
The time-of-day part of the datetime
Example
>>> d = ZonedDateTime(2021, 1, 2, 3, 4, 5, tz="Europe/Paris") ZonedDateTime(2021-01-02T03:04:05+01:00[Europe/Paris]) >>> d.time() Time(03:04:05)
To perform the inverse, use
Time.on()
and a method likeassume_utc()
orassume_tz()
:>>> time.on(date).assume_tz("Europe/Paris")
- class whenever._KnowsInstantAndLocalΒΆ
Bases:
_KnowsLocal
,_KnowsInstant
Common behavior for all types that know both a local time and an instant:
(The class itself it not for public use.)
- instant() Instant [source]ΒΆ
Get the underlying instant in time
Example
>>> d = ZonedDateTime(2020, 8, 15, hour=23, tz="Europe/Amsterdam") >>> d.instant() Instant(2020-08-15 21:00:00Z)
- local() LocalDateTime [source]ΒΆ
Get the underlying local date and time
As an inverse,
LocalDateTime
has methodsassume_utc()
,assume_fixed_offset()
,assume_tz()
, andassume_system_tz()
which may require additional arguments.
Concrete classesΒΆ
- class whenever.InstantΒΆ
Bases:
_KnowsInstant
Represents a moment in time with nanosecond precision.
This class is great for representing a specific point in time independent of location. It maps 1:1 to UTC or a UNIX timestamp.
Example
>>> from whenever import Instant >>> py311_release = Instant.from_utc(2022, 10, 24, hour=17) Instant(2022-10-24 17:00:00Z) >>> py311_release.add(hours=3).timestamp() 1666641600
- classmethod from_utc(year: int, month: int, day: int, hour: int = 0, minute: int = 0, second: int = 0, *, nanosecond: int = 0) Instant [source]ΒΆ
Create an Instant defined by a UTC date and time.
- format_rfc3339() str [source]ΒΆ
Format as an RFC 3339 string
YYYY-MM-DD HH:MM:SSZ
If you prefer the
T
separator, use format_common_iso() instead.The inverse of the
parse_rfc3339()
method.Example
>>> Instant.from_utc(2020, 8, 15, hour=23, minute=12).format_rfc3339() "2020-08-15 23:12:00Z"
- classmethod parse_rfc3339(s: str, /) Instant [source]ΒΆ
Parse a UTC datetime in RFC 3339 format.
The inverse of the
format_rfc3339()
method.Example
>>> Instant.parse_rfc3339("2020-08-15 23:12:00Z") Instant(2020-08-15 23:12:00Z) >>> >>> # also valid: >>> Instant.parse_rfc3339("2020-08-15T23:12:00+00:00") >>> Instant.parse_rfc3339("2020-08-15_23:12:00.34Z") >>> Instant.parse_rfc3339("2020-08-15t23:12:00z") >>> >>> # not valid (nonzero offset): >>> Instant.parse_rfc3339("2020-08-15T23:12:00+02:00")
Important
Nonzero offsets will not be implicitly converted to UTC, but will raise a ValueError. Use
OffsetDateTime.parse_rfc3339()
if youβd like to parse an RFC 3339 string with a nonzero offset.
- format_rfc2822() str [source]ΒΆ
Format as an RFC 2822 string.
The inverse of the
parse_rfc2822()
method.Example
>>> Instant.from_utc(2020, 8, 15, hour=23, minute=12).format_rfc2822() "Sat, 15 Aug 2020 23:12:00 GMT"
- classmethod parse_rfc2822(s: str, /) Instant [source]ΒΆ
Parse a UTC datetime in RFC 2822 format.
The inverse of the
format_rfc2822()
method.Example
>>> Instant.parse_rfc2822("Sat, 15 Aug 2020 23:12:00 GMT") Instant(2020-08-15 23:12:00Z)
>>> # also valid: >>> Instant.parse_rfc2822("Sat, 15 Aug 2020 23:12:00 +0000") >>> Instant.parse_rfc2822("Sat, 15 Aug 2020 23:12:00 -0000") >>> Instant.parse_rfc2822("Sat, 15 Aug 2020 23:12:00 UT") >>> Instant.parse_rfc2822("Sat, 15 Aug 2020 23:12:00 UTC")
>>> # Error: includes offset. Use OffsetDateTime.parse_rfc2822() instead >>> Instant.parse_rfc2822("Sat, 15 Aug 2020 23:12:00 +0200")
Important
This function parses, but does not validate the input (yet). This is due to the limitations of the underlying function
email.utils.parsedate_to_datetime()
.Nonzero offsets will not be implicitly converted to UTC. Use
OffsetDateTime.parse_rfc2822()
if youβd like to parse an RFC 2822 string with a nonzero offset.
- add(*, hours: float = 0, minutes: float = 0, seconds: float = 0, milliseconds: float = 0, microseconds: float = 0, nanoseconds: int = 0) Instant [source]ΒΆ
Add a time amount to this instant.
See the docs on arithmetic for more information.
- subtract(*, hours: float = 0, minutes: float = 0, seconds: float = 0, milliseconds: float = 0, microseconds: float = 0, nanoseconds: int = 0) Instant [source]ΒΆ
Subtract a time amount from this instant.
See the docs on arithmetic for more information.
- round(unit: Literal['hour', 'minute', 'second', 'millisecond', 'microsecond', 'nanosecond'] = 'second', increment: int = 1, mode: Literal['ceil', 'floor', 'half_ceil', 'half_floor', 'half_even'] = 'half_even') Instant [source]ΒΆ
Round the instant to the specified unit and increment. Various rounding modes are available.
Examples
>>> Instant.from_utc(2020, 1, 1, 12, 39, 59).round("minute", 15) Instant(2020-01-01 12:45:00Z) >>> Instant.from_utc(2020, 1, 1, 8, 9, 13).round("second", 5, mode="floor") Instant(2020-01-01 08:09:10Z)
- __add__(delta: TimeDelta) Instant [source]ΒΆ
Add a time amount to this datetime.
See the docs on arithmetic for more information.
- __sub__(other: TimeDelta | _KnowsInstant) Instant | TimeDelta [source]ΒΆ
Subtract another exact time or timedelta
Subtraction of deltas happens in the same way as the
subtract()
method. Subtraction of instants happens the same way as thedifference()
method.See the docs on arithmetic for more information.
Example
>>> d = Instant.from_utc(2020, 8, 15, hour=23, minute=12) >>> d - hours(24) - seconds(5) Instant(2020-08-14 23:11:55Z) >>> d - Instant.from_utc(2020, 8, 14) TimeDelta(47:12:00)
- class whenever.LocalDateTime(year: int, month: int, day: int, hour: int = 0, minute: int = 0, second: int = 0, *, nanosecond: int = 0)ΒΆ
Bases:
_KnowsLocal
A local date and time, i.e. it would appear to people on a wall clock.
It canβt be mixed with aware datetimes. Conversion to aware datetimes can only be done by explicitly assuming a timezone or offset.
Examples of when to use this type:
You need to express a date and time as it would be observed locally on the βwall clockβ or calendar.
You receive a date and time without any timezone information, and you need a type to represent this lack of information.
In the rare case you truly donβt need to account for timezones, or Daylight Saving Time transitions. For example, when modeling time in a simulation game.
- MIN: ClassVar[LocalDateTime] = LocalDateTime(0001-01-01 00:00:00)ΒΆ
- MAX: ClassVar[LocalDateTime] = LocalDateTime(9999-12-31 23:59:59.999999999)ΒΆ
- assume_utc() Instant [source]ΒΆ
Assume the datetime is in UTC, creating an
Instant
.Example
>>> LocalDateTime(2020, 8, 15, 23, 12).assume_utc() Instant(2020-08-15 23:12:00Z)
- assume_fixed_offset(offset: int | TimeDelta, /) OffsetDateTime [source]ΒΆ
Assume the datetime has the given offset, creating an
OffsetDateTime
.Example
>>> LocalDateTime(2020, 8, 15, 23, 12).assume_fixed_offset(+2) OffsetDateTime(2020-08-15 23:12:00+02:00)
- assume_tz(tz: str, /, disambiguate: Literal['compatible', 'earlier', 'later', 'raise'] = 'compatible') ZonedDateTime [source]ΒΆ
Assume the datetime is in the given timezone, creating a
ZonedDateTime
.Note
The local datetime may be ambiguous in the given timezone (e.g. during a DST transition). Therefore, you must explicitly specify how to handle such a situation using the
disambiguate
argument. See the documentation for more information.Example
>>> d = LocalDateTime(2020, 8, 15, 23, 12) >>> d.assume_tz("Europe/Amsterdam", disambiguate="raise") ZonedDateTime(2020-08-15 23:12:00+02:00[Europe/Amsterdam])
- assume_system_tz(disambiguate: Literal['compatible', 'earlier', 'later', 'raise'] = 'compatible') SystemDateTime [source]ΒΆ
Assume the datetime is in the system timezone, creating a
SystemDateTime
.Note
The local datetime may be ambiguous in the system timezone (e.g. during a DST transition). Therefore, you must explicitly specify how to handle such a situation using the
disambiguate
argument. See the documentation for more information.Example
>>> d = LocalDateTime(2020, 8, 15, 23, 12) >>> # assuming system timezone is America/New_York >>> d.assume_system_tz(disambiguate="raise") SystemDateTime(2020-08-15 23:12:00-04:00)
- classmethod strptime(s: str, /, fmt: str) LocalDateTime [source]ΒΆ
Simple alias for
LocalDateTime.from_py_datetime(datetime.strptime(s, fmt))
Example
>>> LocalDateTime.strptime("2020-08-15", "%Y-%m-%d") LocalDateTime(2020-08-15 00:00:00)
Note
The parsed
tzinfo
must be beNone
. This means you CANNOT include the directives%z
,%Z
, or%:z
in the format string.
- difference(other: LocalDateTime, /, *, ignore_dst: bool = False) TimeDelta [source]ΒΆ
Calculate the difference between two local datetimes.
Important
The difference between two local datetimes implicitly ignores DST transitions and other timezone changes. To perform DST-safe operations, convert to a
ZonedDateTime
first. Or, if you donβt know the timezone and accept potentially incorrect results during DST transitions, passignore_dst=True
. For more information, see the docs.
- __eq__(other: object) bool [source]ΒΆ
Compare objects for equality. Only ever equal to other
LocalDateTime
instances with the same values.Warning
To comply with the Python data model, this method canβt raise a
TypeError
when comparing with other types. Although it seems to be the sensible response, it would result in surprising behavior when using values as dictionary keys.Use mypyβs
--strict-equality
flag to detect and prevent this.Example
>>> LocalDateTime(2020, 8, 15, 23) == LocalDateTime(2020, 8, 15, 23) True >>> LocalDateTime(2020, 8, 15, 23, 1) == LocalDateTime(2020, 8, 15, 23) False >>> LocalDateTime(2020, 8, 15) == Instant.from_utc(2020, 8, 15) False # Use mypy's --strict-equality flag to detect this.
- class whenever.OffsetDateTime(year: int, month: int, day: int, hour: int = 0, minute: int = 0, second: int = 0, *, nanosecond: int = 0, offset: int | TimeDelta)ΒΆ
Bases:
_KnowsInstantAndLocal
A datetime with a fixed UTC offset. Useful for representing the local time at a specific location.
Example
>>> # Midnight in Salt Lake City >>> OffsetDateTime(2023, 4, 21, offset=-6) OffsetDateTime(2023-04-21 00:00:00-06:00)
Note
Adjusting instances of this class do not account for daylight saving time. If you need to add or subtract durations from an offset datetime and account for DST, convert to a
ZonedDateTime
first, This class knows when the offset changes.- format_rfc3339() str [source]ΒΆ
Format as an RFC 3339 string
YYYY-MM-DD HH:MM:SSΒ±HH:MM
If you prefer the
T
separator, useformat_common_iso()
instead.The inverse of the
parse_rfc3339()
method.Example
>>> OffsetDateTime(2020, 8, 15, hour=23, minute=12, offset=hours(4)).format_rfc3339() "2020-08-15 23:12:00+04:00"
Note
The RFC3339 format does not allow for second-level precision of the UTC offset. This should not be a problem in practice, unless youβre dealing with pre-1950s timezones. The
format_common_iso()
does support this precision.
- format_rfc2822() str [source]ΒΆ
Format as an RFC 2822 string.
The inverse of the
parse_rfc2822()
method.Example
>>> OffsetDateTime(2020, 8, 15, 23, 12, offset=hours(2)).format_rfc2822() "Sat, 15 Aug 2020 23:12:00 +0200"
- classmethod parse_rfc3339(s: str, /) OffsetDateTime [source]ΒΆ
Parse a fixed-offset datetime in RFC 3339 format.
The inverse of the
format_rfc3339()
method.Example
>>> OffsetDateTime.parse_rfc3339("2020-08-15 23:12:00+02:00") OffsetDateTime(2020-08-15 23:12:00+02:00) >>> # also valid: >>> OffsetDateTime.parse_rfc3339("2020-08-15T23:12:00Z") >>> OffsetDateTime.parse_rfc3339("2020-08-15_23:12:00.23-12:00") >>> OffsetDateTime.parse_rfc3339("2020-08-15t23:12:00z")
- classmethod parse_rfc2822(s: str, /) OffsetDateTime [source]ΒΆ
Parse an offset datetime in RFC 2822 format.
The inverse of the
format_rfc2822()
method.Example
>>> OffsetDateTime.parse_rfc2822("Sat, 15 Aug 2020 23:12:00 +0200") OffsetDateTime(2020-08-15 23:12:00+02:00) >>> # also valid: >>> OffsetDateTime.parse_rfc2822("Sat, 15 Aug 2020 23:12:00 UT") >>> OffsetDateTime.parse_rfc2822("Sat, 15 Aug 2020 23:12:00 GMT") >>> OffsetDateTime.parse_rfc2822("Sat, 15 Aug 2020 23:12:00 MST")
Warning
This function parses, but does not validate the input (yet). This is due to the limitations of the underlying function
email.utils.parsedate_to_datetime()
.The offset
-0000
has special meaning in RFC 2822, indicating a UTC time with unknown local offset. Thus, it cannot be parsed to anOffsetDateTime
.
- classmethod strptime(s: str, /, fmt: str) OffsetDateTime [source]ΒΆ
Simple alias for
OffsetDateTime.from_py_datetime(datetime.strptime(s, fmt))
Example
>>> OffsetDateTime.strptime("2020-08-15+0200", "%Y-%m-%d%z") OffsetDateTime(2020-08-15 00:00:00+02:00)
Important
The parsed
tzinfo
must be a fixed offset (datetime.timezone
instance). This means you MUST include the directive%z
,%Z
, or%:z
in the format string.
- class whenever.ZonedDateTime(year: int, month: int, day: int, hour: int = 0, minute: int = 0, second: int = 0, *, nanosecond: int = 0, tz: str, disambiguate: Literal['compatible', 'earlier', 'later', 'raise'] = 'compatible')ΒΆ
Bases:
_KnowsInstantAndLocal
A datetime associated with a timezone in the IANA database. Useful for representing the exact time at a specific location.
Example
>>> ZonedDateTime(2024, 12, 8, hour=11, tz="Europe/Paris") ZonedDateTime(2024-12-08 11:00:00+01:00[Europe/Paris]) >>> # Explicitly resolve ambiguities during DST transitions >>> ZonedDateTime(2023, 10, 29, 1, 15, tz="Europe/London", disambiguate="earlier") ZonedDateTime(2023-10-29 01:15:00+01:00[Europe/London])
Important
To use this type properly, read more about ambiguity in timezones.
- is_ambiguous() bool [source]ΒΆ
Whether the local time is ambiguous, e.g. due to a DST transition.
Example
>>> ZonedDateTime(2020, 8, 15, 23, tz="Europe/London").is_ambiguous() False >>> ZonedDateTime(2023, 10, 29, 2, 15, tz="Europe/Amsterdam").is_ambiguous() True
- start_of_day() ZonedDateTime [source]ΒΆ
The start of the current calendar day.
This is almost always at midnight the same day, but may be different for timezones which transition atβand thus skip overβmidnight.
- day_length() TimeDelta [source]ΒΆ
The duration between the start of the current day and the next. This is usually 24 hours, but may be different due to timezone transitions.
Example
>>> ZonedDateTime(2020, 8, 15, tz="Europe/London").day_length() TimeDelta(24:00:00) >>> ZonedDateTime(2023, 10, 29, tz="Europe/Amsterdam").day_length() TimeDelta(25:00:00)
- class whenever.SystemDateTime(year: int, month: int, day: int, hour: int = 0, minute: int = 0, second: int = 0, *, nanosecond: int = 0, disambiguate: Literal['compatible', 'earlier', 'later', 'raise'] = 'compatible')ΒΆ
Bases:
_KnowsInstantAndLocal
Represents a time in the system timezone. It is similar to
OffsetDateTime
, but it knows about the system timezone and its DST transitions.Example
>>> # 8:00 in the system timezoneβParis in this case >>> alarm = SystemDateTime(2024, 3, 31, hour=6) SystemDateTime(2024-03-31 06:00:00+02:00) >>> # Conversion based on Paris' offset >>> alarm.instant() Instant(2024-03-31 04:00:00Z) >>> # DST-safe arithmetic >>> bedtime = alarm - hours(8) SystemDateTime(2024-03-30 21:00:00+01:00)
Attention
To use this type properly, read more about ambiguity and working with the system timezone.
- is_ambiguous() bool [source]ΒΆ
Whether the local time is ambiguous, e.g. due to a DST transition.
Example
>>> # with system configured in Europe/Paris >>> SystemDateTime(2020, 8, 15, 23).is_ambiguous() False >>> SystemDateTime(2023, 10, 29, 2, 15).is_ambiguous() True
Note
This method may give a different result after a change to the system timezone.
- start_of_day() SystemDateTime [source]ΒΆ
The start of the current calendar day.
This is almost always at midnight the same day, but may be different for timezones which transition atβand thus skip overβmidnight.
Note
This method may give a different result after a change to the system timezone.
- day_length() TimeDelta [source]ΒΆ
The duration between the start of the current day and the next. This is usually 24 hours, but may be different due to timezone transitions.
Example
>>> # with system configured in Europe/Paris >>> SystemDateTime(2020, 8, 15).day_length() TimeDelta(24:00:00) >>> SystemDateTime(2023, 10, 29).day_length() TimeDelta(25:00:00)
Note
This method may give a different result after a change to the system timezone.
DeltasΒΆ
- whenever.years(i: int, /) DateDelta ΒΆ
Create a
DateDelta
with the given number of years.years(1) == DateDelta(years=1)
- whenever.months(i: int, /) DateDelta ΒΆ
Create a
DateDelta
with the given number of months.months(1) == DateDelta(months=1)
- whenever.weeks(i: int, /) DateDelta ΒΆ
Create a
DateDelta
with the given number of weeks.weeks(1) == DateDelta(weeks=1)
- whenever.days(i: int, /) DateDelta ΒΆ
Create a
DateDelta
with the given number of days.days(1) == DateDelta(days=1)
- whenever.hours(i: float, /) TimeDelta ΒΆ
Create a
TimeDelta
with the given number of hours.hours(1) == TimeDelta(hours=1)
- whenever.minutes(i: float, /) TimeDelta ΒΆ
Create a
TimeDelta
with the given number of minutes.minutes(1) == TimeDelta(minutes=1)
- whenever.seconds(i: float, /) TimeDelta ΒΆ
Create a
TimeDelta
with the given number of seconds.seconds(1) == TimeDelta(seconds=1)
- whenever.milliseconds(i: int, /) TimeDelta ΒΆ
Create a
TimeDelta
with the given number of milliseconds.milliseconds(1) == TimeDelta(milliseconds=1)
- whenever.microseconds(i: float, /) TimeDelta ΒΆ
Create a
TimeDelta
with the given number of microseconds.microseconds(1) == TimeDelta(microseconds=1)
- whenever.nanoseconds(i: int, /) TimeDelta ΒΆ
Create a
TimeDelta
with the given number of nanoseconds.nanoseconds(1) == TimeDelta(nanoseconds=1)
- class whenever.TimeDelta(*, hours: float = 0, minutes: float = 0, seconds: float = 0, milliseconds: float = 0, microseconds: float = 0, nanoseconds: int = 0)ΒΆ
A duration consisting of a precise time: hours, minutes, (nano)seconds
The inputs are normalized, so 90 minutes becomes 1 hour and 30 minutes, for example.
Examples
>>> d = TimeDelta(hours=1, minutes=30) TimeDelta(01:30:00) >>> d.in_minutes() 90.0
Note
A shorter way to instantiate a timedelta is to use the helper functions
hours()
,minutes()
, etc.- __abs__() TimeDelta [source]ΒΆ
The absolute value
Example
>>> d = TimeDelta(hours=-1, minutes=-30) >>> abs(d) TimeDelta(01:30:00)
- __add__(other: TimeDelta) TimeDelta [source]ΒΆ
Add two deltas together
Example
>>> d = TimeDelta(hours=1, minutes=30) >>> d + TimeDelta(minutes=30) TimeDelta(02:00:00)
- __bool__() bool [source]ΒΆ
True if the value is non-zero
Example
>>> bool(TimeDelta()) False >>> bool(TimeDelta(minutes=1)) True
- __eq__(other: object) bool [source]ΒΆ
Compare for equality
Example
>>> d = TimeDelta(hours=1, minutes=30) >>> d == TimeDelta(minutes=90) True >>> d == TimeDelta(hours=2) False
- __mul__(other: float) TimeDelta [source]ΒΆ
Multiply by a number
Example
>>> d = TimeDelta(hours=1, minutes=30) >>> d * 2.5 TimeDelta(03:45:00)
- __neg__() TimeDelta [source]ΒΆ
Negate the value
Example
>>> d = TimeDelta(hours=1, minutes=30) >>> -d TimeDelta(-01:30:00)
- __sub__(other: TimeDelta) TimeDelta [source]ΒΆ
Subtract two deltas
Example
>>> d = TimeDelta(hours=1, minutes=30) >>> d - TimeDelta(minutes=30) TimeDelta(01:00:00)
- __truediv__(other: float | TimeDelta) TimeDelta | float [source]ΒΆ
Divide by a number or another delta
Example
>>> d = TimeDelta(hours=1, minutes=30) >>> d / 2.5 TimeDelta(00:36:00) >>> d / TimeDelta(minutes=30) 3.0
Note
Because TimeDelta is limited to nanosecond precision, the result of division may not be exact.
- format_common_iso() 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_common_iso()
.Example
>>> TimeDelta(hours=1, minutes=30).format_common_iso() 'PT1H30M'
- classmethod from_py_timedelta(td: timedelta, /) TimeDelta [source]ΒΆ
Create from a
timedelta
Inverse of
py_timedelta()
Example
>>> TimeDelta.from_py_timedelta(timedelta(seconds=5400)) TimeDelta(01:30:00)
- in_days_of_24h() float [source]ΒΆ
The total size in days (of exactly 24 hours each)
Note
Note that this may not be the same as days on the calendar, since some days have 23 or 25 hours due to daylight saving time.
- in_hours() float [source]ΒΆ
The total size in hours
Example
>>> d = TimeDelta(hours=1, minutes=30) >>> d.in_hours() 1.5
- in_hrs_mins_secs_nanos() tuple[int, int, int, int] [source]ΒΆ
Convert to a tuple of (hours, minutes, seconds, nanoseconds)
Example
>>> d = TimeDelta(hours=1, minutes=30, microseconds=5_000_090) >>> d.in_hrs_mins_secs_nanos() (1, 30, 5, 90_000)
- in_microseconds() float [source]ΒΆ
The total size in microseconds
>>> d = TimeDelta(seconds=2, nanoseconds=50) >>> d.in_microseconds() 2_000_000.05
- in_milliseconds() float [source]ΒΆ
The total size in milliseconds
>>> d = TimeDelta(seconds=2, microseconds=50) >>> d.in_milliseconds() 2_000.05
- in_minutes() float [source]ΒΆ
The total size in minutes
Example
>>> d = TimeDelta(hours=1, minutes=30, seconds=30) >>> d.in_minutes() 90.5
- in_nanoseconds() int [source]ΒΆ
The total size in nanoseconds
>>> d = TimeDelta(seconds=2, nanoseconds=50) >>> d.in_nanoseconds() 2_000_000_050
- in_seconds() float [source]ΒΆ
The total size in seconds
Example
>>> d = TimeDelta(minutes=2, seconds=1, microseconds=500_000) >>> d.in_seconds() 121.5
- classmethod parse_common_iso(s: str, /) TimeDelta [source]ΒΆ
Parse the popular interpretation of the ISO 8601 duration format. Does not parse all possible ISO 8601 durations. See here for more information.
Inverse of
format_common_iso()
Example
>>> TimeDelta.parse_common_iso("PT1H30M") TimeDelta(01:30:00)
Note
Any duration with a date part is considered invalid.
PT0S
is valid, butP0D
is not.
- py_timedelta() timedelta [source]ΒΆ
Convert to a
timedelta
Inverse of
from_py_timedelta()
Note
Nanoseconds are truncated to microseconds. If you need more control over rounding, use
round()
first.Example
>>> d = TimeDelta(hours=1, minutes=30) >>> d.py_timedelta() timedelta(seconds=5400)
- round(unit: Literal['hour', 'minute', 'second', 'millisecond', 'microsecond', 'nanosecond'] = 'second', increment: int = 1, mode: Literal['ceil', 'floor', 'half_ceil', 'half_floor', 'half_even'] = 'half_even') TimeDelta [source]ΒΆ
Round the delta to the specified unit and increment. Various rounding modes are available.
Examples
>>> t = TimeDelta(seconds=12345) TimeDelta(03:25:45) >>> t.round("minute") TimeDelta(03:26:00) >>> t.round("second", increment=10, mode="floor") Time(03:25:40)
- class whenever.DateDelta(*, years: int = 0, months: int = 0, weeks: int = 0, days: int = 0)ΒΆ
A duration of time consisting of calendar units (years, months, weeks, and days)
- __abs__() DateDelta [source]ΒΆ
If the contents are negative, return the positive version
Example
>>> p = DateDelta(months=-2, days=-3) >>> abs(p) DateDelta(P2M3D)
- __add__(other: DateDelta | TimeDelta) DateDelta | DateTimeDelta [source]ΒΆ
Add the fields of another delta to this one
Example
>>> p = DateDelta(weeks=2, months=1) >>> p + DateDelta(weeks=1, days=4) DateDelta(P1M25D)
- __bool__() bool [source]ΒΆ
True if any contains any non-zero data
Example
>>> bool(DateDelta()) False >>> bool(DateDelta(days=-1)) True
- __eq__(other: object) bool [source]ΒΆ
Compare for equality, normalized to months and days.
a == b is equivalent to a.in_months_days() == b.in_months_days()
Example
>>> p = DateDelta(weeks=4, days=2) DateDelta(P30D) >>> p == DateDelta(weeks=3, days=9) True >>> p == DateDelta(weeks=2, days=4) True # same number of days >>> p == DateDelta(months=1) False # months and days cannot be compared directly
- __mul__(other: int) DateDelta [source]ΒΆ
Multiply the contents by a round number
Example
>>> p = DateDelta(years=1, weeks=2) >>> p * 2 DateDelta(P2Y28D)
- __neg__() DateDelta [source]ΒΆ
Negate the contents
Example
>>> p = DateDelta(weeks=2, days=3) >>> -p DateDelta(-P17D)
- __sub__(other: DateDelta | TimeDelta) DateDelta | DateTimeDelta [source]ΒΆ
Subtract the fields of another delta from this one
Example
>>> p = DateDelta(weeks=2, days=3) >>> p - DateDelta(days=2) DateDelta(P15D)
- format_common_iso() 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_common_iso()
.The format looks like this:
P(nY)(nM)(nD)
For example:
P1D P2M P1Y2M3W4D
Example
>>> p = DateDelta(years=1, months=2, weeks=3, days=11) >>> p.common_iso() 'P1Y2M3W11D' >>> DateDelta().common_iso() 'P0D'
- in_months_days() tuple[int, int] [source]ΒΆ
Convert to a tuple of months and days.
Example
>>> p = DateDelta(months=25, days=9) >>> p.in_months_days() (25, 9) >>> DateDelta(months=-13, weeks=-5) (-13, -35)
- in_years_months_days() tuple[int, int, int] [source]ΒΆ
Convert to a tuple of years, months, and days.
Example
>>> p = DateDelta(years=1, months=2, days=11) >>> p.in_years_months_days() (1, 2, 11)
- classmethod parse_common_iso(s: str, /) DateDelta [source]ΒΆ
Parse the popular interpretation of the ISO 8601 duration format. Does not parse all possible ISO 8601 durations. See here for more information.
Inverse of
format_common_iso()
Example
>>> DateDelta.parse_common_iso("P1W11D") DateDelta(P1W11D) >>> DateDelta.parse_common_iso("-P3M") DateDelta(-P3M)
Note
Only durations without time component are accepted.
P0D
is valid, butPT0S
is not.Note
The number of digits in each component is limited to 8.
- class whenever.DateTimeDelta(*, years: int = 0, months: int = 0, weeks: int = 0, days: int = 0, hours: float = 0, minutes: float = 0, seconds: float = 0, milliseconds: float = 0, microseconds: float = 0, nanoseconds: int = 0)ΒΆ
A duration with both a date and time component.
- __abs__() DateTimeDelta [source]ΒΆ
The absolute value of the delta
Example
>>> d = DateTimeDelta(weeks=1, days=-11, hours=4) >>> abs(d) DateTimeDelta(P1W11DT4H)
- __add__(other: DateTimeDelta | TimeDelta | DateDelta) DateTimeDelta [source]ΒΆ
Add two deltas together
Example
>>> d = DateTimeDelta(weeks=1, days=11, hours=4) >>> d + DateTimeDelta(months=2, days=3, minutes=90) DateTimeDelta(P1M1W14DT5H30M)
- __bool__() bool [source]ΒΆ
True if any field is non-zero
Example
>>> bool(DateTimeDelta()) False >>> bool(DateTimeDelta(minutes=1)) True
- __eq__(other: object) bool [source]ΒΆ
Compare for equality
Example
>>> d = DateTimeDelta( ... weeks=1, ... days=23, ... hours=4, ... ) >>> d == DateTimeDelta( ... weeks=1, ... days=23, ... minutes=4 * 60, # normalized ... ) True >>> d == DateTimeDelta( ... weeks=4, ... days=2, # days/weeks are normalized ... hours=4, ... ) True >>> d == DateTimeDelta( ... months=1, # months/days cannot be compared directly ... hours=4, ... ) False
- __mul__(other: int) DateTimeDelta [source]ΒΆ
Multiply by a number
Example
>>> d = DateTimeDelta(weeks=1, days=11, hours=4) >>> d * 2 DateTimeDelta(P2W22DT8H)
- __neg__() DateTimeDelta [source]ΒΆ
Negate the delta
Example
>>> d = DateTimeDelta(days=11, hours=4) >>> -d DateTimeDelta(-P11DT4H)
- __sub__(other: DateTimeDelta | TimeDelta | DateDelta) DateTimeDelta [source]ΒΆ
Subtract two deltas
Example
>>> d = DateTimeDelta(weeks=1, days=11, hours=4) >>> d - DateTimeDelta(months=2, days=3, minutes=90) DateTimeDelta(-P2M1W8DT2H30M)
- format_common_iso() 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_common_iso()
.The format is:
P(nY)(nM)(nD)T(nH)(nM)(nS)
Example
>>> d = DateTimeDelta( ... weeks=1, ... days=11, ... hours=4, ... milliseconds=12, ... ) >>> d.format_common_iso() 'P1W11DT4H0.012S'
- in_months_days_secs_nanos() tuple[int, int, int, int] [source]ΒΆ
Convert to a tuple of (months, days, seconds, nanoseconds)
Example
>>> d = DateTimeDelta(weeks=1, days=11, hours=4, microseconds=2) >>> d.in_months_days_secs_nanos() (0, 18, 14_400, 2000)
- classmethod parse_common_iso(s: str, /) DateTimeDelta [source]ΒΆ
Parse the popular interpretation of the ISO 8601 duration format. Does not parse all possible ISO 8601 durations. See here for more information.
Examples:
P4D # 4 days PT4H # 4 hours PT3M40.5S # 3 minutes and 40.5 seconds P1W11DT4H # 1 week, 11 days, and 4 hours -PT7H4M # -7 hours and -4 minutes (-7:04:00) +PT7H4M # 7 hours and 4 minutes (7:04:00)
Inverse of
format_common_iso()
Example
>>> DateTimeDelta.parse_common_iso("-P1W11DT4H") DateTimeDelta(-P1W11DT4H)
Date and time componentsΒΆ
- class whenever.Date(year: int, month: int, day: int)ΒΆ
A date without a time component
Example
>>> d = Date(2021, 1, 2) Date(2021-01-02)
- __eq__(other: object) bool [source]ΒΆ
Compare for equality
Example
>>> d = Date(2021, 1, 2) >>> d == Date(2021, 1, 2) True >>> d == Date(2021, 1, 3) False
- __sub__(d: DateDelta | Date) Date | DateDelta [source]ΒΆ
Subtract a delta from a date, or subtract two dates
Subtracting a delta works the same as
subtract()
.>>> Date(2021, 1, 2) - DateDelta(weeks=1, days=3) Date(2020-12-26)
The difference between two dates is calculated in months and days, such that:
>>> delta = d1 - d2 >>> d2 + delta == d1 # always
The following is not always true:
>>> d1 - (d1 - d2) == d2 # not always true! >>> -(d2 - d1) == d1 - d2 # not always true!
Examples:
>>> Date(2023, 4, 15) - Date(2011, 6, 24) DateDelta(P12Y9M22D) >>> # Truncation >>> Date(2024, 4, 30) - Date(2023, 5, 31) DateDelta(P11M) >>> Date(2024, 3, 31) - Date(2023, 6, 30) DateDelta(P9M1D) >>> # the other way around, the result is different >>> Date(2023, 6, 30) - Date(2024, 3, 31) DateDelta(-P9M)
Note
If youβd like to calculate the difference in days only (no months), use the
days_until()
ordays_since()
instead.
- add(*args, **kwargs) Date [source]ΒΆ
Add a components to a date.
See the docs on arithmetic for more information.
Example
>>> d = Date(2021, 1, 2) >>> d.add(years=1, months=2, days=3) Date(2022-03-05) >>> Date(2020, 2, 29).add(years=1) Date(2021-02-28)
- at(t: Time, /) LocalDateTime [source]ΒΆ
Combine a date with a time to create a datetime
Example
>>> d = Date(2021, 1, 2) >>> d.at(Time(12, 30)) LocalDateTime(2021-01-02 12:30:00)
You can use methods like
assume_utc()
orassume_tz()
to make the result aware.
- day_of_week() Weekday [source]ΒΆ
The day of the week
Example
>>> Date(2021, 1, 2).day_of_week() Weekday.SATURDAY >>> Weekday.SATURDAY.value 6 # the ISO value
- days_since(other: Date, /) int [source]ΒΆ
Calculate the number of days this day is after another date. If the other date is after this date, the result is negative.
Example
>>> Date(2021, 1, 5).days_since(Date(2021, 1, 2)) 3
Note
If youβre interested in calculating the difference in terms of days and months, use the subtraction operator instead.
- days_until(other: Date, /) int [source]ΒΆ
Calculate the number of days from this date to another date. If the other date is before this date, the result is negative.
Example
>>> Date(2021, 1, 2).days_until(Date(2021, 1, 5)) 3
Note
If youβre interested in calculating the difference in terms of days and months, use the subtraction operator instead.
- format_common_iso() str [source]ΒΆ
Format as the common ISO 8601 date format.
Inverse of
parse_common_iso()
.Example
>>> Date(2021, 1, 2).format_common_iso() '2021-01-02'
- classmethod from_py_date(d: date, /) Date [source]ΒΆ
Create from a
date
Example
>>> Date.from_py_date(date(2021, 1, 2)) Date(2021-01-02)
- month_day() MonthDay [source]ΒΆ
The month and day (without a year component)
Example
>>> Date(2021, 1, 2).month_day() MonthDay(--01-02)
- classmethod parse_common_iso(s: str, /) Date [source]ΒΆ
Create from the common ISO 8601 date format
YYYY-MM-DD
. Does not accept more βexoticβ ISO 8601 formats.Inverse of
format_common_iso()
Example
>>> Date.parse_common_iso("2021-01-02") Date(2021-01-02)
- replace(**kwargs: Any) Date [source]ΒΆ
Create a new instance with the given fields replaced
Example
>>> d = Date(2021, 1, 2) >>> d.replace(day=4) Date(2021-01-04)
- subtract(*args, **kwargs) Date [source]ΒΆ
Subtract components from a date.
See the docs on arithmetic for more information.
Example
>>> d = Date(2021, 1, 2) >>> d.subtract(years=1, months=2, days=3) Date(2019-10-30) >>> Date(2021, 3, 1).subtract(years=1) Date(2020-03-01)
- class whenever.YearMonth(year: int, month: int)ΒΆ
A year and month without a day component
Useful for representing recurring events or billing periods.
Example
>>> ym = YearMonth(2021, 1) YearMonth(2021-01)
- __eq__(other: object) bool [source]ΒΆ
Compare for equality
Example
>>> ym = YearMonth(2021, 1) >>> ym == YearMonth(2021, 1) True >>> ym == YearMonth(2021, 2) False
- format_common_iso() str [source]ΒΆ
Format as the common ISO 8601 year-month format.
Inverse of
parse_common_iso()
.Example
>>> YearMonth(2021, 1).format_common_iso() '2021-01'
- on_day(day: int, /) Date [source]ΒΆ
Create a date from this year-month with a given day
Example
>>> YearMonth(2021, 1).on_day(2) Date(2021-01-02)
- classmethod parse_common_iso(s: str, /) YearMonth [source]ΒΆ
Create from the common ISO 8601 format
YYYY-MM
. Does not accept more βexoticβ ISO 8601 formats.Inverse of
format_common_iso()
Example
>>> YearMonth.parse_common_iso("2021-01") YearMonth(2021-01)
- class whenever.MonthDay(month: int, day: int)ΒΆ
A month and day without a year component.
Useful for representing recurring events or birthdays.
Example
>>> MonthDay(11, 23) MonthDay(--11-23)
- __eq__(other: object) bool [source]ΒΆ
Compare for equality
Example
>>> md = MonthDay(10, 1) >>> md == MonthDay(10, 1) True >>> md == MonthDay(10, 2) False
- format_common_iso() str [source]ΒΆ
Format as the common ISO 8601 month-day format.
Inverse of
parse_common_iso
.Example
>>> MonthDay(10, 8).format_common_iso() '--10-08'
Note
This format is officially only part of the 2000 edition of the ISO 8601 standard. There is no alternative for month-day in the newer editions. However, it is still widely used in other libraries.
- in_year(year: int, /) Date [source]ΒΆ
Create a date from this month-day with a given day
Example
>>> MonthDay(8, 1).in_year(2025) Date(2025-08-01)
Note
This method will raise a
ValueError
if the month-day is a leap day and the year is not a leap year.
- is_leap() bool [source]ΒΆ
Check if the month-day is February 29th
Example
>>> MonthDay(2, 29).is_leap() True >>> MonthDay(3, 1).is_leap() False
- classmethod parse_common_iso(s: str, /) MonthDay [source]ΒΆ
Create from the common ISO 8601 format
--MM-DD
. Does not accept more βexoticβ ISO 8601 formats.Inverse of
format_common_iso()
Example
>>> MonthDay.parse_common_iso("--11-23") MonthDay(--11-23)
- class whenever.Time(hour: int = 0, minute: int = 0, second: int = 0, *, nanosecond: int = 0)ΒΆ
Time of day without a date component
Example
>>> t = Time(12, 30, 0) Time(12:30:00)
- __eq__(other: object) bool [source]ΒΆ
Compare for equality
Example
>>> t = Time(12, 30, 0) >>> t == Time(12, 30, 0) True >>> t == Time(12, 30, 1) False
- format_common_iso() str [source]ΒΆ
Format as the common ISO 8601 time format.
Inverse of
parse_common_iso()
.Example
>>> Time(12, 30, 0).format_common_iso() '12:30:00'
- classmethod from_py_time(t: time, /) Time [source]ΒΆ
Create from a
time
Example
>>> Time.from_py_time(time(12, 30, 0)) Time(12:30:00)
fold value is ignored.
- on(d: Date, /) LocalDateTime [source]ΒΆ
Combine a time with a date to create a datetime
Example
>>> t = Time(12, 30) >>> t.on(Date(2021, 1, 2)) LocalDateTime(2021-01-02 12:30:00)
Then, use methods like
assume_utc()
orassume_tz()
to make the result aware.
- classmethod parse_common_iso(s: str, /) Time [source]ΒΆ
Create from the common ISO 8601 time format
HH:MM:SS
. Does not accept more βexoticβ ISO 8601 formats.Inverse of
format_common_iso()
Example
>>> Time.parse_common_iso("12:30:00") Time(12:30:00)
- replace(**kwargs: Any) Time [source]ΒΆ
Create a new instance with the given fields replaced
Example
>>> t = Time(12, 30, 0) >>> d.replace(minute=3, nanosecond=4_000) Time(12:03:00.000004)
- round(unit: Literal['hour', 'minute', 'second', 'millisecond', 'microsecond', 'nanosecond'] = 'second', increment: int = 1, mode: Literal['ceil', 'floor', 'half_ceil', 'half_floor', 'half_even'] = 'half_even') Time [source]ΒΆ
Round the time to the specified unit and increment. Various rounding modes are available.
Examples
>>> Time(12, 39, 59).round("minute", 15) Time(12:45:00) >>> Time(8, 9, 13).round("second", 5, mode="floor") Time(08:09:10)
MiscellaneousΒΆ
- enum whenever.Weekday(value)ΒΆ
The days of the week;
.value
corresponds with ISO numbering.Valid values are as follows:
- MONDAY = <Weekday.MONDAY: 1>ΒΆ
- TUESDAY = <Weekday.TUESDAY: 2>ΒΆ
- WEDNESDAY = <Weekday.WEDNESDAY: 3>ΒΆ
- THURSDAY = <Weekday.THURSDAY: 4>ΒΆ
- FRIDAY = <Weekday.FRIDAY: 5>ΒΆ
- SATURDAY = <Weekday.SATURDAY: 6>ΒΆ
- SUNDAY = <Weekday.SUNDAY: 7>ΒΆ
- exception whenever.RepeatedTimeΒΆ
Bases:
Exception
A datetime is repeated in a timezone, e.g. because of DST
- exception whenever.SkippedTimeΒΆ
Bases:
Exception
A datetime is skipped in a timezone, e.g. because of DST
- exception whenever.InvalidOffsetΒΆ
Bases:
ValueError
A string has an invalid offset for the given zone
- class whenever.patch_current_time(dt: Instant | ZonedDateTime | OffsetDateTime | SystemDateTime, /, *, keep_ticking: bool)[source]ΒΆ
Patch the current time to a fixed value (for testing purposes). Behaves as a context manager or decorator, with similar semantics to
unittest.mock.patch
.Important
This function should be used only for testing purposes. It is not thread-safe or part of the stable API.
This function only affects wheneverβs
now
functions. It does not affect the standard libraryβs time functions or any other libraries. Use thetime_machine
package if you also want to patch other libraries.It doesnβt affect the system timezone. If you need to patch the system timezone, set the
TZ
environment variable in combination withtime.tzset
. Be aware that this only works on Unix-like systems.
Example
>>> from whenever import Instant, patch_current_time >>> i = Instant.from_utc(1980, 3, 2, hour=2) >>> with patch_current_time(i, keep_ticking=False) as p: ... assert Instant.now() == i ... p.shift(hours=4) ... assert i.now() == i.add(hours=4) ... >>> assert Instant.now() != i ... >>> @patch_current_time(i, keep_ticking=True) ... def test_thing(p): ... assert (Instant.now() - i) < seconds(1) ... p.shift(hours=8) ... sleep(0.000001) ... assert hours(8) < (Instant.now() - i) < hours(8.1)