Changelog¶
0.10.0b1 (2026-03-20)¶
A big release with several breaking changes and improvements. Highlights
are the new delta API, customizable string formatting and parsing,
and since()/until() methods for calculating differences between datetimes.
See the full list below.
Breaking changes
DateTimeDeltaandDateDeltahave been replaced byItemizedDeltaandItemizedDateDelta, respectively. The helper functions for creating calendar deltas (years(),months(),weeks(),days()) have also been deprecated.The new deltas are fully un-normalized, meaning “90 minutes” and “1 hour and 30 minutes” are distinct values. They implement the
Mappinginterface and support a rich set of operations includingadd(),subtract(),total(),in_units(),replace(), andsign().Rationale: the “partially” normalized approach was confusing to users. A fully un-normalized approach also better fits the new API for calculating deltas between datetimes. This approach is also more consistent with other libraries, and allows for more control over formatting and parsing of deltas.
Migration:
Replace
DateDelta(...)withItemizedDateDelta(...).Replace
DateTimeDelta(...)withItemizedDelta(...).Replace
years(),months(),weeks(),days()helper functions withItemizedDateDelta(years=...), etc. Or, if passing to a datetime method, use keyword arguments directly (e.g.dt.add(years=1, months=2)).Replace
.in_months_days()and.in_months_days_secs_nanos()with.in_units(['months', 'days'])and.in_units(['months', 'days', 'seconds', 'nanoseconds']), respectively.The
Date+/-operators withDateDeltaare deprecated; useadd()/subtract()instead.The
Date-operator between two dates is deprecated; usesince()orsubtract()instead.
The
ignore_dstparameter (which was used to enable DST-unsafe operations) has been replaced by a warnings mechanism that allows users to suppress or escalate DST-related warnings using context managers or Python’s standard warning filters.Rationale: The
ignore_dstparameter was a source of confusion, and made theOffsetDateTimeAPIs less compatible.Migration:
Remove
ignore_dst=Truefrom all calls.For
OffsetDateTimeoperations: usewith ignore_potentially_stale_offset_warning(): ...to suppress warnings.For
PlainDateTimeoperations: usewith ignore_timezone_unaware_arithmetic_warning(): ...to suppress warnings.Alternatively, use Python’s
warnings.filterwarnings()to suppressPotentiallyStaleOffsetWarningorTimeZoneUnawareArithmeticWarning.
Behavior of an edge case is changed: disambiguation of non-existent times as a result of calendar arithmetic (or
replace()) no longer tries to reuse the previous offset. This change also fixes a rare bug in case a timezone transition skips an entire day (like the Samoa timezone did in 2011) (#252).Rationale: Unlike the case of repeated times, reusing the previous offset for non-existent times doesn’t have the advantage of preventing unexpected jumps in time. The new behavior is consistent with other libraries.
Dropped Python 3.9 support
Rationale: Python 3.9 is EOL since October 2025. Python 3.9 only accounts for less than 0.1% of downloads.
Removed
format_common_iso()andparse_common_iso()methods. Useformat_iso()andparse_iso()instead. These have been deprecated since 0.9.0.The
round()methods are stricter about keyword-only and positional-only arguments.
Deprecated
TimeDelta.in_hours(),.in_minutes(),.in_seconds(),.in_milliseconds(),.in_microseconds(),.in_nanoseconds(),.in_days_of_24h(), and.in_hrs_mins_secs_nanos(). Usetotal()orin_units()instead.The
difference()method on datetimes is deprecated. Instead, use the-subtraction operator, or the newsince()method.Date.days_since()andDate.days_until(). Usesince()anduntil()withtotal='days'instead.py_date(),py_time(),py_datetime(), andpy_timedelta(). Use the newto_stdlib()method instead, which provides a consistent name across all types.from_py_date(),from_py_time(),from_py_datetime(), andfrom_py_timedelta(). Use the constructor directly instead (e.g.Date(datetime.date(...))).parse_strptime()methods onOffsetDateTimeandPlainDateTime. Use the newparse()method instead.
Improved
New
since()anduntil()methods onDate,ZonedDateTime,OffsetDateTime, andPlainDateTimefor calculating the difference between two values in terms of specific calendar/time units.New
format()andparse()methods onDate,Time,PlainDateTime,OffsetDateTime,ZonedDateTime, andInstantfor custom format/parse patterns. Example:Date(2024, 3, 15).format("YYYY/MM/DD")→"2024/03/15". These types also support__format__, enabling f-string usage:f"{date:YYYY/MM/DD}". See the pattern format documentation for details.New
TimeDelta.total()andTimeDelta.in_units()methods for converting a time delta into specific units.New
TimeDelta.add()andTimeDelta.subtract()methods. The operators+and-were supported already, but these methods make it easier for simple operations, as well as making the API more consistent with other classes.New
OffsetDateTime.assume_tz()method for associating an offset datetime with a timezone.round()methods now support four new rounding modes:trunc,expand,half_trunc, andhalf_expand. They also now support larger and irregular values forincrement.TimeDelta.round()now supports days and weeks as rounding units (with a warning about 24-hour days).All types that have a Python standard library equivalent now also accept these objects in the constructor. For example:
Date(datetime.date(2024, 1, 1)).New
ZonedDateTime.dst_offset()andZonedDateTime.tz_abbrev()methods for querying timezone metadata (DST offset adjustment and timezone abbreviation).Warning classes (
PotentiallyStaleOffsetWarning,TimeZoneUnawareArithmeticWarning,DaysNotAlways24HoursWarning) and corresponding context managers (ignore_potentially_stale_offset_warning(),ignore_timezone_unaware_arithmetic_warning(),ignore_days_not_always_24h_warning()) for fine-grained control over DST-related warnings.A huge revamp and expansion of the documentation. The structure and navigability of API reference and overview pages has been improved. Several new pages have been added, including:
An explanation of the fundamental concepts of time
An overview of Python’s datetime pitfalls
Explanation of the rounding API
Fixed
(Pure-Python version) Fixed incorrect behavior of
<operator betweenTimeinstances if nanoseconds are involved.
0.9.5 (2026-01-11)¶
Fix issue where not all windows wheels were built and uploaded (#317)
0.9.4 (2025-12-14)¶
Added support for free-threaded Python (#166)
0.9.3 (2025-10-16)¶
Fixed incorrect offsets for some timezones before the start of their first recorded transition (typically pre-1950) (#296)
0.9.2 (2025-09-29)¶
Methods that take an int, float, or str now also accept subclasses of these types.
This is consistent with the behavior of the standard library and
improves compatibility with libraries like numpy and pandas (#260)
0.9.1 (2025-09-28)¶
Added ZonedDateTime.now_in_system_tz() and
ZonedDateTime.from_system_tz() as convenience methods to ease
migration away from SystemDateTime.
0.9.0 (2025-09-25)¶
Breaking Changes
SystemDateTimehas been removed and merged intoZonedDateTimeTo create a more consistent and intuitive API, the
SystemDateTimeclass has been removed. Its functionality is now fully integrated into an enhancedZonedDateTime, which now serves as the single, canonical class for all timezone-aware datetimes, including those based on the system’s local timezone.Rationale:
The
SystemDateTimeclass, while useful, created several challenges that compromised the library’s consistency and predictability:Inconsistent Behavior: Methods like
replace()andadd()on aSystemDateTimeinstance would use the current system timezone definition, not necessarily the one that was active when the instance was created. This could lead to subtle and unpredictable bugs if the system timezone changed during the program’s execution.API Division: Despite having nearly identical interfaces,
SystemDateTimeandZonedDateTimewere not interchangeable. A function expecting aZonedDateTimecould not accept aSystemDateTime, forcing users to write more complex code withUniontype hints.Maintenance Overhead: Maintaining two parallel APIs for timezone-aware datetimes led to significant code duplication and a higher maintenance burden.
This change unifies the API by integrating system timezone support directly into
ZonedDateTime, providing a single, consistent way to handle all timezone-aware datetimes. The original use cases forSystemDateTimeare fully supported by the improvedZonedDateTime.This new, unified approach also provides two major benefits:
Performance: Operations on a
ZonedDateTimerepresenting a system time are now orders of magnitude faster than they were on the oldSystemDateTime.Cross-Platform Consistency: The new
whenever.reset_system_tz()function provides a reliable, cross-platform way to update the library’s view of the system timezone, replacing the previous reliance on the Unix-onlytime.tzset().
Migration:
Replace all
SystemDateTimewithZonedDateTimein all type hints.Replace
SystemDateTime.now()withZonedDateTime.now_in_system_tz()(whenever >=0.9.1) orInstant.now().to_system_tz()(whenever <0.9.1)Replace
SystemDateTime(...)constructor calls withZonedDateTime.from_system_tz(...)(whenever >=0.9.1) orPlainDateTime(...).assume_system_tz()(whenever <0.9.1)Check calls to
.to_system_tz()and.assume_system_tz(): these methods now return aZonedDateTimeinstance. In most cases, no code change is needed.Instead of
time.tzset(), usewhenever.reset_system_tz()to update the system timezone (forwheneveronly).
ZonedDateTimeinstances with a system timezone may in rare cases not have a known IANA timezone ID (thetzproperty will beNone). This is an unfortunate limitation of some platforms. SuchZonedDateTimeinstances can still be used for all operations, and will account for DST correctly. However, these instances cannot be pickled, and their ISO format will not be able to include the timezone ID.Rationale: This is an necessary compromise for broad system timezone support. Other libraries (and Python’s own
zoneinfo) have similar limitations.The
repr()of all classes now includes quotes: e.g.Date("2023-10-05"). Since all constructors now also accept ISO 8601 strings, therepr()output can be directly used as input and thuseval(repr(obj)) == obj.Rationale: This makes the types easier to use in interactive sessions and tests. A round-trippable
repr()is also a common expectation for primitive types.Renamed
[format|parse]_common_isomethods to[format|parse]_iso. The old methods are still available (but deprecated) to ease the transition.Rationale: The “common” qualifier is no longer necessary because these methods have been expanded to handle a wider range of ISO 8601 formats.
Removed the deprecated
local()methods (useto_plain()instead).Removed the deprecated
instant()method (useto_instant()instead).
Improved
All classes can now be directly instantiated from an ISO 8601 formatted string passed as a sole argument. For example,
Date("2023-10-05")is equivalent toDate(2023, 10, 5)(which is still supported, of course).Customizable ISO 8601 Formatting: The
format_iso()methods now accept parameters to customize the output. You can control the separator (e.g.,'T'or' '), the smallest unit (fromhourtonanosecond), and toggle the “basic” (compact) or “extended” format.Also, the formatting is now significantly faster. Up to 5x faster for
ZonedDateTime, which is now 10x faster than the standard library’sdatetime.isoformat().
Fixed
Resolved a memory leak in the Rust extension where timezone objects that were no longer in use were not properly evicted from the cache.
Fixed a rare bug in determining the UTC offset for times far in the future
Fixed
PlainDateTimeconstructor raisingTypeErrorinstead ofValueErrorwhen passed invalid parameters.TZ IDs starting with a
./are now properly rejected. Other path traversal attempts were already handled correctly.More robust timezone refcounting in the Rust extension, preventing crashes in rare cases (#270)
Panics in Rust extension no longer crash the interpreter, raise
RuntimeErrorinstead
0.8.9 (2025-09-21)¶
Fixed not all test files included in source distribution (#266)
Uploaded missing Python 3.14 wheels
0.8.8 (2025-07-24)¶
Add wheels for Python 3.14 now that its ABI is stable.
Add a pure Python wheel so platforms without binary wheels can use
whenever’s pure Python version without having to go through the source build process (#256)
0.8.7 (2025-07-18)¶
Fix some
MINandMAXconstants not documented in the API reference.Add
Time.MINalias forTime.MIDNIGHTfor consistency (#245)Fix bug in rounding of midnight
ZonedDateTimevalues in “ceil”/day mode (#249)
0.8.6 (2025-06-23)¶
Improve error message of
ZonedDateTime.from_py_datetime()in case the datetime’sZoneInfo.keyisNone.Fix performance regression in
Date.day_of_week()(#244)
0.8.5 (2025-06-09)¶
Relax build requirements. It now only depends on
setuptools_rustif opting to build the Rust extension (#240)Fixed not all Rust files included in source distribution.
Update some outdated docstrings.
0.8.4 (2025-05-28)¶
Fix Pydantic JSON schema generation in certain contexts, which affected FastAPI doc generation.
0.8.3 (2025-05-22)¶
Ensure Pydantic parsing failures of
whenevertypes always result in a properValidationError, not aTypeError.
0.8.2 (2025-05-21)¶
Allow Pydantic to generate JSON schema for
whenevertypes. This is particularly useful for generating OpenAPI schemas for FastAPI.
0.8.1 (2025-05-21)¶
New
Added support for Pydantic serialization/deserialization of
whenevertypes in the ISO 8601 format. This functionality is in preview, and may be subject to change in the future. (#175)
Fixed
Weekdayenum values from the Rust extension are now pickleable.Solve crash if Python’s garbage collection occurs while the Rust extension is still initializing.
Fixed a crash in parsing malformed fractional
TimeDeltaseconds (#234)
Improved
Time.from_py()now ignores anytzinfo, instead of raising an error.A comprehensive refactor of the Rust extension module eliminates most unnecessary
unsafecode, making it safer and more idiomatic.
0.8.0 (2025-05-01)¶
A big release with several improvements and breaking changes that lay the groundwork for the eventual 1.0 release.
Improved
Timezone operations in the Rust extension are now a lot faster (5-8x), due to a new implementation replacing the use of the standard library
zoneinfomodule. (#202)The
parse_common_iso()methods support a wider range of ISO 8601 formats. See the updated documentation for details. (#204)Added an “examples” page to the documentation with practical snippets. (#198)
RFC2822 parsing is now more robust and faster. (#200)
Import speed is improved significantly for both the Rust and pure Python versions (#228)
Breaking changes
LocalDateTimehas been renamed toPlainDateTime, and thelocal()method has been renamed toto_plain(). The old names are still available (but deprecated) to ease the transition.Rationale: In observing adoption of the library, the term “local” causes confusion for a number of users, since the term “local” is so overloaded in the Python world.
PlainDateTimeis used in Javascript’s Temporal API, and seems to resonate better with users. See the FAQ for a detailed discussion on the name.Rename
instant()method toto_instant()Rationale: The new name is more consistent with the rest of the API.
Removed the
[format|parse]_rfc3339method.Rationale: The improved ISO 8601 parsing method is now RFC 3339 compatible, making this method unnecessary. Strict RFC 3339 parsing can still be done with
strptime, if desiredPassing invalid timezone names now raise a
whenever.TimeZoneNotFoundError(subclass ofValueError) instead ofzoneinfo.ZoneInfoNotFoundError(subclass ofKeyError).Rationale: This ensures whenever is independent of the
zoneinfomodule, and its particularities don’t leak into thewheneverAPI.TimeDelta.from_py_timedeltano longer acceptstimedeltasubclasses.Rationale: timedelta subclasses (like pendulum.Duration) often add other time components, which cannot be guaranteed to be handled correctly.
The
strptimemethods have been renamedparse_strptime, and itsformatargument is now a keyword-only argument.Rationale: This ensures all parsing methods have the
parse_prefix, helping in API consistency and discoverability. The keyword-only argument helps distinguish between the format string and the string to parse.The
InvalidOffsetexception has been renamedInvalidOffsetErrorRationale: this more clearly indicates that this is an error condition. See #154 for discussion.
SkippedTimeandRepeatedTimeare now subclasses ofValueError.Rationale: it ensures these exceptions can be caught together with other exceptions like
InvalidOffsetErrorandTimeZoneNotFoundErrorduring parsing.Whenever is no longer affected by
ZoneInfo.clear_cache()orzoneinfo.reset_tzpath(), since it now uses its own cache with corresponding methods.Rationale: This ensures whenever is independent of
zoneinfoin both Rust and pure Python implementations.
Fixed
Improved robustness of date calculations at extreme boundaries. (#219)
Fixed a bug in the pure-Python version of
ZonedDateTime.exact_eq()that could cause false positives in some cases.Fixed incorrect type stubs for
day_length()andstart_of_day()methods.Corrected the description of parameters accepted by
now(). (#213)
0.7.3 (2025-03-19)¶
Fixed type annotations of
Weekdayenum values, so they are properly marked asint.
0.7.2 (2025-02-25)¶
Fixed
round()method behaving incorrectly whenincrementargument is not passed explicitly (#209)
0.7.1 (2025-02-24)¶
Date.addandDate.subtractnow supportDateDeltato be passed as sole positional argument. This is consistent with the behavior of datetime classes.Improved performance and robustness of date calculations at extreme boundaries
Minor fixes to docstrings
0.7.0 (2025-02-20)¶
This release adds rounding functionality, along with a small breaking change (see below).
Breaking changes
TimeDelta.py_timedelta()now truncates nanoseconds to microseconds instead of rounding them. Use the newround()method to customize rounding behavior.
Added
Added
round()to all datetime,Instant, andTimeDeltaclassesAdd floor division and modulo operators to
TimeDeltaAdd
is_ambiguous(),day_length()andstart_of_day()toSystemDateTime, for consistency withZonedDateTime.Improvements to documentation
0.6.17 (2025-01-30)¶
Added
day_length()andstart_of_day()methods toZonedDateTimeto make it easier to work with edge cases around DST transitions, and prepare for implementing rounding methods in the future.Fix cases in type stubs where positional-only arguments weren’t marked as such
0.6.16 (2024-12-22)¶
Fix bug in
ZonedDateTimerepr()that would mangle some timezone namesMake
disambiguateargument optional, defaulting to"compatible".Rationale: This required parameter was a frequent source of irritation for users. Although “explicit is better than implicit”, other modern libraries and standards also choose an (implicit) default. For those that do want to enforce explicit handling of ambiguous times, a special stubs file or other plugin may be introduced in the future.
Various small fixes to the docs
0.6.15 (2024-12-11)¶
Add
Date.days_[since|until]methods for calculating the difference between two dates in days only (no months or years)Improve docs about arithmetic rules for calendar and time units.
0.6.14 (2024-11-27)¶
Ensure docstrings and error messages are consistent in Rust extension as well as the pure-Python version
Remove undocumented properties
hour/minute/etcfromInstantthat were accidentally left in the Rust extension.exact_eq()now also raisesTypeErrorin the pure Python version when comparing different types.
0.6.13 (2024-11-17)¶
Added
Make
from_py_datetime()onInstant/OffsetDateTimeless pedantic. They now accept any aware datetimeNew
Date.today_in_system_tz()convenience method
Fixed
Parsing UTC offsets with out-of-range minute components (e.g.
06:79) now raises the expected parsing failure.Note in
parse_rfc2822()docstring that it doesn’t (yet) validate the input, due to limitations in the underlying parser.
0.6.12 (2024-11-08)¶
Fixed
format_rfc3339()docstrings that incorrectly included aTseparator. Clarified thatTcan be added by using theformat_common_iso()method instead. (#185)
0.6.11 (2024-11-04)¶
Added
Added
YearMonthandMonthDayclasses for working with year-month and month-day pairs
Fixed
whenever.__version__is now also accessible when Rust extension is used
0.6.10 (2024-10-30)¶
Improved
Improve method documentation and autocomplete support (#172, #173, #176)
Fixed
Remove lingering undocumented
offsetonInstantFix incorrect
LocalDateTime.differencereturn type annotation
0.6.9 (2024-09-12)¶
Clarify DST-related error messages (#169)
0.6.8 (2024-09-05)¶
Fix object deallocation bug that caused a crash in rare cases (#167)
0.6.7 (2024-08-06)¶
Add Python 3.13 binary wheels, now that its ABI is stable
Small improvements to import speed
0.6.6 (2024-07-27)¶
Fix potential memory leak in
.now()iftime-machineis used
0.6.5 (2024-07-27)¶
from_timestampnow also accepts floats, to ease porting code fromdatetime(#159)Fixed incorrect fractional seconds when parsing negative values in
from_timestampmethods.Fix some places where
ValueErrorwas raised instead ofTypeError
0.6.4 (2024-07-26)¶
Add helper
patch_current_timefor patching current time in whenever (only) (#147)Support patching the current time with time-machine (#147)
Remove undocumented
year/month/day/offsetproperties fromInstantReduce size of binary distributions
Clarify contribution guidelines
0.6.3 (2024-07-13)¶
Improve robustness and speed of keyword argument parsing in Rust extension (#149)
Add more answers to common questions in the docs and FAQ (#148, #150)
0.6.2 (2024-07-04)¶
Add third-party licenses to distributions
0.6.1 (2024-07-04)¶
Small updates to project metadata
0.6.0 (2024-07-04)¶
A big release touting a Rust extension module and an API more consistent with other modern libraries.
Added or improved
Implement as a Rust extension module, leading to a big speedup
Add
replace_dateandreplace_timemethods to datetimes.Add
Date.MINandDate.MAXconstants.from_py_*methods are more robust.The pickle format for most types is now more efficient.
Breaking changes
UTCDateTimeis nowInstant. Removed methods that were specific to UTC.Rationale:
Instantis simpler and more conceptually clear. It also avoids the mistake of performing calendar arithmetic in UTC.NaiveDateTimeis nowLocalDateTimeRationale: “Local” is more descriptive for describing the concept of “wall clock” time observed locally by humans. It’s also consistent with other libraries and standards.
Nanosecond precision is now the default for all datetimes and deltas.
nanosecondis a keyword-only argument for all constructors, to prevent mistakes porting code fromdatetime(which uses microseconds).Rationale: Nanosecond precision is the standard for modern datetime libraries.
Unified
[from_]canonical_formatmethods with[from_]common_iso8601methods into[format|parse]_common_isomethods.Rationale: This cuts down on the number of methods; the performance benefits of separate methods aren’t worth the clutter.
Timestamp methods now use integers instead of floats. There are now separate methods for seconds, milliseconds, and nanoseconds.
Rationale: This prevents loss of precision when converting to floats, and is more in line with other modern libraries.
Renamed
[from_][rfc3339|rfc2822]methods to[format|parse]_[rfc3339|rfc2822].Rationale: Consistency with other methods.
Added explicit
ignore_dst=Trueflag to DST-unsafe operations such as shifting an offset datetime.Rationale: Previously, DST-unsafe operations were completely disallowed, but to a frustrating degree. This flag is a better alternative than having users resort to workarounds.
Renamed
as_utc,as_offset,as_zoned,as_localtoto_utc,to_fixed_offset,to_tz,to_system_tz, and theNaiveDateTime.assume_*methods accordinglyRationale: “to” better clarifies a conversion is being made (not a replacement), and “fixed offset” and “tz” are more descriptive than “offset” and “zoned”.
disambiguate=is non-optional for all relevant methods. The only exception is the constructor, which defaults to “raise”.Rationale: This makes it explicit how ambiguous and non-existent times are handled.
Removed weakref support.
Rationale: The overhead of weakrefs was too high for such primitive objects, and the use case was not clear.
Weekdays are now an enum instead of an integer.
Rationale: Enums are more descriptive and less error-prone, especially since ISO weekdays start at 1 and Python weekdays at 0.
Calendar units in
Date[Time]Deltacan now only be retrieved together. For example, there is nodelta.monthsordelta.daysanymore,delta.in_months_days()should be used in this case.Rationale: This safeguards against mistakes like
(date1 - date2).dayswhich would only return the days component of the delta, excluding months. Having to callin_months_days()is more explicit that both parts are needed.Units in delta cannot be different signs anymore (after normalization).
Rationale: The use case for mixed sign deltas (e.g. 2 months and -15 days) is unclear, and having a consistent sign makes it easier to reason about. It also aligns with the most well-known version of the ISO format.
Calendar units are normalized, but only in so far as they can be converted strictly. For example, 1 year is always equal to 12 months, but 1 month isn’t equal to a fixed number of days. Refer to the delta docs for more information.
Rationale: This is more in line with
TimeDeltawhich also normalizes.Renamed
AmbiguousTimetoRepeatedTime.Rationale: The new name is more descriptive for repeated times occurring twice due to DST. It also clarifies the difference between “repeated” times and “ambiguous” times (which can also refer to non-existent times).
Dropped Python 3.8 support
Rationale: Rust extension relies on C API features added in Python 3.9. Python 3.8 will be EOL later this year.
0.5.1 (2024-04-02)¶
Fix
LocalSystemDateTime.now()not setting the correct offset (#104)
0.5.0 (2024-03-21)¶
Breaking changes
Fix handling of
-0000offset in RFC2822 format, which was not according to the standard.NaiveDateTimecan now no longer be created from this format.DateDeltacanonical format now usesPprefix.
Improved
Add explicit ISO8601 formatting/parsing methods to datetimes, date, time, and deltas.
Add missing
Date.from_canonical_formatmethod.Separate docs for deltas and datetimes.
NaiveDateTime.assume_offsetnow also accepts integers as hour offsets.
0.4.0 (2024-03-13)¶
A big release with the main feature being the addition of date/time deltas. I’ve also tried to bundle as many small breaking changes as possible into this release, to avoid having to do them in the future.
Breaking changes
LocalDateTimerenamed toLocalSystemDateTime.Rationale: The
LocalDateTimename is used in other libraries for naive datetimes, and the new name is more explicit.LocalSystemDateTimeno longer adjusts automatically to changes in the system timezone. Now,LocalSystemDateTimereflects the system timezone at the moment of instantiation. It can be updated explicitly.Rationale: The old behavior was dependent on too many assumptions, and behaved unintuitively in some cases. It also made the class dependent on shared mutable state, which made it hard to reason about.
The
disambiguate=argument now also determines how non-existent times are handled.Rationale: This makes it possible to handle both ambiguous and non-existent times gracefully and in a consistent way. This behavior is also more in line with the RFC5545 standard, and Temporal.
from_naive()removed in favor of methods onNaiveDateTime. For example,UTCDateTime.from_naive(n)becomesn.assume_utc().Rationale: It’s shorter, and more explicit about assumptions.
Renamed
ZonedDateTime.disambiguated()to.is_ambiguous().Rationale: The new name distinguishes it from the
disambiguate=argument, which also affects non-existent times.Replaced
.pyproperty with.py_datetime()method.Rationale: Although it currently works fine as a property, this may be changed in the future if the library no longer contains a
datetimeinternally.Removed properties that simply delegated to the underlying
datetimeobject:tzinfo,weekday, andfold.dateandtimenow returnwhenever.Dateandwhenever.Timeobjects.Rationale: Removing these properties makes it possible to create improved versions. If needed, these properties can be accessed from the underlying datetime object with
.py_datetime().Renamed
.canonical_str()to.canonical_format().Rationale: A more descriptive name.
Renamed
DoesntExistInZonetoSkippedTime,AmbiguoustoAmbiguousTime.Rationale: The new names are shorter and more consistent.
Renamed
minandmaxtoMINandMAX.Rationale: Consistency with other uppercase class constants
Improved
Added a
disambiguation="compatible"option that matches the behavior of other languages and the RFC5545 standard.Shortened the
repr()of all types, use space separator instead ofT.Added
sep="T" or " "option tocanonical_format()OffsetDateTimeconstructor and methods creating offset datetimes now accept integers as hour offsets.Added
DateandTimeclasses for working with dates and times separately.
0.3.4 (2024-02-07)¶
Improved exception messages for ambiguous or non-existent times (#26)
0.3.3 (2024-02-04)¶
Add CPython-maintained
tzdatapackage as Windows dependency (#32)
0.3.2 (2024-02-03)¶
Relax overly strict Python version constraint in package metadata (#33)
0.3.1 (2024-02-01)¶
Fix packaging metadata issue involving README and CHANGELOG being installed in the wrong place (#23)
0.3.0 (2024-01-23)¶
Breaking changes
Change pickle format so that backwards-compatible unpickling is possible in the future.
Added
Added
strptime()toUTCDateTime,OffsetDateTimeandNaiveDateTime.Added
rfc2822()/from_rfc2822()toUTCDateTime,OffsetDateTimeandNaiveDateTime.Added
rfc3339()/from_rfc3339()toUTCDateTimeandOffsetDateTime
0.2.1 (2024-01-20)¶
added
days()timedelta aliasImprovements to README, other docs
0.2.0 (2024-01-10)¶
Breaking changes
Disambiguation of local datetimes is now consistent with zoned datetimes, and is also run on
replace().Renamed:
from_str→from_canonical_strto_utc/offset/zoned/local→as_utc/offset/zoned/local.ZonedDateTime.zone→ZonedDateTime.tz
Added
Support comparison between all aware datetimes
support subtraction between all aware datetimes
Convenience methods for converting between aware/naive
More robust handling of zoned/local edge cases
Docs
Cleaned up API reference
Added high-level overview
0.1.0 (2023-12-20)¶
Implement
OffsetDateTime,ZonedDateTimeandLocalDateTime
0.0.4 (2023-11-30)¶
Revert to pure Python implementation, as Rust extension disadvantages outweigh its advantages
Implement
NaiveDateTime
0.0.3 (2023-11-16)¶
Implement basic
UTCDateTime
0.0.2 (2023-11-10)¶
Empty release with Rust extension module
0.0.1¶
Dummy release