rustmax::jiff

Struct Span

Source
pub struct Span { /* private fields */ }
Expand description

A span of time represented via a mixture of calendar and clock units.

A span represents a duration of time in units of years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds and nanoseconds. Spans are used to as inputs to routines like Zoned::checked_add and Date::saturating_sub, and are also outputs from routines like Timestamp::since and DateTime::until.

§Range of spans

Except for nanoseconds, each unit can represent the full span of time expressible via any combination of datetime supported by Jiff. For example:

use jiff::{civil::{DateTime, DateTimeDifference}, ToSpan, Unit};

let options = DateTimeDifference::new(DateTime::MAX).largest(Unit::Year);
assert_eq!(DateTime::MIN.until(options)?.get_years(), 19_998);

let options = options.largest(Unit::Day);
assert_eq!(DateTime::MIN.until(options)?.get_days(), 7_304_483);

let options = options.largest(Unit::Microsecond);
assert_eq!(
    DateTime::MIN.until(options)?.get_microseconds(),
    631_107_417_599_999_999i64,
);

let options = options.largest(Unit::Nanosecond);
// Span is too big, overflow!
assert!(DateTime::MIN.until(options).is_err());

§Building spans

A default or empty span corresponds to a duration of zero time:

use jiff::Span;

assert!(Span::new().is_zero());
assert!(Span::default().is_zero());

Spans are Copy types that have mutator methods on them for creating new spans:

use jiff::Span;

let span = Span::new().days(5).hours(8).minutes(1);
assert_eq!(span.to_string(), "P5DT8H1M");

But Jiff provides a ToSpan trait that defines extension methods on primitive signed integers to make span creation terser:

use jiff::ToSpan;

let span = 5.days().hours(8).minutes(1);
assert_eq!(span.to_string(), "P5DT8H1M");
// singular units on integers can be used too:
let span = 1.day().hours(8).minutes(1);
assert_eq!(span.to_string(), "P1DT8H1M");

§Negative spans

A span may be negative. All of these are equivalent:

use jiff::{Span, ToSpan};

let span = -Span::new().days(5);
assert_eq!(span.to_string(), "-P5D");

let span = Span::new().days(5).negate();
assert_eq!(span.to_string(), "-P5D");

let span = Span::new().days(-5);
assert_eq!(span.to_string(), "-P5D");

let span = -Span::new().days(-5).negate();
assert_eq!(span.to_string(), "-P5D");

let span = -5.days();
assert_eq!(span.to_string(), "-P5D");

let span = (-5).days();
assert_eq!(span.to_string(), "-P5D");

let span = -(5.days());
assert_eq!(span.to_string(), "-P5D");

The sign of a span applies to the entire span. When a span is negative, then all of its units are negative:

use jiff::ToSpan;

let span = -5.days().hours(10).minutes(1);
assert_eq!(span.get_days(), -5);
assert_eq!(span.get_hours(), -10);
assert_eq!(span.get_minutes(), -1);

And if any of a span’s units are negative, then the entire span is regarded as negative:

use jiff::ToSpan;

// It's the same thing.
let span = (-5).days().hours(-10).minutes(-1);
assert_eq!(span.get_days(), -5);
assert_eq!(span.get_hours(), -10);
assert_eq!(span.get_minutes(), -1);

// Still the same. All negative.
let span = 5.days().hours(-10).minutes(1);
assert_eq!(span.get_days(), -5);
assert_eq!(span.get_hours(), -10);
assert_eq!(span.get_minutes(), -1);

// But this is not! The negation in front applies
// to the entire span, which was already negative
// by virtue of at least one of its units being
// negative. So the negation operator in front turns
// the span positive.
let span = -5.days().hours(-10).minutes(-1);
assert_eq!(span.get_days(), 5);
assert_eq!(span.get_hours(), 10);
assert_eq!(span.get_minutes(), 1);

You can also ask for the absolute value of a span:

use jiff::Span;

let span = Span::new().days(5).hours(10).minutes(1).negate().abs();
assert_eq!(span.get_days(), 5);
assert_eq!(span.get_hours(), 10);
assert_eq!(span.get_minutes(), 1);

§Parsing and printing

The Span type provides convenient trait implementations of std::str::FromStr and std::fmt::Display:

use jiff::{Span, ToSpan};

let span: Span = "P2m10dT2h30m".parse()?;
// By default, capital unit designator labels are used.
// This can be changed with `jiff::fmt::temporal::SpanPrinter::lowercase`.
assert_eq!(span.to_string(), "P2M10DT2H30M");

// Or use the "friendly" format by invoking the `Display` alternate:
assert_eq!(format!("{span:#}"), "2mo 10d 2h 30m");

// Parsing automatically supports both the ISO 8601 and "friendly"
// formats. Note that we use `Span::fieldwise` to create a `Span` that
// compares based on each field. To compare based on total duration, use
// `Span::compare` or `Span::total`.
let span: Span = "2mo 10d 2h 30m".parse()?;
assert_eq!(span, 2.months().days(10).hours(2).minutes(30).fieldwise());
let span: Span = "2 months, 10 days, 2 hours, 30 minutes".parse()?;
assert_eq!(span, 2.months().days(10).hours(2).minutes(30).fieldwise());

The format supported is a variation (nearly a subset) of the duration format specified in ISO 8601 and a Jiff-specific “friendly” format. Here are more examples:

use jiff::{Span, ToSpan};

let spans = [
    // ISO 8601
    ("P40D", 40.days()),
    ("P1y1d", 1.year().days(1)),
    ("P3dT4h59m", 3.days().hours(4).minutes(59)),
    ("PT2H30M", 2.hours().minutes(30)),
    ("P1m", 1.month()),
    ("P1w", 1.week()),
    ("P1w4d", 1.week().days(4)),
    ("PT1m", 1.minute()),
    ("PT0.0021s", 2.milliseconds().microseconds(100)),
    ("PT0s", 0.seconds()),
    ("P0d", 0.seconds()),
    (
        "P1y1m1dT1h1m1.1s",
        1.year().months(1).days(1).hours(1).minutes(1).seconds(1).milliseconds(100),
    ),
    // Jiff's "friendly" format
    ("40d", 40.days()),
    ("40 days", 40.days()),
    ("1y1d", 1.year().days(1)),
    ("1yr 1d", 1.year().days(1)),
    ("3d4h59m", 3.days().hours(4).minutes(59)),
    ("3 days, 4 hours, 59 minutes", 3.days().hours(4).minutes(59)),
    ("3d 4h 59m", 3.days().hours(4).minutes(59)),
    ("2h30m", 2.hours().minutes(30)),
    ("2h 30m", 2.hours().minutes(30)),
    ("1mo", 1.month()),
    ("1w", 1.week()),
    ("1 week", 1.week()),
    ("1w4d", 1.week().days(4)),
    ("1 wk 4 days", 1.week().days(4)),
    ("1m", 1.minute()),
    ("0.0021s", 2.milliseconds().microseconds(100)),
    ("0s", 0.seconds()),
    ("0d", 0.seconds()),
    ("0 days", 0.seconds()),
    (
        "1y1mo1d1h1m1.1s",
        1.year().months(1).days(1).hours(1).minutes(1).seconds(1).milliseconds(100),
    ),
    (
        "1yr 1mo 1day 1hr 1min 1.1sec",
        1.year().months(1).days(1).hours(1).minutes(1).seconds(1).milliseconds(100),
    ),
    (
        "1 year, 1 month, 1 day, 1 hour, 1 minute 1.1 seconds",
        1.year().months(1).days(1).hours(1).minutes(1).seconds(1).milliseconds(100),
    ),
    (
        "1 year, 1 month, 1 day, 01:01:01.1",
        1.year().months(1).days(1).hours(1).minutes(1).seconds(1).milliseconds(100),
    ),
];
for (string, span) in spans {
    let parsed: Span = string.parse()?;
    assert_eq!(
        span.fieldwise(),
        parsed.fieldwise(),
        "result of parsing {string:?}",
    );
}

For more details, see the fmt::temporal and fmt::friendly modules.

§Comparisons

A Span does not implement the PartialEq or Eq traits. These traits were implemented in an earlier version of Jiff, but they made it too easy to introduce bugs. For example, 120.minutes() and 2.hours() always correspond to the same total duration, but they have different representations in memory and so didn’t compare equivalent.

The reason why the PartialEq and Eq trait implementations do not do comparisons with total duration is because it is fundamentally impossible to do such comparisons without a reference date in all cases.

However, it is undeniably occasionally useful to do comparisons based on the component fields, so long as such use cases can tolerate two different spans comparing unequal even when their total durations are equivalent. For example, many of the tests in Jiff (including the tests in the documentation) work by comparing a Span to an expected result. This is a good demonstration of when fieldwise comparisons are appropriate.

To do fieldwise comparisons with a span, use the Span::fieldwise method. This method creates a SpanFieldwise, which is just a Span that implements PartialEq and Eq in a fieldwise manner. In other words, it’s a speed bump to ensure this is the kind of comparison you actually want. For example:

use jiff::ToSpan;

assert_ne!(1.hour().fieldwise(), 60.minutes().fieldwise());
// These also work since you only need one fieldwise span to do a compare:
assert_ne!(1.hour(), 60.minutes().fieldwise());
assert_ne!(1.hour().fieldwise(), 60.minutes());

This is because doing true comparisons requires arithmetic and a relative datetime in the general case, and which can fail due to overflow. This operation is provided via Span::compare:

