------------------
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_date`` and ``replace_time`` methods to datetimes.
- Add ``Date.MIN`` and ``Date.MAX`` constants.
- ``from_py_*`` methods are more robust.
- The pickle format for most types is now more efficient.
**Breaking changes**
- ``UTCDateTime`` is now ``Instant``. Removed methods that were specific to UTC.
**Rationale**: ``Instant`` is simpler and more conceptually clear.
It also avoids the mistake of performing calendar arithmetic in UTC.
- ``NaiveDateTime`` is now ``LocalDateTime``
**Rationale**: "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.
``nanosecond`` is a keyword-only argument for all constructors,
to prevent mistakes porting code from ``datetime`` (which uses microseconds).
**Rationale**: Nanosecond precision is the standard for modern datetime libraries.
- Unified ``[from_]canonical_format`` methods with ``[from_]common_iso8601`` methods
into ``[format|parse]_common_iso`` methods.
**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=True`` flag 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_local`` to
``to_utc``, ``to_fixed_offset``, ``to_tz``, ``to_system_tz``,
and the ``NaiveDateTime.assume_*`` methods accordingly
**Rationale**: "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]Delta`` can now only be retrieved together.
For example, there is no ``delta.months`` or ``delta.days`` anymore,
``delta.in_months_days()`` should be used in this case.
**Rationale**: This safeguards against mistakes like ``(date1 - date2).days``
which would only return the *days component* of the delta, excluding months.
Having to call ``in_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 ``TimeDelta`` which also normalizes.
- Renamed ``AmbiguousTime`` to ``RepeatedTime``.
**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.