Converting between types¶
Between exact types¶
You can convert between exact types with the to_instant(),
to_fixed_offset(), to_tz(),
and to_system_tz() methods. These methods return a new
instance of the appropriate type, representing the same moment in time.
This means the results will always compare equal to the original datetime.
>>> d = ZonedDateTime(2023, 12, 28, 11, 30, tz="Europe/Amsterdam")
>>> d.to_instant() # The underlying moment in time
Instant("2023-12-28 10:30:00Z")
>>> d.to_fixed_offset(5) # same moment with a +5:00 offset
OffsetDateTime("2023-12-28 15:30:00+05:00")
>>> d.to_tz("America/New_York") # same moment in New York
ZonedDateTime("2023-12-28 05:30:00-05:00[America/New_York]")
>>> d.to_system_tz() # same moment in the system timezone (e.g. Europe/Paris)
ZonedDateTime("2023-12-28 11:30:00+01:00[Europe/Paris]")
>>> d.to_fixed_offset(4) == d
True # always the same moment in time
To and from local time¶
Conversion to a “plain” datetime is easy: calling
to_plain() simply
retrieves the date and time part of the datetime, and discards the any timezone
or offset information.
>>> d = ZonedDateTime(2023, 12, 28, 11, 30, tz="Europe/Amsterdam")
>>> n = d.to_plain()
PlainDateTime("2023-12-28 11:30:00")
You can convert from plain datetimes with the assume_utc(),
assume_fixed_offset(),
assume_tz(), and
assume_system_tz() methods.
>>> n = PlainDateTime(2023, 12, 28, 11, 30)
>>> n.assume_utc()
Instant("2023-12-28 11:30:00Z")
>>> n.assume_tz("Europe/Amsterdam")
ZonedDateTime("2023-12-28 11:30:00+01:00[Europe/Amsterdam]")
Similarly, you can associate an OffsetDateTime
with a timezone using assume_tz():
>>> o = OffsetDateTime(2023, 12, 28, 11, 30, offset=1)
>>> o.assume_tz("Europe/Amsterdam")
ZonedDateTime("2023-12-28 11:30:00+01:00[Europe/Amsterdam]")
By default, this raises an error if the offset doesn’t match the timezone.
You can control what happens in case of a mismatch with the offset_mismatch argument:
>>> o = OffsetDateTime(2023, 12, 28, 11, 30, offset=5)
>>> o.assume_tz("Europe/Amsterdam", offset_mismatch="keep_instant")
ZonedDateTime("2023-12-28 07:30:00+01:00[Europe/Amsterdam]")
>>> o.assume_tz("Europe/Amsterdam", offset_mismatch="keep_local")
ZonedDateTime("2023-12-28 11:30:00+01:00[Europe/Amsterdam]")
Tip
The naming difference between to_* and assume_* methods is intentional.
See the FAQ for the rationale.
```{admonition} When is assume_tz useful?
:class: hint
A common scenario is receiving timestamps from an external source
(API, database, log file) that only carries a fixed offset.
If the timezone rules for that region change later—for example,
a country abolishes DST—the stored offset may no longer be valid
for arithmetic on future dates.
assume_tz() lets you associate the
correct timezone so that subsequent operations account for the
current rules.