0.2.0
This is a new semver incompatible release of Jiff. It contains several breaking changes. I expect most users of Jiff to be able to upgrade without any changes. The fundamental API organization of Jiff has not changed.
In case you haven't heard of it before, Jiff is a relatively new datetime library for Rust. Jiff takes enormous inspiration from Temporal. Jiff supports automatic and seamless integration with the Time Zone Database, DST aware arithmetic and rounding, formatting and parsing zone aware datetimes losslessly, opt-in Serde support and a whole lot more. Jiff's overall goal is to guide you into the pit of success and make it harder to write buggy code for handling datetimes.
Some of the highlights of this release include reducing footguns and better ecosystem integration.
For reducing footguns, APIs on Span will no longer implicitly assume that days are always 24 hours long. And Span no longer implements PartialEq or Eq (instead favoring span.fieldwise() to create a value that supports naive fieldwise comparison). Moreover, when using TimeZone::system() (perhaps via Zoned::now()), if the system time zone could not be detected, then a special Etc/Unknown time zone will be used instead. This avoids erroring, but also surfaces itself to make it clearer that something has (perhaps) gone wrong.
As for ecosystem integration, this release coincides with the publication of the jiff-icu, jiff-sqlx and jiff-diesel crates. jiff-icu integrates with the ICU4X project, and is now the recommended way to use Jiff to work with non-Gregorian calendars or to localize datetimes for end users. jiff-sqlx and jiff-diesel provide wrapper types that implement the necessary traits to make it ergonomic to store and retrieve Jiff values in a database using SQLx or Diesel, respectively.
Unless something unexpected happens, my plan is for the next breaking change release to be Jiff 1.0 in about 6 months. Once Jiff 1.0 is out, I plan to commit to it indefinitely.
BREAKING CHANGES:
This is an exhaustive list of breaking changes. Changes with the bolded RUNTIME prefix are changes that will not be caught by the Rust compiler. That is, they are changes in runtime behavior.
- #28: The deprecated
intzroutines onZoned,Timestamp,civil::DateTimeandcivil::Datehave been removed. You can usein_tzinstead. This change was made because many found the nameintzto be unclear. - #32: The
PartialEqandEqtrait implementations onSpanhave been removed. Ideally these shouldn't have been used, but if you do need them, please useSpan::fieldwiseto create aSpanFieldwise, which does have thePartialEqandEqtraits implemented. These were removed onSpanitself because they made it very easy to commit subtle bugs. - #36: Turn panics during
Timestamp::saturing_addinto errors. Callers adding spans that are known to contain units of hours or smaller are guaranteed that this will not return an error. - RUNTIME #48: On
SpanAPIs, days are no longer silently assumed to always be 24 hours when a relative datetime is not provided. Instead, to perform operations on units of days or bigger, callers must either provide a relative date or opt into invariant 24-hour days withSpanRelativeTo::days_are_24_hours. Shortcuts have been added to the span builders. For example,SpanTotal::days_are_24_hours. - RUNTIME #147: Change the behavior of the deprecated
%Vconversion specifier injiff::fmt::strtimefrom formatting an IANA time zone identifier to formatting an ISO 8601 week number. To format an IANA time zone identifier, use%Qor%:Q(which were introduced injiff 0.1). - RUNTIME #212: When parsing into a
Zonedwith a civil time corresponding to a gap, we treat all offsets as invalid and return an error. Previously, we would accept the offset as given. This brings us into line with Temporal's behavior. For example, previously Jiff accepted2006-04-02T02:30-05[America/Indiana/Vevay]but will now return an error. This is desirable for cases where a datetime in the future is serialized before a change in the daylight saving time rules. For more examples, seejiff::fmt::temporal::DateTimeParser::offset_conflictfor details on how to change Jiff's default behavior. This behavior change also applies totz::OffsetConflict::PreferOffset. - RUNTIME #213: Tweak the semantics of
tz::TimeZoneDatabaseso that it only initializes one internal tzdb instead of trying to find as many as possible. It is unlikely that you'll be impacted by this change, but it's meant to make the semantics be a bit more sensible. (Injiff 0.1, it was in theory possible for one tz lookup to succeed in the system zoneinfo and then another tz lookup to fail in zoneinfo but succeed automatically via the bundled copy. But this seems confusing and possibly not desirable. Hence the change.) - #218: In order to make naming a little more consistent between
Zonedandcivil::Date, thecivil::Date::to_iso_week_dateandcivil::ISOWeekDate::to_dateAPIs were renamed tocivil::Date::iso_week_dateandcivil::ISOWeekDate::date. - #220: Remove
Span::to_durationfor converting aSpanto astd::time::Durationand renameSpan::to_jiff_durationtoSpan::to_duration. This prioritizesSignedDurationas the "primary" non-calendar duration type in Jiff. And makes it more consistent with APIs likeZoned::duration_since. For non-calendar spans, theTryFrom<Span> for std::time::Durationstill exists. For calendar durations, useSpan::to_durationand then convert theSignedDurationtostd::time::Duration. Additionally,Timestamp::from_jiff_durationandTimestamp::as_jiff_durationwere renamed toTimestamp::from_durationandTimestamp::as_duration, respectively. The old deprecated routines on the unsignedstd::time::Durationhave been removed. - #221: Change the type of the value yielded by the
jiff::tz::TimeZoneNameIteriterator fromStringtojiff::tz::TimeZoneName. This opaque type is more API evolution friendly. To access the string, either useTimeZoneName'sDisplaytrait implementation, or itsas_strmethod. - #222: Split
TimeZone::to_offsetinto two methods. One that just returns the offset, and another,TimeZone::to_offset_info, which includes the offset, DST status and time zone abbreviation. The extra info is rarely needed and is sometimes more costly to compute. Also, make the lifetime of the time zone abbreviation returned byTimeZoneTransition::abbreviationtied to the transition instead of the time zone (for future API flexibility, likely in core-only environments). This change was overall motivated by wanting to do less work in the common case (where we only need the offset), and for reducing the size of aTimeZoneconsiderably in core-only environments. Callers previously usingTimeZone::to_offsetto get DST status and time zone abbreviation should now useTimeZone::to_offset_info. - RUNTIME #230: When
TimeZone::system()cannot find a system configured time zone,jiff 0.1would automatically fall back toTimeZone::UTC(with a WARN-level log message). Injiff 0.2, the fall back is now toTimeZone::unknown(), which has a specialEtc/Unknownidentifier (as specified by Unicode and reserved by the IANA time zone database). The fallback otherwise still behaves as if it wereTimeZone::UTC. This helps surface error conditions related to finding the system time zone without causing unrecoverable failure.
Enhancements:
- #136: When the special
SpanRelativeTo::days_are_24_hours()marker is used, weeks will also be treated as invariant. That is, seven 24-hour days. In all cases, working with years and months still requires a relative date. - #228: It is now possible to forcefully use a bundled copy of the IANA time zone database without relying on disabling crate features. This can be done by enabling the
tzdb-bundle-alwayscrate feature and explicitly creating ajiff::tz::TimeZoneDatabase::bundled()database. Once in hand, you must use APIs likeTimeZoneDatabase::getto create aTimeZoneand avoid any APIs that implicitly use the global time zone database (likeTimestamp::in_tzor evenZoned::from_str). - #238: Add integration with the ICU4X project via the
jiff-icucrate.jiff-icuprovides traits for easily converting between datetime types defined in Jiff and datetime types defined in ICU4X. - #240: Add integration with the SQLx project via the
jiff-sqlxcrate.jiff-sqlxprovides wrapper types that implement the necessary traits in SQLx for reasonably ergonomic integration. This includes PostgreSQL and SQLite support, but not MySQL support. (It's not clear if it's possible at present to provide MySQL supprot fro SQLx for datetime types outside of SQLx itself.) - #241: Add integration with the Diesel project via the
jiff-dieselcrate.jiff-dieselprovides wrapper types that implement the necessary traits in Diesel for reasonably ergonomic integration. This includes MySQL, PostgreSQL and SQLite support.