use jiff::{civil::date, ToSpan};

// This doesn't need a reference date since it's only using time units.
assert_eq!(1.hour().compare(60.minutes())?, std::cmp::Ordering::Equal);
// But if you have calendar units, then you need a
// reference date at minimum:
assert!(1.month().compare(30.days()).is_err());
assert_eq!(
    1.month().compare((30.days(), date(2025, 6, 1)))?,
    std::cmp::Ordering::Equal,
);
// A month can be a differing number of days!
assert_eq!(
    1.month().compare((30.days(), date(2025, 7, 1)))?,
    std::cmp::Ordering::Greater,
);

§Arithmetic

Spans can be added or subtracted via Span::checked_add and Span::checked_sub:

use jiff::{Span, ToSpan};

let span1 = 2.hours().minutes(20);
let span2: Span = "PT89400s".parse()?;
assert_eq!(span1.checked_add(span2)?, 27.hours().minutes(10).fieldwise());

When your spans involve calendar units, a relative datetime must be provided. (Because, for example, 1 month from March 1 is 31 days, but 1 month from April 1 is 30 days.)

use jiff::{civil::date, Span, ToSpan};

let span1 = 2.years().months(6).days(20);
let span2 = 400.days();
assert_eq!(
    span1.checked_add((span2, date(2023, 1, 1)))?,
    3.years().months(7).days(24).fieldwise(),
);
// The span changes when a leap year isn't included!
assert_eq!(
    span1.checked_add((span2, date(2025, 1, 1)))?,
    3.years().months(7).days(23).fieldwise(),
);

§Rounding and balancing

Unlike datetimes, multiple distinct Span values can actually correspond to the same duration of time. For example, all of the following correspond to the same duration:

  • 2 hours, 30 minutes
  • 150 minutes
  • 1 hour, 90 minutes

The first is said to be balanced. That is, its biggest non-zero unit cannot be expressed in an integer number of units bigger than hours. But the second is unbalanced because 150 minutes can be split up into hours and minutes. We call this sort of span a “top-heavy” unbalanced span. The third span is also unbalanced, but it’s “bottom-heavy” and rarely used. Jiff will generally only produce spans of the first two types. In particular, most Span producing APIs accept a “largest” Unit parameter, and the result can be said to be a span “balanced up to the largest unit provided.”

