Jiff is a datetime library for Rust. It encourages you to jump into the "pit of success." It is intended to cover all use cases (and more) than what is covered today by the time and chrono crates. It comes with out of the box time zone support, DST-aware duration rounding, DST-safe arithmetic and tons of support for various specs (ISO 8601, RFC 9557, RFC 3339, RFC 2822, RFC 9110, RFC 9636, some RFC 5545 and probably more that I'm forgetting).
I plan to release Jiff 1.0 this summer. After that, the bar for breaking changes is going to be nearly impossibly high. I would love feedback before that point. In particular, I would like to do what I can to discover whether I should be making any other breaking changes before the 1.0 release.
I notice that Span is Copy and has methods to mutate it. I haven't got any example of this, but I wonder if people will accidentally copy the Span and mutate the copy, only to be surprised that the original is not mutated?
Much like why iterators are typically not Copy, perhaps Span should not be either? Curious if this comes up in any experience reports.
I used jiff when it was 0.1.x and remember looking up methods for creating a DateTime when you have a Date and Time was not very intuitive. The methods existed, it was just not straightforward to find them. If I remember correctly, you had to go from Date to DateTime with a midnight time and then a builder on DateTime would let you use the Time to get the DateTime you wanted. Don't know if that has improved since. Ideally I'd expect there to be a direct DateTime::with(Date, Time) or builder constructor that didn't require you to have a DateTime to start from.
Sorry, I'm having trouble understanding you. Could you show a code example?
There are lots of ways to move between and around DateTime, Date and Time. So if there's a path missing, I'd probably be open to adding it. But the method you were looking for does exist: DateTime::from_parts. (And that has existed since jiff 0.1.0.)
What can I add to the docs that would have made your experience better?
I haven't worked with jiff directly, but I have used both regex and regex-automata. Generally they are well documented, but one thing I found is that if you don't know the specific name for something it can be hard to find as Rust doc doesn't have full text search.
For example, you have to guess that the search word for "replace" in regex-automata is "interpolate", which is not at all obvious. I ran into similar issues in itertools, the word I was searching for was not the term they used.
I believe there is an attribute to add Rust doc aliases. It would probably help a lot to use this to make things discoverable via likely synonyms. It is especially useful to those of us who are not native English speakers and might not think of the same word the author used as our first choice. I'm not saying that is the specific issue here, but it is an issue in general.
(Adding full text search to rustdoc would be awesome but is obviously out of scope for jiff.)
Another point is to have good tutorial and "book style" docs, not just reference docs. Here it looks like jiff is doing well, though without testing it, it is hard to tell (and I don't have any projects where I need date and time handling currently, my current projects are embedded microcontroller stuff).
I took this as an opportunity to start switching over some of our crates to jiff, and it has been a pretty great experience so far.
My only (very) minor gripe is that it wasn't obvious how to create a std::time::Duration from a SignedDuration. unsigned_abs() doesn't jump out at me as the most obvious method name. My first instinct was to look through the traits to see if there was some std implementation to perform the conversion, but I couldn't find one.
Gotta hand it to you for writing 10/10 documentation. It's on par with the quality of Rocket's documentation. At first I was a little frustrated by having three different duration representations (Span, SignedDuration and std::time::Duration), but the documentation makes the case for each very clear.
(To be fair with regards to unsigned_abs(), I hadn't read this part of the documentation when I was searching for a way to get to a std::time::Duration).
For converting from a SignedDuration to a std::time::Duration, it depends on how you want to treat the failure case. You have SignedDuration::unsigned_abs, as you discovered, for when you want an infallible conversion that ignores the sign. But you also have a impl TryFrom<SignedDuration> for std::time::Duration that gives you a fallible conversion that fails when the duration is negative. This actually mirrors how std sets it up, for example, there is i64::unsigned_abs and a impl TryFrom<i64> for u64. So if you're familiar with how std does numeric conversions, then that experience should just directly translate.