Balanced and unbalanced spans can be switched between as needed via the Span::round API by providing a rounding configuration with SpanRound::largest` set:

use jiff::{SpanRound, ToSpan, Unit};

let span = 2.hours().minutes(30);
let unbalanced = span.round(SpanRound::new().largest(Unit::Minute))?;
assert_eq!(unbalanced, 150.minutes().fieldwise());
let balanced = unbalanced.round(SpanRound::new().largest(Unit::Hour))?;
assert_eq!(balanced, 2.hours().minutes(30).fieldwise());

Balancing can also be done as part of computing spans from two datetimes:

use jiff::{civil::date, ToSpan, Unit};

let zdt1 = date(2024, 7, 7).at(15, 23, 0, 0).in_tz("America/New_York")?;
let zdt2 = date(2024, 11, 5).at(8, 0, 0, 0).in_tz("America/New_York")?;

// To make arithmetic reversible, the default largest unit for spans of
// time computed from zoned datetimes is hours:
assert_eq!(zdt1.until(&zdt2)?, 2_897.hour().minutes(37).fieldwise());
// But we can ask for the span to be balanced up to years:
assert_eq!(
    zdt1.until((Unit::Year, &zdt2))?,
    3.months().days(28).hours(16).minutes(37).fieldwise(),
);

While the Span::round API does balancing, it also, of course, does rounding as well. Rounding occurs when the smallest unit is set to something bigger than Unit::Nanosecond:

use jiff::{ToSpan, Unit};

let span = 2.hours().minutes(30);
assert_eq!(span.round(Unit::Hour)?, 3.hours().fieldwise());

When rounding spans with calendar units (years, months or weeks), then a relative datetime is required:

use jiff::{civil::date, SpanRound, ToSpan, Unit};

let span = 10.years().months(11);
let options = SpanRound::new()
    .smallest(Unit::Year)
    .relative(date(2024, 1, 1));
assert_eq!(span.round(options)?, 11.years().fieldwise());

§Days are not always 24 hours!

That is, a Span is made up of uniform and non-uniform units.

A uniform unit is a unit whose elapsed duration is always the same. A non-uniform unit is a unit whose elapsed duration is not always the same. There are two things that can impact the length of a non-uniform unit: the calendar date and the time zone.

Years and months are always considered non-uniform units. For example, 1 month from 2024-04-01 is 30 days, while 1 month from 2024-05-01 is 31 days. Similarly for years because of leap years.

Hours, minutes, seconds, milliseconds, microseconds and nanoseconds are always considered uniform units.

Days are only considered non-uniform when in the presence of a zone aware datetime. A day can be more or less than 24 hours, and it can be balanced up and down, but only when a relative zoned datetime is given. This typically happens because of DST (daylight saving time), but can also occur because of other time zone transitions too.

use jiff::{civil::date, SpanRound, ToSpan, Unit};

// 2024-03-10 in New York was 23 hours long,
// because of a jump to DST at 2am.
let zdt = date(2024, 3, 9).at(21, 0, 0, 0).in_tz("America/New_York")?;
// Goes from days to hours:
assert_eq!(
    1.day().round(SpanRound::new().largest(Unit::Hour).relative(&zdt))?,
    23.hours().fieldwise(),
);
// Goes from hours to days:
assert_eq!(
    23.hours().round(SpanRound::new().largest(Unit::Day).relative(&zdt))?,
    1.day().fieldwise(),
);
// 24 hours is more than 1 day starting at this time:
assert_eq!(
    24.hours().round(SpanRound::new().largest(Unit::Day).relative(&zdt))?,
    1.day().hours(1).fieldwise(),
);

And similarly, days can be longer than 24 hours:

use jiff::{civil::date, SpanRound, ToSpan, Unit};

// 2024-11-03 in New York was 25 hours long,
// because of a repetition of the 1 o'clock AM hour.
let zdt = date(2024, 11, 2).at(21, 0, 0, 0).in_tz("America/New_York")?;
// Goes from days to hours:
assert_eq!(
    1.day().round(SpanRound::new().largest(Unit::Hour).relative(&zdt))?,
    25.hours().fieldwise(),
);
// Goes from hours to days:
assert_eq!(
    25.hours().round(SpanRound::new().largest(Unit::Day).relative(&zdt))?,
    1.day().fieldwise(),
);
// 24 hours is less than 1 day starting at this time,
// so it stays in units of hours even though we ask
// for days (because 24 isn't enough hours to make
// 1 day):
assert_eq!(
    24.hours().round(SpanRound::new().largest(Unit::Day).relative(&zdt))?,
    24.hours().fieldwise(),
);

The APIs on Span will otherwise treat days as non-uniform unless a relative civil date is given, or there is an explicit opt-in to invariant 24-hour days. For example:

use jiff::{civil, SpanRelativeTo, ToSpan, Unit};

let span = 1.day();

// An error because days aren't always 24 hours:
assert_eq!(
    span.total(Unit::Hour).unwrap_err().to_string(),
    "using unit 'day' in a span or configuration requires that either \
     a relative reference time be given or \
     `SpanRelativeTo::days_are_24_hours()` is used to indicate \
     invariant 24-hour days, but neither were provided",
);
// Opt into invariant 24 hour days without a relative date:
let marker = SpanRelativeTo::days_are_24_hours();
let hours = span.total((Unit::Hour, marker))?;
// Or use a relative civil date, and all days are 24 hours:
let date = civil::date(2020, 1, 1);
let hours = span.total((Unit::Hour, date))?;
assert_eq!(hours, 24.0);

In Jiff, all weeks are 7 days. And generally speaking, weeks only appear in a Span if they were explicitly put there by the caller or if they were explicitly requested by the caller in an API. For example:

use jiff::{civil::date, ToSpan, Unit};

let dt1 = date(2024, 1, 1).at(0, 0, 0, 0);
let dt2 = date(2024, 7, 16).at(0, 0, 0, 0);
// Default units go up to days.
assert_eq!(dt1.until(dt2)?, 197.days().fieldwise());
// No weeks, even though we requested up to year.
assert_eq!(dt1.until((Unit::Year, dt2))?, 6.months().days(15).fieldwise());
// We get weeks only when we ask for them.
assert_eq!(dt1.until((Unit::Week, dt2))?, 28.weeks().days(1).fieldwise());

§Integration with std::time::Duration and SignedDuration

While Jiff primarily uses a Span for doing arithmetic on datetimes, one can convert between a Span and a std::time::Duration or a SignedDuration. The main difference between them is that a Span always keeps tracks of its individual units, and a Span can represent non-uniform units like months. In contrast, Duration and SignedDuration are always an exact elapsed amount of time. They don’t distinguish between 120 seconds and 2 minutes. And they can’t represent the concept of “months” because a month doesn’t have a single fixed amount of time.

However, an exact duration is still useful in certain contexts. Beyond that, it serves as an interoperability point due to the presence of an unsigned exact duration type in the standard library. Because of that, Jiff provides TryFrom trait implementations for converting to and from a std::time::Duration (and, of course, a SignedDuration). For example, to convert from a std::time::Duration to a Span:

use std::time::Duration;

use jiff::{Span, ToSpan};

let duration = Duration::new(86_400, 123_456_789);
let span = Span::try_from(duration)?;
// A duration-to-span conversion always results in a span with
// non-zero units no bigger than seconds.
assert_eq!(
    span.fieldwise(),
    86_400.seconds().milliseconds(123).microseconds(456).nanoseconds(789),
);

// Note that the conversion is fallible! For example:
assert!(Span::try_from(Duration::from_secs(u64::MAX)).is_err());
// At present, a Jiff `Span` can only represent a range of time equal to
// the range of time expressible via minimum and maximum Jiff timestamps.
// Which is roughly -9999-01-01 to 9999-12-31, or ~20,000 years.
assert!(Span::try_from(Duration::from_secs(999_999_999_999)).is_err());

And to convert from a Span to a std::time::Duration:

use std::time::Duration;

use jiff::{Span, ToSpan};

let span = 86_400.seconds()
    .milliseconds(123)
    .microseconds(456)
    .nanoseconds(789);
let duration = Duration::try_from(span)?;
assert_eq!(duration, Duration::new(86_400, 123_456_789));

Note that an error will occur when converting a Span to a std::time::Duration using the TryFrom trait implementation with units bigger than hours:

use std::time::Duration;

use jiff::ToSpan;

let span = 2.days().hours(10);
assert_eq!(
    Duration::try_from(span).unwrap_err().to_string(),
    "failed to convert span to duration without relative datetime \
     (must use `Span::to_duration` instead): using unit 'day' in a \
     span or configuration requires that either a relative reference \
     time be given or `SpanRelativeTo::days_are_24_hours()` is used \
     to indicate invariant 24-hour days, but neither were provided",
);

Similar code can be written for SignedDuration as well.

If you need to convert such spans, then as the error suggests, you’ll need to use Span::to_duration with a relative date.

And note that since a Span is signed and a std::time::Duration is unsigned, converting a negative Span to std::time::Duration will always fail. One can use Span::signum to get the sign of the span and Span::abs to make the span positive before converting it to a Duration:

use std::time::Duration;

use jiff::{Span, ToSpan};

let span = -86_400.seconds().nanoseconds(1);
let (sign, duration) = (span.signum(), Duration::try_from(span.abs())?);
assert_eq!((sign, duration), (-1, Duration::new(86_400, 1)));

Or, consider using Jiff’s own SignedDuration instead:

use jiff::{SignedDuration, Span, ToSpan};

let span = -86_400.seconds().nanoseconds(1);
let duration = SignedDuration::try_from(span)?;
assert_eq!(duration, SignedDuration::new(-86_400, -1));

Implementations§

Source§

impl Span

Infallible routines for setting units on a Span.

These are useful when the units are determined by the programmer or when they have been validated elsewhere. In general, use these routines when constructing an invalid Span should be considered a bug in the program.

Source

pub fn new() -> Span

Creates a new span representing a zero duration. That is, a duration in which no time has passed.

Source

pub fn years<I>(self, years: I) -> Span
where I: Into<i64>,

Set the number of years on this span. The value may be negative.

The fallible version of this method is Span::try_years.

§Panics

This panics when the number of years is too small or too big. The minimum value is -19,998. The maximum value is 19,998.

Source

pub fn months<I>(self, months: I) -> Span
where I: Into<i64>,

Set the number of months on this span. The value may be negative.

The fallible version of this method is Span::try_months.

§Panics

This panics when the number of months is too small or too big. The minimum value is -239,976. The maximum value is 239,976.

Source

pub fn weeks<I>(self, weeks: I) -> Span
where I: Into<i64>,

Set the number of weeks on this span. The value may be negative.

The fallible version of this method is Span::try_weeks.

§Panics

This panics when the number of weeks is too small or too big. The minimum value is -1,043,497. The maximum value is 1_043_497.

Source

pub fn days<I>(self, days: I) -> Span
where I: Into<i64>,

Set the number of days on this span. The value may be negative.

The fallible version of this method is Span::try_days.

§Panics

This panics when the number of days is too small or too big. The minimum value is -7,304,484. The maximum value is 7,304,484.

Source

pub fn hours<I>(self, hours: I) -> Span
where I: Into<i64>,

Set the number of hours on this span. The value may be negative.

The fallible version of this method is Span::try_hours.

§Panics

This panics when the number of hours is too small or too big. The minimum value is -175,307,616. The maximum value is 175,307,616.

Source

pub fn minutes<I>(self, minutes: I) -> Span
where I: Into<i64>,

Set the number of minutes on this span. The value may be negative.

The fallible version of this method is Span::try_minutes.

§Panics

This panics when the number of minutes is too small or too big. The minimum value is -10,518,456,960. The maximum value is 10,518,456,960.

Source

pub fn seconds<I>(self, seconds: I) -> Span
where I: Into<i64>,

Set the number of seconds on this span. The value may be negative.

The fallible version of this method is Span::try_seconds.

§Panics

This panics when the number of seconds is too small or too big. The minimum value is -631,107,417,600. The maximum value is 631,107,417,600.

Source

pub fn milliseconds<I>(self, milliseconds: I) -> Span
where I: Into<i64>,

Set the number of milliseconds on this span. The value may be negative.

The fallible version of this method is Span::try_milliseconds.

§Panics

This panics when the number of milliseconds is too small or too big. The minimum value is -631,107,417,600,000. The maximum value is 631,107,417,600,000.

Source

pub fn microseconds<I>(self, microseconds: I) -> Span
where I: Into<i64>,

Set the number of microseconds on this span. The value may be negative.

The fallible version of this method is Span::try_microseconds.

§Panics

This panics when the number of microseconds is too small or too big. The minimum value is -631,107,417,600,000,000. The maximum value is 631,107,417,600,000,000.

Source

pub fn nanoseconds<I>(self, nanoseconds: I) -> Span
where I: Into<i64>,

Set the number of nanoseconds on this span. The value may be negative.

Note that unlike all other units, a 64-bit integer number of nanoseconds is not big enough to represent all possible spans between all possible datetimes supported by Jiff. This means, for example, that computing a span between two datetimes that are far enough apart and requesting a largest unit of Unit::Nanosecond, might return an error due to lack of precision.

The fallible version of this method is Span::try_nanoseconds.

§Panics

This panics when the number of nanoseconds is too small or too big. The minimum value is -9,223,372,036,854,775,807. The maximum value is 9,223,372,036,854,775,807.

Source§

impl Span

Fallible methods for setting units on a Span.

These methods are useful when the span is made up of user provided values that may not be in range.

Source

pub fn try_years<I>(self, years: I) -> Result<Span, Error>
where I: Into<i64>,

Set the number of years on this span. The value may be negative.

The panicking version of this method is Span::years.

§Errors

This returns an error when the number of years is too small or too big. The minimum value is -19,998. The maximum value is 19,998.

Source

pub fn try_months<I>(self, months: I) -> Result<Span, Error>
where I: Into<i64>,

Set the number of months on this span. The value may be negative.

The panicking version of this method is Span::months.

§Errors

This returns an error when the number of months is too small or too big. The minimum value is -239,976. The maximum value is 239,976.

Source

pub fn try_weeks<I>(self, weeks: I) -> Result<Span, Error>
where I: Into<i64>,

Set the number of weeks on this span. The value may be negative.

The panicking version of this method is Span::weeks.

§Errors

This returns an error when the number of weeks is too small or too big. The minimum value is -1,043,497. The maximum value is 1_043_497.

Source

pub fn try_days<I>(self, days: I) -> Result<Span, Error>
where I: Into<i64>,

Set the number of days on this span. The value may be negative.

The panicking version of this method is Span::days.

§Errors

This returns an error when the number of days is too small or too big. The minimum value is -7,304,484. The maximum value is 7,304,484.

Source

pub fn try_hours<I>(self, hours: I) -> Result<Span, Error>
where I: Into<i64>,

Set the number of hours on this span. The value may be negative.

The panicking version of this method is Span::hours.

§Errors

This returns an error when the number of hours is too small or too big. The minimum value is -175,307,616. The maximum value is 175,307,616.

Source

pub fn try_minutes<I>(self, minutes: I) -> Result<Span, Error>
where I: Into<i64>,

Set the number of minutes on this span. The value may be negative.

The panicking version of this method is Span::minutes.

§Errors

This returns an error when the number of minutes is too small or too big. The minimum value is -10,518,456,960. The maximum value is 10,518,456,960.

Source

pub fn try_seconds<I>(self, seconds: I) -> Result<Span, Error>
where I: Into<i64>,

Set the number of seconds on this span. The value may be negative.

The panicking version of this method is Span::seconds.

§Errors

This returns an error when the number of seconds is too small or too big. The minimum value is -631,107,417,600. The maximum value is 631,107,417,600.

Source

pub fn try_milliseconds<I>(self, milliseconds: I) -> Result<Span, Error>
where I: Into<i64>,

Set the number of milliseconds on this span. The value may be negative.

The panicking version of this method is Span::milliseconds.

§Errors

This returns an error when the number of milliseconds is too small or too big. The minimum value is -631,107,417,600,000. The maximum value is 631,107,417,600,000.

Source

pub fn try_microseconds<I>(self, microseconds: I) -> Result<Span, Error>
where I: Into<i64>,

Set the number of microseconds on this span. The value may be negative.

The panicking version of this method is Span::microseconds.

§Errors

This returns an error when the number of microseconds is too small or too big. The minimum value is -631,107,417,600,000,000. The maximum value is 631,107,417,600,000,000.

Source

pub fn try_nanoseconds<I>(self, nanoseconds: I) -> Result<Span, Error>
where I: Into<i64>,

Set the number of nanoseconds on this span. The value may be negative.

Note that unlike all other units, a 64-bit integer number of nanoseconds is not big enough to represent all possible spans between all possible datetimes supported by Jiff. This means, for example, that computing a span between two datetimes that are far enough apart and requesting a largest unit of Unit::Nanosecond, might return an error due to lack of precision.

The panicking version of this method is Span::nanoseconds.

§Errors

This returns an error when the number of nanoseconds is too small or too big. The minimum value is -9,223,372,036,854,775,807. The maximum value is 9,223,372,036,854,775,807.

Source§

impl Span

Routines for accessing the individual units in a Span.

Source

pub fn get_years(&self) -> i16

Returns the number of year units in this span.

Note that this is not the same as the total number of years in the span. To get that, you’ll need to use either Span::round or Span::total.

§Example
use jiff::{civil::date, ToSpan, Unit};

let span = 3.years().months(24);
assert_eq!(3, span.get_years());
assert_eq!(5.0, span.total((Unit::Year, date(2024, 1, 1)))?);
Source

pub fn get_months(&self) -> i32

Returns the number of month units in this span.

Note that this is not the same as the total number of months in the span. To get that, you’ll need to use either Span::round or Span::total.

§Example
use jiff::{civil::date, ToSpan, Unit};

let span = 7.months().days(59);
assert_eq!(7, span.get_months());
assert_eq!(9.0, span.total((Unit::Month, date(2022, 6, 1)))?);
Source

pub fn get_weeks(&self) -> i32

Returns the number of week units in this span.

Note that this is not the same as the total number of weeks in the span. To get that, you’ll need to use either Span::round or Span::total.

§Example
use jiff::{civil::date, ToSpan, Unit};

let span = 3.weeks().days(14);
assert_eq!(3, span.get_weeks());
assert_eq!(5.0, span.total((Unit::Week, date(2024, 1, 1)))?);
Source

pub fn get_days(&self) -> i32

Returns the number of day units in this span.

Note that this is not the same as the total number of days in the span. To get that, you’ll need to use either Span::round or Span::total.

§Example
use jiff::{ToSpan, Unit, Zoned};

let span = 3.days().hours(47);
assert_eq!(3, span.get_days());

let zdt: Zoned = "2024-03-07[America/New_York]".parse()?;
assert_eq!(5.0, span.total((Unit::Day, &zdt))?);
Source

pub fn get_hours(&self) -> i32

Returns the number of hour units in this span.

Note that this is not the same as the total number of hours in the span. To get that, you’ll need to use either Span::round or Span::total.

§Example
use jiff::{ToSpan, Unit};

let span = 3.hours().minutes(120);
assert_eq!(3, span.get_hours());
assert_eq!(5.0, span.total(Unit::Hour)?);
Source

pub fn get_minutes(&self) -> i64

Returns the number of minute units in this span.

Note that this is not the same as the total number of minutes in the span. To get that, you’ll need to use either Span::round or Span::total.

§Example
use jiff::{ToSpan, Unit};

let span = 3.minutes().seconds(120);
assert_eq!(3, span.get_minutes());
assert_eq!(5.0, span.total(Unit::Minute)?);
Source

pub fn get_seconds(&self) -> i64

Returns the number of second units in this span.

Note that this is not the same as the total number of seconds in the span. To get that, you’ll need to use either Span::round or Span::total.

§Example
use jiff::{ToSpan, Unit};

let span = 3.seconds().milliseconds(2_000);
assert_eq!(3, span.get_seconds());
assert_eq!(5.0, span.total(Unit::Second)?);
Source

pub fn get_milliseconds(&self) -> i64

Returns the number of millisecond units in this span.

Note that this is not the same as the total number of milliseconds in the span. To get that, you’ll need to use either Span::round or Span::total.

§Example
use jiff::{ToSpan, Unit};

let span = 3.milliseconds().microseconds(2_000);
assert_eq!(3, span.get_milliseconds());
assert_eq!(5.0, span.total(Unit::Millisecond)?);
Source

pub fn get_microseconds(&self) -> i64

Returns the number of microsecond units in this span.

Note that this is not the same as the total number of microseconds in the span. To get that, you’ll need to use either Span::round or Span::total.

§Example
use jiff::{ToSpan, Unit};

let span = 3.microseconds().nanoseconds(2_000);
assert_eq!(3, span.get_microseconds());
assert_eq!(5.0, span.total(Unit::Microsecond)?);
Source

pub fn get_nanoseconds(&self) -> i64

Returns the number of nanosecond units in this span.

Note that this is not the same as the total number of nanoseconds in the span. To get that, you’ll need to use either Span::round or Span::total.

§Example
use jiff::{ToSpan, Unit};

let span = 3.microseconds().nanoseconds(2_000);
assert_eq!(2_000, span.get_nanoseconds());
assert_eq!(5_000.0, span.total(Unit::Nanosecond)?);
Source§

impl Span

Routines for manipulating, comparing and inspecting Span values.

Source

pub fn abs(self) -> Span

Returns a new span that is the absolute value of this span.

If this span is zero or positive, then this is a no-op.

§Example
use jiff::ToSpan;

let span = -100.seconds();
assert_eq!(span.to_string(), "-PT100S");
let span = span.abs();
assert_eq!(span.to_string(), "PT100S");
Source

pub fn negate(self) -> Span

Returns a new span that negates this span.

If this span is zero, then this is a no-op. If this span is negative, then the returned span is positive. If this span is positive, then the returned span is negative.

§Example
use jiff::ToSpan;

let span = 100.days();
assert_eq!(span.to_string(), "P100D");
let span = span.negate();
assert_eq!(span.to_string(), "-P100D");
§Example: available via the negation operator

This routine can also be used via -:

use jiff::ToSpan;

let span = 100.days();
assert_eq!(span.to_string(), "P100D");
let span = -span;
assert_eq!(span.to_string(), "-P100D");
Source

pub fn signum(self) -> i8

Returns the “sign number” or “signum” of this span.

The number returned is -1 when this span is negative, 0 when this span is zero and 1 when this span is positive.

Source

pub fn is_positive(self) -> bool

Returns true if and only if this span is positive.

This returns false when the span is zero or negative.

§Example
use jiff::ToSpan;

assert!(!2.months().is_negative());
assert!((-2.months()).is_negative());
Source

pub fn is_negative(self) -> bool

Returns true if and only if this span is negative.

This returns false when the span is zero or positive.

§Example
use jiff::ToSpan;

assert!(!2.months().is_negative());
assert!((-2.months()).is_negative());
Source

pub fn is_zero(self) -> bool

Returns true if and only if every field in this span is set to 0.

§Example
use jiff::{Span, ToSpan};

assert!(Span::new().is_zero());
assert!(Span::default().is_zero());
assert!(0.seconds().is_zero());
assert!(!0.seconds().seconds(1).is_zero());
assert!(0.seconds().seconds(1).seconds(0).is_zero());
Source

pub fn fieldwise(self) -> SpanFieldwise

Returns this Span as a value with a type that implements the Hash, Eq and PartialEq traits in a fieldwise fashion.

A SpanFieldwise is meant to make it easy to compare two spans in a “dumb” way based purely on its unit values. This is distinct from something like Span::compare that performs a comparison on the actual elapsed time of two spans.

It is generally discouraged to use SpanFieldwise since spans that represent an equivalent elapsed amount of time may compare unequal. However, in some cases, it is useful to be able to assert precise field values. For example, Jiff itself makes heavy use of fieldwise comparisons for tests.

§Example: the difference between SpanFieldwise and Span::compare

In short, SpanFieldwise considers 2 hours and 120 minutes to be distinct values, but Span::compare considers them to be equivalent:

use std::cmp::Ordering;
use jiff::ToSpan;

assert_ne!(120.minutes().fieldwise(), 2.hours().fieldwise());
assert_eq!(120.minutes().compare(2.hours())?, Ordering::Equal);
Source

pub fn checked_mul(self, rhs: i64) -> Result<Span, Error>

Multiplies each field in this span by a given integer.

If this would cause any individual field in this span to overflow, then this returns an error.

§Example
use jiff::ToSpan;

let span = 4.days().seconds(8);
assert_eq!(span.checked_mul(2)?, 8.days().seconds(16).fieldwise());
assert_eq!(span.checked_mul(-3)?, -12.days().seconds(24).fieldwise());
// Notice that no re-balancing is done. It's "just" multiplication.
assert_eq!(span.checked_mul(10)?, 40.days().seconds(80).fieldwise());

let span = 10_000.years();
// too big!
assert!(span.checked_mul(3).is_err());
§Example: available via the multiplication operator

This method can be used via the * operator. Note though that a panic happens on overflow.

use jiff::ToSpan;

let span = 4.days().seconds(8);
assert_eq!(span * 2, 8.days().seconds(16).fieldwise());
assert_eq!(2 * span, 8.days().seconds(16).fieldwise());
assert_eq!(span * -3, -12.days().seconds(24).fieldwise());
assert_eq!(-3 * span, -12.days().seconds(24).fieldwise());
Source

pub fn checked_add<'a, A>(&self, options: A) -> Result<Span, Error>
where A: Into<SpanArithmetic<'a>>,

Adds a span to this one and returns the sum as a new span.

When adding a span with units greater than hours, callers must provide a relative datetime to anchor the spans.

Arithmetic proceeds as specified in RFC 5545. Bigger units are added together before smaller units.

This routine accepts anything that implements Into<SpanArithmetic>. There are some trait implementations that make using this routine ergonomic:

  • From<Span> for SpanArithmetic adds the given span to this one.
  • From<(Span, civil::Date)> for SpanArithmetic adds the given span to this one relative to the given date. There are also From implementations for civil::DateTime and Zoned.

This also works with different duration types, such as SignedDuration and std::time::Duration, via additional trait implementations:

  • From<SignedDuration> for SpanArithmetic adds the given duration to this one.
  • From<(SignedDuration, civil::Date)> for SpanArithmetic adds the given duration to this one relative to the given date. There are also From implementations for civil::DateTime and Zoned.

And similarly for std::time::Duration.

Adding a negative span is equivalent to subtracting its absolute value.

The largest non-zero unit in the span returned is at most the largest non-zero unit among the two spans being added. For an absolute duration, its “largest” unit is considered to be nanoseconds.

The sum returned is automatically re-balanced so that the span is not “bottom heavy.”

§Errors

This returns an error when adding the two spans would overflow any individual field of a span. This will also return an error if either of the spans have non-zero units of days or greater and no relative reference time is provided.

Callers may use SpanArithmetic::days_are_24_hours as a special marker instead of providing a relative civil date to indicate that all days should be 24 hours long. This also results in treating all weeks as seven 24 hour days (168 hours).

§Example
use jiff::ToSpan;

assert_eq!(
    1.hour().checked_add(30.minutes())?,
    1.hour().minutes(30).fieldwise(),
);
§Example: re-balancing

This example shows how units are automatically rebalanced into bigger units when appropriate.

use jiff::ToSpan;

let span1 = 2.hours().minutes(59);
let span2 = 2.minutes();
assert_eq!(span1.checked_add(span2)?, 3.hours().minutes(1).fieldwise());
§Example: days are not assumed to be 24 hours by default

When dealing with units involving days or weeks, one must either provide a relative datetime (shown in the following examples) or opt into invariant 24 hour days:

use jiff::{SpanRelativeTo, ToSpan};

let span1 = 2.days().hours(23);
let span2 = 2.hours();
assert_eq!(
    span1.checked_add((span2, SpanRelativeTo::days_are_24_hours()))?,
    3.days().hours(1).fieldwise(),
);
§Example: adding spans with calendar units

If you try to add two spans with calendar units without specifying a relative datetime, you’ll get an error:

use jiff::ToSpan;

let span1 = 1.month().days(15);
let span2 = 15.days();
assert!(span1.checked_add(span2).is_err());

A relative datetime is needed because calendar spans may correspond to different actual durations depending on where the span begins:

use jiff::{civil::date, ToSpan};

let span1 = 1.month().days(15);
let span2 = 15.days();
// 1 month from March 1 is 31 days...
assert_eq!(
    span1.checked_add((span2, date(2008, 3, 1)))?,
    2.months().fieldwise(),
);
// ... but 1 month from April 1 is 30 days!
assert_eq!(
    span1.checked_add((span2, date(2008, 4, 1)))?,
    1.month().days(30).fieldwise(),
);
§Example: error on overflow

Adding two spans can overflow, and this will result in an error:

use jiff::ToSpan;

assert!(19_998.years().checked_add(1.year()).is_err());
§Example: adding an absolute duration to a span

This shows how one isn’t limited to just adding two spans together. One can also add absolute durations to a span.

use std::time::Duration;

use jiff::{SignedDuration, ToSpan};

assert_eq!(
    1.hour().checked_add(SignedDuration::from_mins(30))?,
    1.hour().minutes(30).fieldwise(),
);
assert_eq!(
    1.hour().checked_add(Duration::from_secs(30 * 60))?,
    1.hour().minutes(30).fieldwise(),
);

Note that even when adding an absolute duration, if the span contains non-uniform units, you still need to provide a relative datetime:

use jiff::{civil::date, SignedDuration, ToSpan};

// Might be 1 month or less than 1 month!
let dur = SignedDuration::from_hours(30 * 24);
// No relative datetime provided even when the span
// contains non-uniform units results in an error.
assert!(1.month().checked_add(dur).is_err());
// In this case, 30 days is one month (April).
assert_eq!(
    1.month().checked_add((dur, date(2024, 3, 1)))?,
    2.months().fieldwise(),
);
// In this case, 30 days is less than one month (May).
assert_eq!(
    1.month().checked_add((dur, date(2024, 4, 1)))?,
    1.month().days(30).fieldwise(),
);
Source

pub fn checked_sub<'a, A>(&self, options: A) -> Result<Span, Error>
where A: Into<SpanArithmetic<'a>>,

This routine is identical to Span::checked_add with the given duration negated.

§Errors

This has the same error conditions as Span::checked_add.

§Example
use std::time::Duration;

use jiff::{SignedDuration, ToSpan};

assert_eq!(
    1.hour().checked_sub(30.minutes())?,
    30.minutes().fieldwise(),
);
assert_eq!(
    1.hour().checked_sub(SignedDuration::from_mins(30))?,
    30.minutes().fieldwise(),
);
assert_eq!(
    1.hour().checked_sub(Duration::from_secs(30 * 60))?,
    30.minutes().fieldwise(),
);
Source

pub fn compare<'a, C>(&self, options: C) -> Result<Ordering, Error>
where C: Into<SpanCompare<'a>>,

Compares two spans in terms of how long they are. Negative spans are considered shorter than the zero span.

Two spans compare equal when they correspond to the same duration of time, even if their individual fields are different. This is in contrast to the Eq trait implementation of Span, which performs exact field-wise comparisons. This split exists because the comparison provided by this routine is “heavy” in that it may need to do datetime arithmetic to return an answer. In contrast, the Eq trait implementation is “cheap.”

This routine accepts anything that implements Into<SpanCompare>. There are some trait implementations that make using this routine ergonomic:

  • From<Span> for SpanCompare compares the given span to this one.
  • From<(Span, civil::Date)> for SpanArithmetic compares the given span to this one relative to the given date. There are also From implementations for civil::DateTime and Zoned.
§Errors

If either of the spans being compared have a non-zero calendar unit (units bigger than hours), then this routine requires a relative datetime. If one is not provided, then an error is returned.

An error can also occur when adding either span to the relative datetime given results in overflow.

Callers may use SpanArithmetic::days_are_24_hours as a special marker instead of providing a relative civil date to indicate that all days should be 24 hours long. This also results in treating all weeks as seven 24 hour days (168 hours).

§Example
use jiff::ToSpan;

let span1 = 3.hours();
let span2 = 180.minutes();
assert_eq!(span1.compare(span2)?, std::cmp::Ordering::Equal);
// But notice that the two spans are not equal via `Eq`:
assert_ne!(span1.fieldwise(), span2.fieldwise());
§Example: negative spans are less than zero
use jiff::ToSpan;

let span1 = -1.second();
let span2 = 0.seconds();
assert_eq!(span1.compare(span2)?, std::cmp::Ordering::Less);
§Example: comparisons take DST into account

When a relative datetime is time zone aware, then DST is taken into account when comparing spans:

use jiff::{civil, ToSpan, Zoned};

let span1 = 79.hours().minutes(10);
let span2 = 3.days().hours(7).seconds(630);
let span3 = 3.days().hours(6).minutes(50);

let relative: Zoned = "2020-11-01T00-07[America/Los_Angeles]".parse()?;
let mut spans = [span1, span2, span3];
spans.sort_by(|s1, s2| s1.compare((s2, &relative)).unwrap());
assert_eq!(
    spans.map(|sp| sp.fieldwise()),
    [span1.fieldwise(), span3.fieldwise(), span2.fieldwise()],
);

// Compare with the result of sorting without taking DST into account.
// We can that by providing a relative civil date:
let relative = civil::date(2020, 11, 1);
spans.sort_by(|s1, s2| s1.compare((s2, relative)).unwrap());
assert_eq!(
    spans.map(|sp| sp.fieldwise()),
    [span3.fieldwise(), span1.fieldwise(), span2.fieldwise()],
);

See the examples for Span::total if you want to sort spans without an unwrap() call.

Source

pub fn total<'a, T>(&self, options: T) -> Result<f64, Error>
where T: Into<SpanTotal<'a>>,

Returns a floating point number representing the total number of a specific unit (as given) in this span. If the span is not evenly divisible by the requested units, then the number returned may have a fractional component.

This routine accepts anything that implements Into<SpanTotal>. There are some trait implementations that make using this routine ergonomic:

  • From<Unit> for SpanTotal computes a total for the given unit in this span.
  • From<(Unit, civil::Date)> for SpanTotal computes a total for the given unit in this span, relative to the given date. There are also From implementations for civil::DateTime and Zoned.
§Errors

If this span has any non-zero calendar unit (units bigger than hours), then this routine requires a relative datetime. If one is not provided, then an error is returned.

An error can also occur when adding the span to the relative datetime given results in overflow.

Callers may use SpanArithmetic::days_are_24_hours as a special marker instead of providing a relative civil date to indicate that all days should be 24 hours long. This also results in treating all weeks as seven 24 hour days (168 hours).

§Example

This example shows how to find the number of seconds in a particular span:

use jiff::{ToSpan, Unit};

let span = 3.hours().minutes(10);
assert_eq!(span.total(Unit::Second)?, 11_400.0);
§Example: 24 hour days

This shows how to find the total number of 24 hour days in 123,456,789 seconds.

use jiff::{SpanTotal, ToSpan, Unit};

let span = 123_456_789.seconds();
assert_eq!(
    span.total(SpanTotal::from(Unit::Day).days_are_24_hours())?,
    1428.8980208333332,
);
§Example: DST is taken into account

The month of March 2024 in America/New_York had 31 days, but one of those days was 23 hours long due a transition into daylight saving time:

use jiff::{civil::date, ToSpan, Unit};

let span = 744.hours();
let relative = date(2024, 3, 1).in_tz("America/New_York")?;
// Because of the short day, 744 hours is actually a little *more* than
// 1 month starting from 2024-03-01.
assert_eq!(span.total((Unit::Month, &relative))?, 1.0013888888888889);

Now compare what happens when the relative datetime is civil and not time zone aware:

use jiff::{civil::date, ToSpan, Unit};

let span = 744.hours();
let relative = date(2024, 3, 1);
assert_eq!(span.total((Unit::Month, relative))?, 1.0);
§Example: infallible sorting

The sorting example in Span::compare has to use unwrap() in its sort_by(..) call because Span::compare may fail and there is no “fallible” sorting routine in Rust’s standard library (as of 2024-07-07). While the ways in which Span::compare can fail for a valid configuration are limited to overflow for “extreme” values, it is possible to sort spans infallibly by computing floating point representations for each span up-front:

use jiff::{civil::Date, ToSpan, Unit, Zoned};

let span1 = 79.hours().minutes(10);
let span2 = 3.days().hours(7).seconds(630);
let span3 = 3.days().hours(6).minutes(50);

let relative: Zoned = "2020-11-01T00-07[America/Los_Angeles]".parse()?;
let mut spans = [
    (span1, span1.total((Unit::Day, &relative))?),
    (span2, span2.total((Unit::Day, &relative))?),
    (span3, span3.total((Unit::Day, &relative))?),
];
spans.sort_by(|&(_, total1), &(_, total2)| total1.total_cmp(&total2));
assert_eq!(
    spans.map(|(sp, _)| sp.fieldwise()),
    [span1.fieldwise(), span3.fieldwise(), span2.fieldwise()],
);

// Compare with the result of sorting without taking DST into account.
// We do that here by providing a relative civil date.
let relative: Date = "2020-11-01".parse()?;
let mut spans = [
    (span1, span1.total((Unit::Day, relative))?),
    (span2, span2.total((Unit::Day, relative))?),
    (span3, span3.total((Unit::Day, relative))?),
];
spans.sort_by(|&(_, total1), &(_, total2)| total1.total_cmp(&total2));
assert_eq!(
    spans.map(|(sp, _)| sp.fieldwise()),
    [span3.fieldwise(), span1.fieldwise(), span2.fieldwise()],
);
Source

pub fn round<'a, R>(self, options: R) -> Result<Span, Error>
where R: Into<SpanRound<'a>>,

Returns a new span that is balanced and rounded.

Rounding a span has a number of parameters, all of which are optional. When no parameters are given, then no rounding or balancing is done, and the span as given is returned. That is, it’s a no-op.

The parameters are, in brief:

  • SpanRound::largest sets the largest Unit that is allowed to be non-zero in the span returned. When only the largest unit is set, rounding itself doesn’t occur and instead the span is merely balanced.
  • SpanRound::smallest sets the smallest Unit that is allowed to be non-zero in the span returned. By default, it is set to Unit::Nanosecond, i.e., no rounding occurs. When the smallest unit is set to something bigger than nanoseconds, then the non-zero units in the span smaller than the smallest unit are used to determine how the span should be rounded. For example, rounding 1 hour 59 minutes to the nearest hour using the default rounding mode would produce 2 hours.
  • SpanRound::mode determines how to handle the remainder when rounding. The default is RoundMode::HalfExpand, which corresponds to how you were taught to round in school. Alternative modes, like RoundMode::Trunc, exist too. For example, a truncating rounding of 1 hour 59 minutes to the nearest hour would produce 1 hour.
  • SpanRound::increment sets the rounding granularity to use for the configured smallest unit. For example, if the smallest unit is minutes and the increment is 5, then the span returned will always have its minute units set to a multiple of 5.
  • SpanRound::relative sets the datetime from which to interpret the span. This is required when rounding spans with calendar units (years, months or weeks). When a relative datetime is time zone aware, then rounding accounts for the fact that not all days are 24 hours long. When a relative datetime is omitted or is civil (not time zone aware), then days are always 24 hours long.
§Constructing a SpanRound

This routine accepts anything that implements Into<SpanRound>. There are a few key trait implementations that make this convenient:

  • From<Unit> for SpanRound will construct a rounding configuration where the smallest unit is set to the one given.
  • From<(Unit, i64)> for SpanRound will construct a rounding configuration where the smallest unit and the rounding increment are set to the ones given.

To set other options (like the largest unit, the rounding mode and the relative datetime), one must explicitly create a SpanRound and pass it to this routine.

§Errors

In general, there are two main ways for rounding to fail: an improper configuration like trying to round a span with calendar units but without a relative datetime, or when overflow occurs. Overflow can occur when the span, added to the relative datetime if given, would exceed the minimum or maximum datetime values. Overflow can also occur if the span is too big to fit into the requested unit configuration. For example, a span like 19_998.years() cannot be represented with a 64-bit integer number of nanoseconds.

Callers may use SpanArithmetic::days_are_24_hours as a special marker instead of providing a relative civil date to indicate that all days should be 24 hours long. This also results in treating all weeks as seven 24 hour days (168 hours).

§Example: balancing

This example demonstrates balancing, not rounding. And in particular, this example shows how to balance a span as much as possible (i.e., with units of hours or smaller) without needing to specify a relative datetime:

use jiff::{SpanRound, ToSpan, Unit};

let span = 123_456_789_123_456_789i64.nanoseconds();
assert_eq!(
    span.round(SpanRound::new().largest(Unit::Hour))?.fieldwise(),
    34_293.hours().minutes(33).seconds(9)
        .milliseconds(123).microseconds(456).nanoseconds(789),
);

Or you can opt into invariant 24-hour days (and 7-day weeks) without a relative date with SpanRound::days_are_24_hours:

use jiff::{SpanRound, ToSpan, Unit};

let span = 123_456_789_123_456_789i64.nanoseconds();
assert_eq!(
    span.round(
        SpanRound::new().largest(Unit::Day).days_are_24_hours(),
    )?.fieldwise(),
    1_428.days()
        .hours(21).minutes(33).seconds(9)
        .milliseconds(123).microseconds(456).nanoseconds(789),
);
§Example: balancing and rounding

This example is like the one before it, but where we round to the nearest second:

use jiff::{SpanRound, ToSpan, Unit};

let span = 123_456_789_123_456_789i64.nanoseconds();
assert_eq!(
    span.round(SpanRound::new().largest(Unit::Hour).smallest(Unit::Second))?,
    34_293.hours().minutes(33).seconds(9).fieldwise(),
);

Or, just rounding to the nearest hour can make use of the From<Unit> for SpanRound trait implementation:

use jiff::{ToSpan, Unit};

let span = 123_456_789_123_456_789i64.nanoseconds();
assert_eq!(span.round(Unit::Hour)?, 34_294.hours().fieldwise());
§Example: balancing with a relative datetime

Even with calendar units, so long as a relative datetime is provided, it’s easy to turn days into bigger units:

use jiff::{civil::date, SpanRound, ToSpan, Unit};

let span = 1_000.days();
let relative = date(2000, 1, 1);
let options = SpanRound::new().largest(Unit::Year).relative(relative);
assert_eq!(span.round(options)?, 2.years().months(8).days(26).fieldwise());
§Example: round to the nearest half-hour
use jiff::{Span, ToSpan, Unit};

let span: Span = "PT23h50m3.123s".parse()?;
assert_eq!(span.round((Unit::Minute, 30))?, 24.hours().fieldwise());
§Example: yearly quarters in a span

This example shows how to find how many full 3 month quarters are in a particular span of time.

use jiff::{civil::date, RoundMode, SpanRound, ToSpan, Unit};

let span1 = 10.months().days(15);
let round = SpanRound::new()
    .smallest(Unit::Month)
    .increment(3)
    .mode(RoundMode::Trunc)
    // A relative datetime must be provided when
    // rounding involves calendar units.
    .relative(date(2024, 1, 1));
let span2 = span1.round(round)?;
assert_eq!(span2.get_months() / 3, 3);
Source

pub fn to_duration<'a, R>(&self, relative: R) -> Result<SignedDuration, Error>
where R: Into<SpanRelativeTo<'a>>,

Converts a Span to a SignedDuration relative to the date given.

In most cases, it is unlikely that you’ll need to use this routine to convert a Span to a SignedDuration. Namely, by default:

  • Zoned::until guarantees that the biggest non-zero unit is hours.
  • Timestamp::until guarantees that the biggest non-zero unit is seconds.
  • DateTime::until guarantees that the biggest non-zero unit is days.
  • Date::until guarantees that the biggest non-zero unit is days.
  • Time::until guarantees that the biggest non-zero unit is hours.

In the above, only DateTime::until and Date::until return calendar units by default. In which case, one may pass SpanRelativeTo::days_are_24_hours or an actual relative date to resolve the length of a day.

Of course, any of the above can be changed by asking, for example, Zoned::until to return units up to years.

§Errors

This returns an error if adding this span to the date given results in overflow. This can also return an error if one uses SpanRelativeTo::days_are_24_hours with a Span that has non-zero units greater than weeks.

§Example: converting a span with calendar units to a SignedDuration

This compares the number of seconds in a non-leap year with a leap year:

use jiff::{civil::date, SignedDuration, ToSpan};

let span = 1.year();

let duration = span.to_duration(date(2024, 1, 1))?;
assert_eq!(duration, SignedDuration::from_secs(31_622_400));
let duration = span.to_duration(date(2023, 1, 1))?;
assert_eq!(duration, SignedDuration::from_secs(31_536_000));
§Example: converting a span without a relative datetime

If for some reason it doesn’t make sense to include a relative datetime, you can use this routine to convert a Span with units up to weeks to a SignedDuration via the SpanRelativeTo::days_are_24_hours marker:

use jiff::{civil::date, SignedDuration, SpanRelativeTo, ToSpan};

let span = 1.week().days(1);

let duration = span.to_duration(SpanRelativeTo::days_are_24_hours())?;
assert_eq!(duration, SignedDuration::from_hours(192));
Source§

impl Span

This impl block contains no items.

Crate internal APIs that operate on ranged integer types.

Source§

impl Span

This impl block contains no items.

Crate internal helper routines.

Trait Implementations§

Source§

impl<'a> Add<Span> for &'a Zoned

Adds a span of time to a zoned datetime.

This uses checked arithmetic and panics on overflow. To handle overflow without panics, use Zoned::checked_add.

Source§

type Output = Zoned

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Span) -> Zoned

Performs the + operation. Read more
Source§

impl Add<Span> for Date

Adds a span of time to a date.

This uses checked arithmetic and panics on overflow. To handle overflow without panics, use Date::checked_add.

Source§

type Output = Date

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Span) -> Date

Performs the + operation. Read more
Source§

impl Add<Span> for DateTime

Adds a span of time to a datetime.

This uses checked arithmetic and panics on overflow. To handle overflow without panics, use DateTime::checked_add.

Source§

type Output = DateTime

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Span) -> DateTime

Performs the + operation. Read more
Source§

impl Add<Span> for Offset

Adds a span of time to an offset. This panics on overflow.

For checked arithmetic, see Offset::checked_add.

Source§

type Output = Offset

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Span) -> Offset

Performs the + operation. Read more
Source§

impl Add<Span> for Time

Adds a span of time. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_add.

Source§

type Output = Time

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Span) -> Time

Performs the + operation. Read more
Source§

impl Add<Span> for Timestamp

Adds a span of time to a timestamp.

This uses checked arithmetic and panics when it fails. To handle arithmetic without panics, use Timestamp::checked_add. Note that the failure condition includes overflow and using a Span with non-zero units greater than hours.

Source§

type Output = Timestamp

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Span) -> Timestamp

Performs the + operation. Read more
Source§

impl AddAssign<Span> for Date

Adds a span of time to a date in place.

This uses checked arithmetic and panics on overflow. To handle overflow without panics, use Date::checked_add.

Source§

fn add_assign(&mut self, rhs: Span)

Performs the += operation. Read more
Source§

impl AddAssign<Span> for DateTime

Adds a span of time to a datetime in place.

This uses checked arithmetic and panics on overflow. To handle overflow without panics, use DateTime::checked_add.

Source§

fn add_assign(&mut self, rhs: Span)

Performs the += operation. Read more
Source§

impl AddAssign<Span> for Offset

Adds a span of time to an offset in place. This panics on overflow.

For checked arithmetic, see Offset::checked_add.

Source§

fn add_assign(&mut self, rhs: Span)

Performs the += operation. Read more
Source§

impl AddAssign<Span> for Time

Adds a span of time in place. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_add.

Source§

fn add_assign(&mut self, rhs: Span)

Performs the += operation. Read more
Source§

impl AddAssign<Span> for Timestamp

Adds a span of time to a timestamp in place.

This uses checked arithmetic and panics when it fails. To handle arithmetic without panics, use Timestamp::checked_add. Note that the failure condition includes overflow and using a Span with non-zero units greater than hours.

Source§

fn add_assign(&mut self, rhs: Span)

Performs the += operation. Read more
Source§

impl AddAssign<Span> for Zoned

Adds a span of time to a zoned datetime in place.

This uses checked arithmetic and panics on overflow. To handle overflow without panics, use Zoned::checked_add.

Source§

fn add_assign(&mut self, rhs: Span)

Performs the += operation. Read more
Source§

impl Clone for Span

Source§

fn clone(&self) -> Span

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Span

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for Span

Source§

fn default() -> Span

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for Span

Source§

fn deserialize<D>( deserializer: D, ) -> Result<Span, <D as Deserializer<'de>>::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for Span

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<'a> From<&'a Span> for DateArithmetic

Source§

fn from(span: &'a Span) -> DateArithmetic

Converts to this type from the input type.
Source§

impl<'a> From<&'a Span> for DateTimeArithmetic

Source§

fn from(span: &'a Span) -> DateTimeArithmetic

Converts to this type from the input type.
Source§

impl<'a> From<&'a Span> for OffsetArithmetic

Source§

fn from(span: &'a Span) -> OffsetArithmetic

Converts to this type from the input type.
Source§

impl<'a> From<&'a Span> for SpanArithmetic<'static>

Source§

fn from(span: &'a Span) -> SpanArithmetic<'static>

Converts to this type from the input type.
Source§

impl<'a> From<&'a Span> for SpanCompare<'static>

Source§

fn from(span: &'a Span) -> SpanCompare<'static>

Converts to this type from the input type.
Source§

impl<'a> From<&'a Span> for TimeArithmetic

Source§

fn from(span: &'a Span) -> TimeArithmetic

Converts to this type from the input type.
Source§

impl<'a> From<&'a Span> for TimestampArithmetic

Source§

fn from(span: &'a Span) -> TimestampArithmetic

Converts to this type from the input type.
Source§

impl<'a> From<&'a Span> for ZonedArithmetic

Source§

fn from(span: &'a Span) -> ZonedArithmetic

Converts to this type from the input type.
Source§

impl From<Span> for DateArithmetic

Source§

fn from(span: Span) -> DateArithmetic

Converts to this type from the input type.
Source§

impl From<Span> for DateTimeArithmetic

Source§

fn from(span: Span) -> DateTimeArithmetic

Converts to this type from the input type.
Source§

impl From<Span> for OffsetArithmetic

Source§

fn from(span: Span) -> OffsetArithmetic

Converts to this type from the input type.
Source§

impl From<Span> for SpanArithmetic<'static>

Source§

fn from(span: Span) -> SpanArithmetic<'static>

Converts to this type from the input type.
Source§

impl From<Span> for SpanCompare<'static>

Source§

fn from(span: Span) -> SpanCompare<'static>

Converts to this type from the input type.
Source§

impl From<Span> for SpanFieldwise

Source§

fn from(span: Span) -> SpanFieldwise

Converts to this type from the input type.
Source§

impl From<Span> for TimeArithmetic

Source§

fn from(span: Span) -> TimeArithmetic

Converts to this type from the input type.
Source§

impl From<Span> for TimestampArithmetic

Source§

fn from(span: Span) -> TimestampArithmetic

Converts to this type from the input type.
Source§

impl From<Span> for ZonedArithmetic

Source§

fn from(span: Span) -> ZonedArithmetic

Converts to this type from the input type.
Source§

impl From<SpanFieldwise> for Span

Source§

fn from(span: SpanFieldwise) -> Span

Converts to this type from the input type.
Source§

impl FromStr for Span

Source§

type Err = Error

The associated error which can be returned from parsing.
Source§

fn from_str(string: &str) -> Result<Span, Error>

Parses a string s to return a value of this type. Read more
Source§

impl Mul<Span> for i64

This multiplies each unit in a span by an integer.

This panics on overflow. For checked arithmetic, use Span::checked_mul.

Source§

type Output = Span

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Span) -> Span

Performs the * operation. Read more
Source§

impl Mul<i64> for Span

This multiplies each unit in a span by an integer.

This panics on overflow. For checked arithmetic, use Span::checked_mul.

Source§

type Output = Span

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: i64) -> Span

Performs the * operation. Read more
Source§

impl Neg for Span

Source§

type Output = Span

The resulting type after applying the - operator.
Source§

fn neg(self) -> Span

Performs the unary - operation. Read more
Source§

impl PartialEq<Span> for SpanFieldwise

Source§

fn eq(&self, rhs: &Span) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<'a> PartialEq<SpanFieldwise> for &'a Span

Source§

fn eq(&self, rhs: &SpanFieldwise) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialEq<SpanFieldwise> for Span

Source§

fn eq(&self, rhs: &SpanFieldwise) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for Span

Source§

fn serialize<S>( &self, serializer: S, ) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl<'a> Sub<Span> for &'a Zoned

Subtracts a span of time from a zoned datetime.

This uses checked arithmetic and panics on overflow. To handle overflow without panics, use Zoned::checked_sub.

Source§

type Output = Zoned

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Span) -> Zoned

Performs the - operation. Read more
Source§

impl Sub<Span> for Date

Subtracts a span of time from a date.

This uses checked arithmetic and panics on overflow. To handle overflow without panics, use Date::checked_sub.

Source§

type Output = Date

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Span) -> Date

Performs the - operation. Read more
Source§

impl Sub<Span> for DateTime

Subtracts a span of time from a datetime.

This uses checked arithmetic and panics on overflow. To handle overflow without panics, use DateTime::checked_sub.

Source§

type Output = DateTime

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Span) -> DateTime

Performs the - operation. Read more
Source§

impl Sub<Span> for Offset

Subtracts a span of time from an offset. This panics on overflow.

For checked arithmetic, see Offset::checked_sub.

Source§

type Output = Offset

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Span) -> Offset

Performs the - operation. Read more
Source§

impl Sub<Span> for Time

Subtracts a span of time. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_sub.

Source§

type Output = Time

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Span) -> Time

Performs the - operation. Read more
Source§

impl Sub<Span> for Timestamp

Subtracts a span of time from a timestamp.

This uses checked arithmetic and panics when it fails. To handle arithmetic without panics, use Timestamp::checked_sub. Note that the failure condition includes overflow and using a Span with non-zero units greater than hours.

Source§

type Output = Timestamp

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Span) -> Timestamp

Performs the - operation. Read more
Source§

impl SubAssign<Span> for Date

Subtracts a span of time from a date in place.

This uses checked arithmetic and panics on overflow. To handle overflow without panics, use Date::checked_sub.

Source§

fn sub_assign(&mut self, rhs: Span)

Performs the -= operation. Read more
Source§

impl SubAssign<Span> for DateTime

Subtracts a span of time from a datetime in place.

This uses checked arithmetic and panics on overflow. To handle overflow without panics, use DateTime::checked_sub.

Source§

fn sub_assign(&mut self, rhs: Span)

Performs the -= operation. Read more
Source§

impl SubAssign<Span> for Offset

Subtracts a span of time from an offset in place. This panics on overflow.

For checked arithmetic, see Offset::checked_sub.

Source§

fn sub_assign(&mut self, rhs: Span)

Performs the -= operation. Read more
Source§

impl SubAssign<Span> for Time

Subtracts a span of time in place. This uses wrapping arithmetic.

For checked arithmetic, see Time::checked_sub.

Source§

fn sub_assign(&mut self, rhs: Span)

Performs the -= operation. Read more
Source§

impl SubAssign<Span> for Timestamp

Subtracts a span of time from a timestamp in place.

This uses checked arithmetic and panics when it fails. To handle arithmetic without panics, use Timestamp::checked_sub. Note that the failure condition includes overflow and using a Span with non-zero units greater than hours.

Source§

fn sub_assign(&mut self, rhs: Span)

Performs the -= operation. Read more
Source§

impl SubAssign<Span> for Zoned

Subtracts a span of time from a zoned datetime in place.

This uses checked arithmetic and panics on overflow. To handle overflow without panics, use Zoned::checked_sub.

Source§

fn sub_assign(&mut self, rhs: Span)

Performs the -= operation. Read more
Source§

impl TryFrom<Duration> for Span

Converts a std::time::Duration to a Span.

The span returned from this conversion will only ever have non-zero units of seconds or smaller.

§Errors

This only fails when the given Duration overflows the maximum number of seconds representable by a Span.

§Example

This shows a basic conversion:

use std::time::Duration;

use jiff::{Span, ToSpan};

let duration = Duration::new(86_400, 123_456_789);
let span = Span::try_from(duration)?;
// A duration-to-span conversion always results in a span with
// non-zero units no bigger than seconds.
assert_eq!(
    span.fieldwise(),
    86_400.seconds().milliseconds(123).microseconds(456).nanoseconds(789),
);

§Example: rounding

This example shows how to convert a Duration to a Span, and then round it up to bigger units given a relative date:

use std::time::Duration;

use jiff::{civil::date, Span, SpanRound, ToSpan, Unit};

let duration = Duration::new(450 * 86_401, 0);
let span = Span::try_from(duration)?;
// We get back a simple span of just seconds:
assert_eq!(span.fieldwise(), Span::new().seconds(450 * 86_401));
// But we can balance it up to bigger units:
let options = SpanRound::new()
    .largest(Unit::Year)
    .relative(date(2024, 1, 1));
assert_eq!(
    span.round(options)?,
    1.year().months(2).days(25).minutes(7).seconds(30).fieldwise(),
);
Source§

type Error = Error

The type returned in the event of a conversion error.
Source§

fn try_from(d: Duration) -> Result<Span, Error>

Performs the conversion.
Source§

impl TryFrom<SignedDuration> for Span

Converts a SignedDuration to a Span.

The span returned from this conversion will only ever have non-zero units of seconds or smaller.

§Errors

This only fails when the given SignedDuration overflows the maximum number of seconds representable by a Span.

§Example

This shows a basic conversion:

use jiff::{SignedDuration, Span, ToSpan};

let duration = SignedDuration::new(86_400, 123_456_789);
let span = Span::try_from(duration)?;
// A duration-to-span conversion always results in a span with
// non-zero units no bigger than seconds.
assert_eq!(
    span.fieldwise(),
    86_400.seconds().milliseconds(123).microseconds(456).nanoseconds(789),
);

§Example: rounding

This example shows how to convert a SignedDuration to a Span, and then round it up to bigger units given a relative date:

use jiff::{civil::date, SignedDuration, Span, SpanRound, ToSpan, Unit};

let duration = SignedDuration::new(450 * 86_401, 0);
let span = Span::try_from(duration)?;
// We get back a simple span of just seconds:
assert_eq!(span.fieldwise(), Span::new().seconds(450 * 86_401));
// But we can balance it up to bigger units:
let options = SpanRound::new()
    .largest(Unit::Year)
    .relative(date(2024, 1, 1));
assert_eq!(
    span.round(options)?,
    1.year().months(2).days(25).minutes(7).seconds(30).fieldwise(),
);
Source§

type Error = Error

The type returned in the event of a conversion error.
Source§

fn try_from(d: SignedDuration) -> Result<Span, Error>

Performs the conversion.
Source§

impl TryFrom<Span> for Duration

Converts a Span to a std::time::Duration.

Note that this assumes that days are always 24 hours long.

§Errors

This can fail for only two reasons:

  • The span is negative. This is an error because a std::time::Duration is unsigned.)
  • The span has any non-zero units greater than hours. This is an error because it’s impossible to determine the length of, e.g., a month without a reference date.

This can never result in overflow because a Duration can represent a bigger span of time than Span when limited to units of hours or lower.

If you need to convert a Span to a Duration that has non-zero units bigger than hours, then please use Span::to_duration with a corresponding relative date.

§Example: maximal span

This example shows the maximum possible span using units of hours or smaller, and the corresponding Duration value:

use std::time::Duration;

use jiff::Span;

let sp = Span::new()
    .hours(175_307_616)
    .minutes(10_518_456_960i64)
    .seconds(631_107_417_600i64)
    .milliseconds(631_107_417_600_000i64)
    .microseconds(631_107_417_600_000_000i64)
    .nanoseconds(9_223_372_036_854_775_807i64);
let duration = Duration::try_from(sp)?;
assert_eq!(duration, Duration::new(3_164_760_460_036, 854_775_807));

§Example: converting a negative span

Since a Span is signed and a Duration is unsigned, converting a negative Span to Duration will always fail. One can use Span::signum to get the sign of the span and Span::abs to make the span positive before converting it to a Duration:

use std::time::Duration;

use jiff::{Span, ToSpan};

let span = -86_400.seconds().nanoseconds(1);
let (sign, duration) = (span.signum(), Duration::try_from(span.abs())?);
assert_eq!((sign, duration), (-1, Duration::new(86_400, 1)));
Source§

type Error = Error

The type returned in the event of a conversion error.
Source§

fn try_from(sp: Span) -> Result<Duration, Error>

Performs the conversion.
Source§

impl TryFrom<Span> for SignedDuration

Converts a Span to a SignedDuration.

Note that this assumes that days are always 24 hours long.

§Errors

This can fail for only when the span has any non-zero units greater than hours. This is an error because it’s impossible to determine the length of, e.g., a month without a reference date.

This can never result in overflow because a SignedDuration can represent a bigger span of time than Span when limited to units of hours or lower.

If you need to convert a Span to a SignedDuration that has non-zero units bigger than hours, then please use Span::to_duration with a corresponding relative date.

§Example: maximal span

This example shows the maximum possible span using units of hours or smaller, and the corresponding SignedDuration value:

use jiff::{SignedDuration, Span};

let sp = Span::new()
    .hours(175_307_616)
    .minutes(10_518_456_960i64)
    .seconds(631_107_417_600i64)
    .milliseconds(631_107_417_600_000i64)
    .microseconds(631_107_417_600_000_000i64)
    .nanoseconds(9_223_372_036_854_775_807i64);
let duration = SignedDuration::try_from(sp)?;
assert_eq!(duration, SignedDuration::new(3_164_760_460_036, 854_775_807));
Source§

type Error = Error

The type returned in the event of a conversion error.
Source§

fn try_from(sp: Span) -> Result<SignedDuration, Error>

Performs the conversion.
Source§

impl Copy for Span

Auto Trait Implementations§

§

impl Freeze for Span

§

impl RefUnwindSafe for Span

§

impl Send for Span

§

impl Sync for Span

§

impl Unpin for Span

§

impl UnwindSafe for Span

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize = _

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> QuickClone<T> for T
where T: Clone,

Source§

fn C(&self) -> T

Source§

impl<T> QuickToOwned for T
where T: ToOwned,

Source§

type Owned = <T as ToOwned>::Owned

Source§

fn O(&self) -> <T as QuickToOwned>::Owned

Source§

impl<T> QuickToString for T
where T: ToString + ?Sized,

Source§

fn S(&self) -> String

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T