Struct jiff::civil::DateTime

source ·
pub struct DateTime { /* private fields */ }
Expand description

A representation of a civil datetime in the Gregorian calendar.

A DateTime value corresponds to a pair of a Date and a Time. That is, a datetime contains a year, month, day, hour, minute, second and the fractional number of nanoseconds.

A DateTime value is guaranteed to contain a valid date and time. For example, neither 2023-02-29T00:00:00 nor 2015-06-30T23:59:60 are valid DateTime values.

§Civil datetimes

A DateTime value behaves without regard to daylight saving time or time zones in general. When doing arithmetic on datetimes with spans defined in units of time (such as with DateTime::checked_add), days are considered to always be precisely 86,400 seconds long.

§Parsing and printing

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

use jiff::civil::DateTime;

let dt: DateTime = "2024-06-19 15:22:45".parse()?;
assert_eq!(dt.to_string(), "2024-06-19T15:22:45");

A civil DateTime can also be parsed from something that contains a datetime, but with perhaps other data (such as an offset or time zone):

use jiff::civil::DateTime;

let dt: DateTime = "2024-06-19T15:22:45-04[America/New_York]".parse()?;
assert_eq!(dt.to_string(), "2024-06-19T15:22:45");

For more information on the specific format supported, see the fmt::temporal module documentation.

§Default value

For convenience, this type implements the Default trait. Its default value corresponds to 0000-01-01T00:00:00.000000000. That is, it is the datetime corresponding to DateTime::from_parts(Date::default(), Time::default()). One can also access this value via the DateTime::ZERO constant.

§Leap seconds

Jiff does not support leap seconds. Jiff behaves as if they don’t exist. The only exception is that if one parses a datetime with a second component of 60, then it is automatically constrained to 59:

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

let dt: DateTime = "2016-12-31 23:59:60".parse()?;
assert_eq!(dt, date(2016, 12, 31).at(23, 59, 59, 0));

§Comparisons

The DateTime type provides both Eq and Ord trait implementations to facilitate easy comparisons. When a datetime dt1 occurs before a datetime dt2, then dt1 < dt2. For example:

use jiff::civil::date;

let dt1 = date(2024, 3, 11).at(1, 25, 15, 0);
let dt2 = date(2025, 1, 31).at(0, 30, 0, 0);
assert!(dt1 < dt2);

§Arithmetic

This type provides routines for adding and subtracting spans of time, as well as computing the span of time between two DateTime values.

For adding or subtracting spans of time, one can use any of the following routines:

Additionally, checked arithmetic is available via the Add and Sub trait implementations. When the result overflows, a panic occurs.

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

let start = date(2024, 2, 25).at(15, 45, 0, 0);
let one_week_later = start + 1.weeks();
assert_eq!(one_week_later, date(2024, 3, 3).at(15, 45, 0, 0));

One can compute the span of time between two datetimes using either DateTime::until or DateTime::since. It’s also possible to subtract two DateTime values directly via a Sub trait implementation:

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

let datetime1 = date(2024, 5, 3).at(23, 30, 0, 0);
let datetime2 = date(2024, 2, 25).at(7, 0, 0, 0);
assert_eq!(datetime1 - datetime2, 68.days().hours(16).minutes(30));

The until and since APIs are polymorphic and allow re-balancing and rounding the span returned. For example, the default largest unit is days (as exemplified above), but we can ask for bigger units:

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

let datetime1 = date(2024, 5, 3).at(23, 30, 0, 0);
let datetime2 = date(2024, 2, 25).at(7, 0, 0, 0);
assert_eq!(
    datetime1.since((Unit::Year, datetime2))?,
    2.months().days(7).hours(16).minutes(30),
);

Or even round the span returned:

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

let datetime1 = date(2024, 5, 3).at(23, 30, 0, 0);
let datetime2 = date(2024, 2, 25).at(7, 0, 0, 0);
assert_eq!(
    datetime1.since(
        DateTimeDifference::new(datetime2)
            .smallest(Unit::Day)
            .largest(Unit::Year),
    )?,
    2.months().days(7),
);
// `DateTimeDifference` uses truncation as a rounding mode by default,
// but you can set the rounding mode to break ties away from zero:
assert_eq!(
    datetime1.since(
        DateTimeDifference::new(datetime2)
            .smallest(Unit::Day)
            .largest(Unit::Year)
            .mode(RoundMode::HalfExpand),
    )?,
    // Rounds up to 8 days.
    2.months().days(8),
);

§Rounding

A DateTime can be rounded based on a DateTimeRound configuration of smallest units, rounding increment and rounding mode. Here’s an example showing how to round to the nearest third hour:

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

let dt = date(2024, 6, 19).at(16, 27, 29, 999_999_999);
assert_eq!(
    dt.round(DateTimeRound::new().smallest(Unit::Hour).increment(3))?,
    date(2024, 6, 19).at(15, 0, 0, 0),
);
// Or alternatively, make use of the `From<(Unit, i64)> for DateTimeRound`
// trait implementation:
assert_eq!(
    dt.round((Unit::Hour, 3))?,
    date(2024, 6, 19).at(15, 0, 0, 0),
);

See DateTime::round for more details.

Implementations§

source§

impl DateTime

source

pub const MIN: DateTime = _

The minimum representable Gregorian datetime.

The minimum is chosen such that any Timestamp combined with any valid time zone offset can be infallibly converted to this type.

source

pub const MAX: DateTime = _

The maximum representable Gregorian datetime.

The maximum is chosen such that any Timestamp combined with any valid time zone offset can be infallibly converted to this type.

source

pub const ZERO: DateTime = _

The first day of the zeroth year.

This is guaranteed to be equivalent to DateTime::default().

§Example
use jiff::civil::DateTime;

assert_eq!(DateTime::ZERO, DateTime::default());
source

pub fn new( year: i16, month: i8, day: i8, hour: i8, minute: i8, second: i8, subsec_nanosecond: i32, ) -> Result<DateTime, Error>

Creates a new DateTime value from its component year, month, day, hour, minute, second and fractional subsecond (up to nanosecond precision) values.

To create a new datetime from another with a particular component, use the methods on DateTimeWith via DateTime::with.

§Errors

This returns an error when the given components do not correspond to a valid datetime. Namely, all of the following must be true:

  • The year must be in the range -9999..=9999.
  • The month must be in the range 1..=12.
  • The day must be at least 1 and must be at most the number of days in the corresponding month. So for example, 2024-02-29 is valid but 2023-02-29 is not.
  • 0 <= hour <= 23
  • 0 <= minute <= 59
  • 0 <= second <= 59
  • 0 <= subsec_nanosecond <= 999,999,999
§Example

This shows an example of a valid datetime:

use jiff::civil::DateTime;

let d = DateTime::new(2024, 2, 29, 21, 30, 5, 123_456_789).unwrap();
assert_eq!(d.year(), 2024);
assert_eq!(d.month(), 2);
assert_eq!(d.day(), 29);
assert_eq!(d.hour(), 21);
assert_eq!(d.minute(), 30);
assert_eq!(d.second(), 5);
assert_eq!(d.millisecond(), 123);
assert_eq!(d.microsecond(), 456);
assert_eq!(d.nanosecond(), 789);

This shows some examples of invalid datetimes:

use jiff::civil::DateTime;

assert!(DateTime::new(2023, 2, 29, 21, 30, 5, 0).is_err());
assert!(DateTime::new(2015, 6, 30, 23, 59, 60, 0).is_err());
assert!(DateTime::new(2024, 6, 20, 19, 58, 0, 1_000_000_000).is_err());
source

pub const fn constant( year: i16, month: i8, day: i8, hour: i8, minute: i8, second: i8, subsec_nanosecond: i32, ) -> DateTime

Creates a new DateTime value in a const context.

Note that an alternative syntax that is terser and perhaps easier to read for the same operation is to combine civil::date with Date::at.

§Panics

This routine panics when DateTime::new would return an error. That is, when the given components do not correspond to a valid datetime. Namely, all of the following must be true:

  • The year must be in the range -9999..=9999.
  • The month must be in the range 1..=12.
  • The day must be at least 1 and must be at most the number of days in the corresponding month. So for example, 2024-02-29 is valid but 2023-02-29 is not.
  • 0 <= hour <= 23
  • 0 <= minute <= 59
  • 0 <= second <= 59
  • 0 <= subsec_nanosecond <= 999,999,999

Similarly, when used in a const context, invalid parameters will prevent your Rust program from compiling.

§Example
use jiff::civil::DateTime;

let dt = DateTime::constant(2024, 2, 29, 21, 30, 5, 123_456_789);
assert_eq!(dt.year(), 2024);
assert_eq!(dt.month(), 2);
assert_eq!(dt.day(), 29);
assert_eq!(dt.hour(), 21);
assert_eq!(dt.minute(), 30);
assert_eq!(dt.second(), 5);
assert_eq!(dt.millisecond(), 123);
assert_eq!(dt.microsecond(), 456);
assert_eq!(dt.nanosecond(), 789);

Or alternatively:

use jiff::civil::date;

let dt = date(2024, 2, 29).at(21, 30, 5, 123_456_789);
assert_eq!(dt.year(), 2024);
assert_eq!(dt.month(), 2);
assert_eq!(dt.day(), 29);
assert_eq!(dt.hour(), 21);
assert_eq!(dt.minute(), 30);
assert_eq!(dt.second(), 5);
assert_eq!(dt.millisecond(), 123);
assert_eq!(dt.microsecond(), 456);
assert_eq!(dt.nanosecond(), 789);
source

pub const fn from_parts(date: Date, time: Time) -> DateTime

Creates a DateTime from its constituent parts.

Any combination of a valid Date and a valid Time results in a valid DateTime.

§Example

This example shows how to build a datetime from its parts:

use jiff::civil::{DateTime, date, time};

let dt = DateTime::from_parts(date(2024, 6, 6), time(6, 0, 0, 0));
assert_eq!(dt, date(2024, 6, 6).at(6, 0, 0, 0));
source

pub fn with(self) -> DateTimeWith

Create a builder for constructing a new DateTime from the fields of this datetime.

See the methods on DateTimeWith for the different ways one can set the fields of a new DateTime.

§Example

The builder ensures one can chain together the individual components of a datetime without it failing at an intermediate step. For example, if you had a date of 2024-10-31T00:00:00 and wanted to change both the day and the month, and each setting was validated independent of the other, you would need to be careful to set the day first and then the month. In some cases, you would need to set the month first and then the day!

But with the builder, you can set values in any order:

use jiff::civil::date;

let dt1 = date(2024, 10, 31).at(0, 0, 0, 0);
let dt2 = dt1.with().month(11).day(30).build()?;
assert_eq!(dt2, date(2024, 11, 30).at(0, 0, 0, 0));

let dt1 = date(2024, 4, 30).at(0, 0, 0, 0);
let dt2 = dt1.with().day(31).month(7).build()?;
assert_eq!(dt2, date(2024, 7, 31).at(0, 0, 0, 0));
source

pub fn year(self) -> i16

Returns the year for this datetime.

§Example
use jiff::civil::date;

let dt1 = date(2024, 3, 9).at(7, 30, 0, 0);
assert_eq!(dt1.year(), 2024);

let dt2 = date(-2024, 3, 9).at(7, 30, 0, 0);
assert_eq!(dt2.year(), -2024);

let dt3 = date(0, 3, 9).at(7, 30, 0, 0);
assert_eq!(dt3.year(), 0);
source

pub fn era_year(self) -> (i16, Era)

Returns the year and its era.

This crate specifically allows years to be negative or 0, where as years written for the Gregorian calendar are always positive and greater than 0. In the Gregorian calendar, the era labels BCE and CE are used to disambiguate between years less than or equal to 0 and years greater than 0, respectively.

The crate is designed this way so that years in the latest era (that is, CE) are aligned with years in this crate.

§Example
use jiff::civil::{Era, date};

let dt = date(2024, 10, 3).at(7, 30, 0, 0);
assert_eq!(dt.era_year(), (2024, Era::CE));

let dt = date(1, 10, 3).at(7, 30, 0, 0);
assert_eq!(dt.era_year(), (1, Era::CE));

let dt = date(0, 10, 3).at(7, 30, 0, 0);
assert_eq!(dt.era_year(), (1, Era::BCE));

let dt = date(-1, 10, 3).at(7, 30, 0, 0);
assert_eq!(dt.era_year(), (2, Era::BCE));

let dt = date(-10, 10, 3).at(7, 30, 0, 0);
assert_eq!(dt.era_year(), (11, Era::BCE));

let dt = date(-9_999, 10, 3).at(7, 30, 0, 0);
assert_eq!(dt.era_year(), (10_000, Era::BCE));
source

pub fn month(self) -> i8

Returns the month for this datetime.

§Example
use jiff::civil::date;

let dt1 = date(2024, 3, 9).at(7, 30, 0, 0);
assert_eq!(dt1.month(), 3);
source

pub fn day(self) -> i8

Returns the day for this datetime.

§Example
use jiff::civil::date;

let dt1 = date(2024, 2, 29).at(7, 30, 0, 0);
assert_eq!(dt1.day(), 29);
source

pub fn hour(self) -> i8

Returns the “hour” component of this datetime.

§Example
use jiff::civil::date;

let dt = date(2000, 1, 2).at(3, 4, 5, 123_456_789);
assert_eq!(dt.hour(), 3);
source

pub fn minute(self) -> i8

Returns the “minute” component of this datetime.

§Example
use jiff::civil::date;

let dt = date(2000, 1, 2).at(3, 4, 5, 123_456_789);
assert_eq!(dt.minute(), 4);
source

pub fn second(self) -> i8

Returns the “second” component of this datetime.

§Example
use jiff::civil::date;

let dt = date(2000, 1, 2).at(3, 4, 5, 123_456_789);
assert_eq!(dt.second(), 5);
source

pub fn millisecond(self) -> i16

Returns the “millisecond” component of this datetime.

§Example
use jiff::civil::date;

let dt = date(2000, 1, 2).at(3, 4, 5, 123_456_789);
assert_eq!(dt.millisecond(), 123);
source

pub fn microsecond(self) -> i16

Returns the “microsecond” component of this datetime.

§Example
use jiff::civil::date;

let dt = date(2000, 1, 2).at(3, 4, 5, 123_456_789);
assert_eq!(dt.microsecond(), 456);
source

pub fn nanosecond(self) -> i16

Returns the “nanosecond” component of this datetime.

§Example
use jiff::civil::date;

let dt = date(2000, 1, 2).at(3, 4, 5, 123_456_789);
assert_eq!(dt.nanosecond(), 789);
source

pub fn subsec_nanosecond(self) -> i32

Returns the fractional nanosecond for this DateTime value.

If you want to set this value on DateTime, then use DateTimeWith::subsec_nanosecond via DateTime::with.

§Example

This shows the relationship between constructing a DateTime value with routines like with().millisecond() and accessing the entire fractional part as a nanosecond:

use jiff::civil::date;

let dt1 = date(2000, 1, 2).at(3, 4, 5, 123_456_789);
assert_eq!(dt1.subsec_nanosecond(), 123_456_789);
let dt2 = dt1.with().millisecond(333).build()?;
assert_eq!(dt2.subsec_nanosecond(), 333_456_789);
§Example: nanoseconds from a timestamp

This shows how the fractional nanosecond part of a DateTime value manifests from a specific timestamp.

use jiff::{civil, Timestamp};

// 1,234 nanoseconds after the Unix epoch.
let zdt = Timestamp::new(0, 1_234)?.intz("UTC")?;
let dt = zdt.datetime();
assert_eq!(dt.subsec_nanosecond(), 1_234);

// 1,234 nanoseconds before the Unix epoch.
let zdt = Timestamp::new(0, -1_234)?.intz("UTC")?;
let dt = zdt.datetime();
// The nanosecond is equal to `1_000_000_000 - 1_234`.
assert_eq!(dt.subsec_nanosecond(), 999998766);
// Looking at the other components of the time value might help.
assert_eq!(dt.hour(), 23);
assert_eq!(dt.minute(), 59);
assert_eq!(dt.second(), 59);
source

pub fn weekday(self) -> Weekday

Returns the weekday corresponding to this datetime.

§Example
use jiff::civil::{Weekday, date};

// The Unix epoch was on a Thursday.
let dt = date(1970, 1, 1).at(7, 30, 0, 0);
assert_eq!(dt.weekday(), Weekday::Thursday);
// One can also get the weekday as an offset in a variety of schemes.
assert_eq!(dt.weekday().to_monday_zero_offset(), 3);
assert_eq!(dt.weekday().to_monday_one_offset(), 4);
assert_eq!(dt.weekday().to_sunday_zero_offset(), 4);
assert_eq!(dt.weekday().to_sunday_one_offset(), 5);
source

pub fn day_of_year(self) -> i16

Returns the ordinal day of the year that this datetime resides in.

For leap years, this always returns a value in the range 1..=366. Otherwise, the value is in the range 1..=365.

§Example
use jiff::civil::date;

let dt = date(2006, 8, 24).at(7, 30, 0, 0);
assert_eq!(dt.day_of_year(), 236);

let dt = date(2023, 12, 31).at(7, 30, 0, 0);
assert_eq!(dt.day_of_year(), 365);

let dt = date(2024, 12, 31).at(7, 30, 0, 0);
assert_eq!(dt.day_of_year(), 366);
source

pub fn day_of_year_no_leap(self) -> Option<i16>

Returns the ordinal day of the year that this datetime resides in, but ignores leap years.

That is, the range of possible values returned by this routine is 1..=365, even if this date resides in a leap year. If this date is February 29, then this routine returns None.

The value 365 always corresponds to the last day in the year, December 31, even for leap years.

§Example
use jiff::civil::date;

let dt = date(2006, 8, 24).at(7, 30, 0, 0);
assert_eq!(dt.day_of_year_no_leap(), Some(236));

let dt = date(2023, 12, 31).at(7, 30, 0, 0);
assert_eq!(dt.day_of_year_no_leap(), Some(365));

let dt = date(2024, 12, 31).at(7, 30, 0, 0);
assert_eq!(dt.day_of_year_no_leap(), Some(365));

let dt = date(2024, 2, 29).at(7, 30, 0, 0);
assert_eq!(dt.day_of_year_no_leap(), None);
source

pub fn start_of_day(&self) -> DateTime

Returns the beginning of the day that this datetime resides in.

That is, the datetime returned always keeps the same date, but its time is always 00:00:00 (midnight).

§Example
use jiff::civil::date;

let dt = date(2024, 7, 3).at(7, 30, 10, 123_456_789);
assert_eq!(dt.start_of_day(), date(2024, 7, 3).at(0, 0, 0, 0));
source

pub fn end_of_day(&self) -> DateTime

Returns the end of the day that this datetime resides in.

That is, the datetime returned always keeps the same date, but its time is always 23:59:59.999999999.

§Example
use jiff::civil::date;

let dt = date(2024, 7, 3).at(7, 30, 10, 123_456_789);
assert_eq!(
    dt.end_of_day(),
    date(2024, 7, 3).at(23, 59, 59, 999_999_999),
);
source

pub fn first_of_month(self) -> DateTime

Returns the first date of the month that this datetime resides in.

The time in the datetime returned remains unchanged.

§Example
use jiff::civil::date;

let dt = date(2024, 2, 29).at(7, 30, 0, 0);
assert_eq!(dt.first_of_month(), date(2024, 2, 1).at(7, 30, 0, 0));
source

pub fn last_of_month(self) -> DateTime

Returns the last date of the month that this datetime resides in.

The time in the datetime returned remains unchanged.

§Example
use jiff::civil::date;

let dt = date(2024, 2, 5).at(7, 30, 0, 0);
assert_eq!(dt.last_of_month(), date(2024, 2, 29).at(7, 30, 0, 0));
source

pub fn days_in_month(self) -> i8

Returns the total number of days in the the month in which this datetime resides.

This is guaranteed to always return one of the following values, depending on the year and the month: 28, 29, 30 or 31.

§Example
use jiff::civil::date;

let dt = date(2024, 2, 10).at(7, 30, 0, 0);
assert_eq!(dt.days_in_month(), 29);

let dt = date(2023, 2, 10).at(7, 30, 0, 0);
assert_eq!(dt.days_in_month(), 28);

let dt = date(2024, 8, 15).at(7, 30, 0, 0);
assert_eq!(dt.days_in_month(), 31);
source

pub fn first_of_year(self) -> DateTime

Returns the first date of the year that this datetime resides in.

The time in the datetime returned remains unchanged.

§Example
use jiff::civil::date;

let dt = date(2024, 2, 29).at(7, 30, 0, 0);
assert_eq!(dt.first_of_year(), date(2024, 1, 1).at(7, 30, 0, 0));
source

pub fn last_of_year(self) -> DateTime

Returns the last date of the year that this datetime resides in.

The time in the datetime returned remains unchanged.

§Example
use jiff::civil::date;

let dt = date(2024, 2, 5).at(7, 30, 0, 0);
assert_eq!(dt.last_of_year(), date(2024, 12, 31).at(7, 30, 0, 0));
source

pub fn days_in_year(self) -> i16

Returns the total number of days in the the year in which this datetime resides.

This is guaranteed to always return either 365 or 366.

§Example
use jiff::civil::date;

let dt = date(2024, 7, 10).at(7, 30, 0, 0);
assert_eq!(dt.days_in_year(), 366);

let dt = date(2023, 7, 10).at(7, 30, 0, 0);
assert_eq!(dt.days_in_year(), 365);
source

pub fn in_leap_year(self) -> bool

Returns true if and only if the year in which this datetime resides is a leap year.

§Example
use jiff::civil::date;

assert!(date(2024, 1, 1).at(7, 30, 0, 0).in_leap_year());
assert!(!date(2023, 12, 31).at(7, 30, 0, 0).in_leap_year());
source

pub fn tomorrow(self) -> Result<DateTime, Error>

Returns the datetime with a date immediately following this one.

The time in the datetime returned remains unchanged.

§Errors

This returns an error when this datetime’s date is the maximum value.

§Example
use jiff::civil::{DateTime, date};

let dt = date(2024, 2, 28).at(7, 30, 0, 0);
assert_eq!(dt.tomorrow()?, date(2024, 2, 29).at(7, 30, 0, 0));

// The max doesn't have a tomorrow.
assert!(DateTime::MAX.tomorrow().is_err());
source

pub fn yesterday(self) -> Result<DateTime, Error>

Returns the datetime with a date immediately preceding this one.

The time in the datetime returned remains unchanged.

§Errors

This returns an error when this datetime’s date is the minimum value.

§Example
use jiff::civil::{DateTime, date};

let dt = date(2024, 3, 1).at(7, 30, 0, 0);
assert_eq!(dt.yesterday()?, date(2024, 2, 29).at(7, 30, 0, 0));

// The min doesn't have a yesterday.
assert!(DateTime::MIN.yesterday().is_err());
source

pub fn nth_weekday_of_month( self, nth: i8, weekday: Weekday, ) -> Result<DateTime, Error>

Returns the “nth” weekday from the beginning or end of the month in which this datetime resides.

The nth parameter can be positive or negative. A positive value computes the “nth” weekday from the beginning of the month. A negative value computes the “nth” weekday from the end of the month. So for example, use -1 to “find the last weekday” in this date’s month.

The time in the datetime returned remains unchanged.

§Errors

This returns an error when nth is 0, or if it is 5 or -5 and there is no 5th weekday from the beginning or end of the month.

§Example

This shows how to get the nth weekday in a month, starting from the beginning of the month:

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

let dt = date(2017, 3, 1).at(7, 30, 0, 0);
let second_friday = dt.nth_weekday_of_month(2, Weekday::Friday)?;
assert_eq!(second_friday, date(2017, 3, 10).at(7, 30, 0, 0));

This shows how to do the reverse of the above. That is, the nth last weekday in a month:

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

let dt = date(2024, 3, 1).at(7, 30, 0, 0);
let last_thursday = dt.nth_weekday_of_month(-1, Weekday::Thursday)?;
assert_eq!(last_thursday, date(2024, 3, 28).at(7, 30, 0, 0));
let second_last_thursday = dt.nth_weekday_of_month(
    -2,
    Weekday::Thursday,
)?;
assert_eq!(second_last_thursday, date(2024, 3, 21).at(7, 30, 0, 0));

This routine can return an error if there isn’t an nth weekday for this month. For example, March 2024 only has 4 Mondays:

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

let dt = date(2024, 3, 25).at(7, 30, 0, 0);
let fourth_monday = dt.nth_weekday_of_month(4, Weekday::Monday)?;
assert_eq!(fourth_monday, date(2024, 3, 25).at(7, 30, 0, 0));
// There is no 5th Monday.
assert!(dt.nth_weekday_of_month(5, Weekday::Monday).is_err());
// Same goes for counting backwards.
assert!(dt.nth_weekday_of_month(-5, Weekday::Monday).is_err());
source

pub fn nth_weekday(self, nth: i32, weekday: Weekday) -> Result<DateTime, Error>

Returns the “nth” weekday from this datetime, not including itself.

The nth parameter can be positive or negative. A positive value computes the “nth” weekday starting at the day after this date and going forwards in time. A negative value computes the “nth” weekday starting at the day before this date and going backwards in time.

For example, if this datetime’s weekday is a Sunday and the first Sunday is asked for (that is, dt.nth_weekday(1, Weekday::Sunday)), then the result is a week from this datetime corresponding to the following Sunday.

The time in the datetime returned remains unchanged.

§Errors

This returns an error when nth is 0, or if it would otherwise result in a date that overflows the minimum/maximum values of DateTime.

§Example

This example shows how to find the “nth” weekday going forwards in time:

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

// Use a Sunday in March as our start date.
let dt = date(2024, 3, 10).at(7, 30, 0, 0);
assert_eq!(dt.weekday(), Weekday::Sunday);

// The first next Monday is tomorrow!
let next_monday = dt.nth_weekday(1, Weekday::Monday)?;
assert_eq!(next_monday, date(2024, 3, 11).at(7, 30, 0, 0));

// But the next Sunday is a week away, because this doesn't
// include the current weekday.
let next_sunday = dt.nth_weekday(1, Weekday::Sunday)?;
assert_eq!(next_sunday, date(2024, 3, 17).at(7, 30, 0, 0));

// "not this Thursday, but next Thursday"
let next_next_thursday = dt.nth_weekday(2, Weekday::Thursday)?;
assert_eq!(next_next_thursday, date(2024, 3, 21).at(7, 30, 0, 0));

This example shows how to find the “nth” weekday going backwards in time:

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

// Use a Sunday in March as our start date.
let dt = date(2024, 3, 10).at(7, 30, 0, 0);
assert_eq!(dt.weekday(), Weekday::Sunday);

// "last Saturday" was yesterday!
let last_saturday = dt.nth_weekday(-1, Weekday::Saturday)?;
assert_eq!(last_saturday, date(2024, 3, 9).at(7, 30, 0, 0));

// "last Sunday" was a week ago.
let last_sunday = dt.nth_weekday(-1, Weekday::Sunday)?;
assert_eq!(last_sunday, date(2024, 3, 3).at(7, 30, 0, 0));

// "not last Thursday, but the one before"
let prev_prev_thursday = dt.nth_weekday(-2, Weekday::Thursday)?;
assert_eq!(prev_prev_thursday, date(2024, 2, 29).at(7, 30, 0, 0));

This example shows that overflow results in an error in either direction:

use jiff::civil::{DateTime, Weekday};

let dt = DateTime::MAX;
assert_eq!(dt.weekday(), Weekday::Friday);
assert!(dt.nth_weekday(1, Weekday::Saturday).is_err());

let dt = DateTime::MIN;
assert_eq!(dt.weekday(), Weekday::Monday);
assert!(dt.nth_weekday(-1, Weekday::Sunday).is_err());
§Example: the start of Israeli summer time

Israeli law says (at present, as of 2024-03-11) that DST or “summer time” starts on the Friday before the last Sunday in March. We can find that date using both nth_weekday and DateTime::nth_weekday_of_month:

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

let march = date(2024, 3, 1).at(0, 0, 0, 0);
let last_sunday = march.nth_weekday_of_month(-1, Weekday::Sunday)?;
let dst_starts_on = last_sunday.nth_weekday(-1, Weekday::Friday)?;
assert_eq!(dst_starts_on, date(2024, 3, 29).at(0, 0, 0, 0));
§Example: getting the start of the week

Given a date, one can use nth_weekday to determine the start of the week in which the date resides in. This might vary based on whether the weeks start on Sunday or Monday. This example shows how to handle both.

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

let dt = date(2024, 3, 15).at(7, 30, 0, 0);
// For weeks starting with Sunday.
let start_of_week = dt.tomorrow()?.nth_weekday(-1, Weekday::Sunday)?;
assert_eq!(start_of_week, date(2024, 3, 10).at(7, 30, 0, 0));
// For weeks starting with Monday.
let start_of_week = dt.tomorrow()?.nth_weekday(-1, Weekday::Monday)?;
assert_eq!(start_of_week, date(2024, 3, 11).at(7, 30, 0, 0));

In the above example, we first get the date after the current one because nth_weekday does not consider itself when counting. This works as expected even at the boundaries of a week:

use jiff::civil::{Time, Weekday, date};

// The start of the week.
let dt = date(2024, 3, 10).at(0, 0, 0, 0);
let start_of_week = dt.tomorrow()?.nth_weekday(-1, Weekday::Sunday)?;
assert_eq!(start_of_week, date(2024, 3, 10).at(0, 0, 0, 0));
// The end of the week.
let dt = date(2024, 3, 16).at(23, 59, 59, 999_999_999);
let start_of_week = dt
    .tomorrow()?
    .nth_weekday(-1, Weekday::Sunday)?
    .with().time(Time::midnight()).build()?;
assert_eq!(start_of_week, date(2024, 3, 10).at(0, 0, 0, 0));
source

pub fn date(self) -> Date

Returns the date component of this datetime.

§Example
use jiff::civil::date;

let dt = date(2024, 3, 14).at(18, 45, 0, 0);
assert_eq!(dt.date(), date(2024, 3, 14));
source

pub fn time(self) -> Time

Returns the time component of this datetime.

§Example
use jiff::civil::{date, time};

let dt = date(2024, 3, 14).at(18, 45, 0, 0);
assert_eq!(dt.time(), time(18, 45, 0, 0));
source

pub fn intz(self, time_zone_name: &str) -> Result<Zoned, Error>

Converts a civil datetime to a Zoned datetime by adding the given time zone.

The name given is resolved to a TimeZone by using the default TimeZoneDatabase created by tz::db. Indeed, this is a convenience function for DateTime::to_zoned where the time zone database lookup is done automatically.

In some cases, a civil datetime may be ambiguous in a particular time zone. This routine automatically utilizes the Disambiguation::Compatible strategy for resolving ambiguities. That is, if a civil datetime occurs in a backward transition (called a fold), then the earlier time is selected. Or if a civil datetime occurs in a forward transition (called a gap), then the later time is selected.

To convert a datetime to a Zoned using a different disambiguation strategy, use TimeZone::to_ambiguous_zoned.

§Errors

This returns an error when the given time zone name could not be found in the default time zone database.

This also returns an error if this datetime could not be represented as an instant. This can occur in some cases near the minimum and maximum boundaries of a DateTime.

§Example

This is a simple example of converting a civil datetime (a “wall” or “local” or “naive” datetime) to a datetime that is aware of its time zone:

use jiff::civil::DateTime;

let dt: DateTime = "2024-06-20 15:06".parse()?;
let zdt = dt.intz("America/New_York")?;
assert_eq!(zdt.to_string(), "2024-06-20T15:06:00-04:00[America/New_York]");
§Example: dealing with ambiguity

In the America/New_York time zone, there was a forward transition at 2024-03-10 02:00:00 civil time, and a backward transition at 2024-11-03 01:00:00 civil time. In the former case, a gap was created such that the 2 o’clock hour never appeared on clocks for folks in the America/New_York time zone. In the latter case, a fold was created such that the 1 o’clock hour was repeated. Thus, March 10, 2024 in New York was 23 hours long, while November 3, 2024 in New York was 25 hours long.

This example shows how datetimes in these gaps and folds are resolved by default:

use jiff::civil::DateTime;

// This is the gap, where by default we select the later time.
let dt: DateTime = "2024-03-10 02:30".parse()?;
let zdt = dt.intz("America/New_York")?;
assert_eq!(zdt.to_string(), "2024-03-10T03:30:00-04:00[America/New_York]");

// This is the fold, where by default we select the earlier time.
let dt: DateTime = "2024-11-03 01:30".parse()?;
let zdt = dt.intz("America/New_York")?;
// Since this is a fold, the wall clock time is repeated. It might be
// hard to see that this is the earlier time, but notice the offset:
// it is the offset for DST time in New York. The later time, or the
// repetition of the 1 o'clock hour, would occur in standard time,
// which is an offset of -05 for New York.
assert_eq!(zdt.to_string(), "2024-11-03T01:30:00-04:00[America/New_York]");
§Example: errors

This routine can return an error when the time zone is unrecognized:

use jiff::civil::date;

let dt = date(2024, 6, 20).at(15, 6, 0, 0);
assert!(dt.intz("does not exist").is_err());

Note that even if a time zone exists in, say, the IANA database, there may have been a problem reading it from your system’s installation of that database. To see what wrong, enable Jiff’s logging crate feature and install a logger. If there was a failure, then a WARN level log message should be emitted.

This routine can also fail if this datetime cannot be represented within the allowable timestamp limits:

use jiff::{civil::DateTime, tz::{Offset, TimeZone}};

let dt = DateTime::MAX;
// All errors because the combination of the offset and the datetime
// isn't enough to fit into timestamp limits.
assert!(dt.intz("UTC").is_err());
assert!(dt.intz("America/New_York").is_err());
assert!(dt.intz("Australia/Tasmania").is_err());
// In fact, the only valid offset one can use to turn the maximum civil
// datetime into a Zoned value is the maximum offset:
let tz = Offset::from_seconds(93_599).unwrap().to_time_zone();
assert!(dt.to_zoned(tz).is_ok());
// One second less than the maximum offset results in a failure at the
// maximum datetime boundary.
let tz = Offset::from_seconds(93_598).unwrap().to_time_zone();
assert!(dt.to_zoned(tz).is_err());

This behavior exists because it guarantees that every possible Zoned value can be converted into a civil datetime, but not every possible combination of civil datetime and offset can be converted into a Zoned value. There isn’t a way to make every possible roundtrip lossless in both directions, so Jiff chooses to ensure that there is always a way to convert a Zoned instant to a human readable wall clock time.

source

pub fn to_zoned(self, tz: TimeZone) -> Result<Zoned, Error>

Converts a civil datetime to a Zoned datetime by adding the given TimeZone.

In some cases, a civil datetime may be ambiguous in a particular time zone. This routine automatically utilizes the Disambiguation::Compatible strategy for resolving ambiguities. That is, if a civil datetime occurs in a backward transition (called a fold), then the earlier time is selected. Or if a civil datetime occurs in a forward transition (called a gap), then the later time is selected.

To convert a datetime to a Zoned using a different disambiguation strategy, use TimeZone::to_ambiguous_zoned.

In the common case of a time zone being represented as a name string, like Australia/Tasmania, consider using DateTime::to_zoned instead.

§Errors

This returns an error if this datetime could not be represented as an instant. This can occur in some cases near the minimum and maximum boundaries of a DateTime.

§Example

This example shows how to created a zoned value with a fixed time zone offset:

use jiff::{civil::date, tz::{self, TimeZone}};

let tz = TimeZone::fixed(tz::offset(-4));
let zdt = date(2024, 6, 20).at(17, 3, 0, 0).to_zoned(tz)?;
// A time zone annotation is still included in the printable version
// of the Zoned value, but it is fixed to a particular offset.
assert_eq!(zdt.to_string(), "2024-06-20T17:03:00-04:00[-04:00]");
§Example: POSIX time zone strings

And this example shows how to create a time zone from a POSIX time zone string that describes the transition to and from daylight saving time for America/St_Johns. In particular, this rule uses non-zero minutes, which is atypical.

use jiff::{civil::date, tz::TimeZone};

let tz = TimeZone::posix("NST3:30NDT,M3.2.0,M11.1.0")?;
let zdt = date(2024, 6, 20).at(17, 3, 0, 0).to_zoned(tz)?;
// There isn't any agreed upon mechanism for transmitting a POSIX time
// zone string within an RFC 9557 TZ annotation, so Jiff just emits the
// offset. In practice, POSIX TZ strings are rarely user facing anyway.
// (They are still in widespread use as an implementation detail of the
// IANA Time Zone Database however.)
assert_eq!(zdt.to_string(), "2024-06-20T17:03:00-02:30[-02:30]");
source

pub fn checked_add<A: Into<DateTimeArithmetic>>( self, duration: A, ) -> Result<DateTime, Error>

Add the given span of time to this datetime. If the sum would overflow the minimum or maximum datetime values, then an error is returned.

This operation accepts three different duration types: Span, SignedDuration or std::time::Duration. This is achieved via From trait implementations for the DateTimeArithmetic type.

§Properties

This routine is not reversible because some additions may be ambiguous. For example, adding 1 month to the datetime 2024-03-31T00:00:00 will produce 2024-04-30T00:00:00 since April has only 30 days in a month. Moreover, subtracting 1 month from 2024-04-30T00:00:00 will produce 2024-03-30T00:00:00, which is not the date we started with.

If spans of time are limited to units of days (or less), then this routine is reversible. This also implies that all operations with a SignedDuration or a std::time::Duration are reversible.

§Errors

If the span added to this datetime would result in a datetime that exceeds the range of a DateTime, then this will return an error.

§Example

This shows a few examples of adding spans of time to various dates. We make use of the ToSpan trait for convenient creation of spans.

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

let dt = date(1995, 12, 7).at(3, 24, 30, 3_500);
let got = dt.checked_add(20.years().months(4).nanoseconds(500))?;
assert_eq!(got, date(2016, 4, 7).at(3, 24, 30, 4_000));

let dt = date(2019, 1, 31).at(15, 30, 0, 0);
let got = dt.checked_add(1.months())?;
assert_eq!(got, date(2019, 2, 28).at(15, 30, 0, 0));
§Example: available via addition operator

This routine can be used via the + operator. Note though that if it fails, it will result in a panic.

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

let dt = date(1995, 12, 7).at(3, 24, 30, 3_500);
let got = dt + 20.years().months(4).nanoseconds(500);
assert_eq!(got, date(2016, 4, 7).at(3, 24, 30, 4_000));
§Example: negative spans are supported
use jiff::{civil::date, ToSpan};

let dt = date(2024, 3, 31).at(19, 5, 59, 999_999_999);
assert_eq!(
    dt.checked_add(-1.months())?,
    date(2024, 2, 29).at(19, 5, 59, 999_999_999),
);
§Example: error on overflow
use jiff::{civil::date, ToSpan};

let dt = date(2024, 3, 31).at(13, 13, 13, 13);
assert!(dt.checked_add(9000.years()).is_err());
assert!(dt.checked_add(-19000.years()).is_err());
§Example: adding absolute durations

This shows how to add signed and unsigned absolute durations to a DateTime.

use std::time::Duration;

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

let dt = date(2024, 2, 29).at(0, 0, 0, 0);

let dur = SignedDuration::from_hours(25);
assert_eq!(dt.checked_add(dur)?, date(2024, 3, 1).at(1, 0, 0, 0));
assert_eq!(dt.checked_add(-dur)?, date(2024, 2, 27).at(23, 0, 0, 0));

let dur = Duration::from_secs(25 * 60 * 60);
assert_eq!(dt.checked_add(dur)?, date(2024, 3, 1).at(1, 0, 0, 0));
// One cannot negate an unsigned duration,
// but you can subtract it!
assert_eq!(dt.checked_sub(dur)?, date(2024, 2, 27).at(23, 0, 0, 0));
source

pub fn checked_sub<A: Into<DateTimeArithmetic>>( self, duration: A, ) -> Result<DateTime, Error>

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

§Errors

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

§Example

This routine can be used via the - operator. Note though that if it fails, it will result in a panic.

use std::time::Duration;

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

let dt = date(1995, 12, 7).at(3, 24, 30, 3_500);
assert_eq!(
    dt - 20.years().months(4).nanoseconds(500),
    date(1975, 8, 7).at(3, 24, 30, 3_000),
);

let dur = SignedDuration::new(24 * 60 * 60, 3_500);
assert_eq!(dt - dur, date(1995, 12, 6).at(3, 24, 30, 0));

let dur = Duration::new(24 * 60 * 60, 3_500);
assert_eq!(dt - dur, date(1995, 12, 6).at(3, 24, 30, 0));
source

pub fn saturating_add<A: Into<DateTimeArithmetic>>( self, duration: A, ) -> DateTime

This routine is identical to DateTime::checked_add, except the result saturates on overflow. That is, instead of overflow, either DateTime::MIN or DateTime::MAX is returned.

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

let dt = date(2024, 3, 31).at(13, 13, 13, 13);
assert_eq!(DateTime::MAX, dt.saturating_add(9000.years()));
assert_eq!(DateTime::MIN, dt.saturating_add(-19000.years()));
assert_eq!(DateTime::MAX, dt.saturating_add(SignedDuration::MAX));
assert_eq!(DateTime::MIN, dt.saturating_add(SignedDuration::MIN));
assert_eq!(DateTime::MAX, dt.saturating_add(std::time::Duration::MAX));
source

pub fn saturating_sub<A: Into<DateTimeArithmetic>>( self, duration: A, ) -> DateTime

This routine is identical to DateTime::saturating_add with the span parameter negated.

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

let dt = date(2024, 3, 31).at(13, 13, 13, 13);
assert_eq!(DateTime::MIN, dt.saturating_sub(19000.years()));
assert_eq!(DateTime::MAX, dt.saturating_sub(-9000.years()));
assert_eq!(DateTime::MIN, dt.saturating_sub(SignedDuration::MAX));
assert_eq!(DateTime::MAX, dt.saturating_sub(SignedDuration::MIN));
assert_eq!(DateTime::MIN, dt.saturating_sub(std::time::Duration::MAX));
source

pub fn until<A: Into<DateTimeDifference>>(self, other: A) -> Result<Span, Error>

Returns a span representing the elapsed time from this datetime until the given other datetime.

When other occurs before this datetime, then the span returned will be negative.

Depending on the input provided, the span returned is rounded. It may also be balanced up to bigger units than the default. By default, the span returned is balanced such that the biggest possible unit is days.

This operation is configured by providing a DateTimeDifference value. Since this routine accepts anything that implements Into<DateTimeDifference>, once can pass a DateTime directly. One can also pass a (Unit, DateTime), where Unit is treated as DateTimeDifference::largest.

§Properties

It is guaranteed that if the returned span is subtracted from other, and if no rounding is requested, and if the largest unit requested is at most Unit::Day, then the original datetime will be returned.

This routine is equivalent to self.since(other).map(|span| -span) if no rounding options are set. If rounding options are set, then it’s equivalent to self.since(other_without_rounding_options).map(|span| -span), followed by a call to Span::round with the appropriate rounding options set. This is because the negation of a span can result in different rounding results depending on the rounding mode.

§Errors

An error can occur in some cases when the requested configuration would result in a span that is beyond allowable limits. For example, the nanosecond component of a span cannot the span of time between the minimum and maximum datetime supported by Jiff. Therefore, if one requests a span with its largest unit set to Unit::Nanosecond, then it’s possible for this routine to fail.

It is guaranteed that if one provides a datetime with the default DateTimeDifference configuration, then this routine will never fail.

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

let earlier = date(2006, 8, 24).at(22, 30, 0, 0);
let later = date(2019, 1, 31).at(21, 0, 0, 0);
assert_eq!(earlier.until(later)?, 4542.days().hours(22).minutes(30));

// Flipping the dates is fine, but you'll get a negative span.
assert_eq!(later.until(earlier)?, -4542.days().hours(22).minutes(30));
§Example: using bigger units

This example shows how to expand the span returned to bigger units. This makes use of a From<(Unit, DateTime)> for DateTimeDifference trait implementation.

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

let dt1 = date(1995, 12, 07).at(3, 24, 30, 3500);
let dt2 = date(2019, 01, 31).at(15, 30, 0, 0);

// The default limits durations to using "days" as the biggest unit.
let span = dt1.until(dt2)?;
assert_eq!(span.to_string(), "P8456dT12h5m29.9999965s");

// But we can ask for units all the way up to years.
let span = dt1.until((Unit::Year, dt2))?;
assert_eq!(span.to_string(), "P23y1m24dT12h5m29.9999965s");
§Example: rounding the result

This shows how one might find the difference between two datetimes and have the result rounded such that sub-seconds are removed.

In this case, we need to hand-construct a DateTimeDifference in order to gain full configurability.

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

let dt1 = date(1995, 12, 07).at(3, 24, 30, 3500);
let dt2 = date(2019, 01, 31).at(15, 30, 0, 0);

let span = dt1.until(
    DateTimeDifference::from(dt2).smallest(Unit::Second),
)?;
assert_eq!(span, 8456.days().hours(12).minutes(5).seconds(29));

// We can combine smallest and largest units too!
let span = dt1.until(
    DateTimeDifference::from(dt2)
        .smallest(Unit::Second)
        .largest(Unit::Year),
)?;
assert_eq!(span, 23.years().months(1).days(24).hours(12).minutes(5).seconds(29));
§Example: units biggers than days inhibit reversibility

If you ask for units bigger than days, then subtracting the span returned from the other datetime is not guaranteed to result in the original datetime. For example:

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

let dt1 = date(2024, 3, 2).at(0, 0, 0, 0);
let dt2 = date(2024, 5, 1).at(0, 0, 0, 0);

let span = dt1.until((Unit::Month, dt2))?;
assert_eq!(span, 1.month().days(29));
let maybe_original = dt2.checked_sub(span)?;
// Not the same as the original datetime!
assert_eq!(maybe_original, date(2024, 3, 3).at(0, 0, 0, 0));

// But in the default configuration, days are always the biggest unit
// and reversibility is guaranteed.
let span = dt1.until(dt2)?;
assert_eq!(span, 60.days());
let is_original = dt2.checked_sub(span)?;
assert_eq!(is_original, dt1);

This occurs because span are added as if by adding the biggest units first, and then the smaller units. Because months vary in length, their meaning can change depending on how the span is added. In this case, adding one month to 2024-03-02 corresponds to 31 days, but subtracting one month from 2024-05-01 corresponds to 30 days.

source

pub fn since<A: Into<DateTimeDifference>>(self, other: A) -> Result<Span, Error>

This routine is identical to DateTime::until, but the order of the parameters is flipped.

§Errors

This has the same error conditions as DateTime::until.

§Example

This routine can be used via the - operator. Since the default configuration is used and because a Span can represent the difference between any two possible datetimes, it will never panic.

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

let earlier = date(2006, 8, 24).at(22, 30, 0, 0);
let later = date(2019, 1, 31).at(21, 0, 0, 0);
assert_eq!(later - earlier, 4542.days().hours(22).minutes(30));
source

pub fn duration_until(self, other: DateTime) -> SignedDuration

Returns an absolute duration representing the elapsed time from this datetime until the given other datetime.

When other occurs before this datetime, then the duration returned will be negative.

Unlike DateTime::until, this returns a duration corresponding to a 96-bit integer of nanoseconds between two datetimes.

§Fallibility

This routine never panics or returns an error. Since there are no configuration options that can be incorrectly provided, no error is possible when calling this routine. In contrast, DateTime::until can return an error in some cases due to misconfiguration. But like this routine, DateTime::until never panics or returns an error in its default configuration.

§When should I use this versus DateTime::until?

See the type documentation for SignedDuration for the section on when one should use Span and when one should use SignedDuration. In short, use Span (and therefore DateTime::until) unless you have a specific reason to do otherwise.

§Example
use jiff::{civil::date, SignedDuration};

let earlier = date(2006, 8, 24).at(22, 30, 0, 0);
let later = date(2019, 1, 31).at(21, 0, 0, 0);
assert_eq!(
    earlier.duration_until(later),
    SignedDuration::from_hours(4542 * 24)
    + SignedDuration::from_hours(22)
    + SignedDuration::from_mins(30),
);
// Flipping the datetimes is fine, but you'll get a negative duration.
assert_eq!(
    later.duration_until(earlier),
    -SignedDuration::from_hours(4542 * 24)
    - SignedDuration::from_hours(22)
    - SignedDuration::from_mins(30),
);
§Example: difference with DateTime::until

The main difference between this routine and DateTime::until is that the latter can return units other than a 96-bit integer of nanoseconds. While a 96-bit integer of nanoseconds can be converted into other units like hours, this can only be done for uniform units. (Uniform units are units for which each individual unit always corresponds to the same elapsed time regardless of the datetime it is relative to.) This can’t be done for units like years or months.

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

let dt1 = date(2024, 1, 1).at(0, 0, 0, 0);
let dt2 = date(2025, 4, 1).at(0, 0, 0, 0);

let span = dt1.until((Unit::Year, dt2))?;
assert_eq!(span, 1.year().months(3));

let duration = dt1.duration_until(dt2);
assert_eq!(duration, SignedDuration::from_hours(456 * 24));
// There's no way to extract years or months from the signed
// duration like one might extract hours (because every hour
// is the same length). Instead, you actually have to convert
// it to a span and then balance it by providing a relative date!
let options = SpanRound::new().largest(Unit::Year).relative(dt1);
let span = Span::try_from(duration)?.round(options)?;
assert_eq!(span, 1.year().months(3));
§Example: getting an unsigned duration

If you’re looking to find the duration between two datetimes as a std::time::Duration, you’ll need to use this method to get a SignedDuration and then convert it to a std::time::Duration:

use std::time::Duration;

use jiff::civil::date;

let dt1 = date(2024, 7, 1).at(0, 0, 0, 0);
let dt2 = date(2024, 8, 1).at(0, 0, 0, 0);
let duration = Duration::try_from(dt1.duration_until(dt2))?;
assert_eq!(duration, Duration::from_secs(31 * 24 * 60 * 60));

// Note that unsigned durations cannot represent all
// possible differences! If the duration would be negative,
// then the conversion fails:
assert!(Duration::try_from(dt2.duration_until(dt1)).is_err());
source

pub fn duration_since(self, other: DateTime) -> SignedDuration

This routine is identical to DateTime::duration_until, but the order of the parameters is flipped.

§Example
use jiff::{civil::date, SignedDuration};

let earlier = date(2006, 8, 24).at(22, 30, 0, 0);
let later = date(2019, 1, 31).at(21, 0, 0, 0);
assert_eq!(
    later.duration_since(earlier),
    SignedDuration::from_hours(4542 * 24)
    + SignedDuration::from_hours(22)
    + SignedDuration::from_mins(30),
);
source

pub fn round<R: Into<DateTimeRound>>( self, options: R, ) -> Result<DateTime, Error>

Rounds this datetime according to the DateTimeRound configuration given.

The principal option is DateTimeRound::smallest, which allows one to configure the smallest units in the returned datetime. Rounding is what determines whether that unit should keep its current value or whether it should be incremented. Moreover, the amount it should be incremented can be configured via DateTimeRound::increment. Finally, the rounding strategy itself can be configured via DateTimeRound::mode.

Note that this routine is generic and accepts anything that implements Into<DateTimeRound>. Some notable implementations are:

  • From<Unit> for DateTimeRound, which will automatically create a DateTimeRound::new().smallest(unit) from the unit provided.
  • From<(Unit, i64)> for DateTimeRound, which will automatically create a DateTimeRound::new().smallest(unit).increment(number) from the unit and increment provided.
§Errors

This returns an error if the smallest unit configured on the given DateTimeRound is bigger than days. An error is also returned if the rounding increment is greater than 1 when the units are days. (Currently, rounding to the nearest week, month or year is not supported.)

When the smallest unit is less than days, the rounding increment must divide evenly into the next highest unit after the smallest unit configured (and must not be equivalent to it). For example, if the smallest unit is Unit::Nanosecond, then some of the valid values for the rounding increment are 1, 2, 4, 5, 100 and 500. Namely, any integer that divides evenly into 1,000 nanoseconds since there are 1,000 nanoseconds in the next highest unit (microseconds).

This can also return an error in some cases where rounding would require arithmetic that exceeds the maximum datetime value.

§Example

This is a basic example that demonstrates rounding a datetime to the nearest day. This also demonstrates calling this method with the smallest unit directly, instead of constructing a DateTimeRound manually.

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

let dt = date(2024, 6, 19).at(15, 0, 0, 0);
assert_eq!(dt.round(Unit::Day)?, date(2024, 6, 20).at(0, 0, 0, 0));
let dt = date(2024, 6, 19).at(10, 0, 0, 0);
assert_eq!(dt.round(Unit::Day)?, date(2024, 6, 19).at(0, 0, 0, 0));
§Example: changing the rounding mode

The default rounding mode is RoundMode::HalfExpand, which breaks ties by rounding away from zero. But other modes like RoundMode::Trunc can be used too:

use jiff::{civil::{DateTimeRound, date}, RoundMode, Unit};

let dt = date(2024, 6, 19).at(15, 0, 0, 0);
assert_eq!(dt.round(Unit::Day)?, date(2024, 6, 20).at(0, 0, 0, 0));
// The default will round up to the next day for any time past noon,
// but using truncation rounding will always round down.
assert_eq!(
    dt.round(
        DateTimeRound::new().smallest(Unit::Day).mode(RoundMode::Trunc),
    )?,
    date(2024, 6, 19).at(0, 0, 0, 0),
);
§Example: rounding to the nearest 5 minute increment
use jiff::{civil::date, Unit};

// rounds down
let dt = date(2024, 6, 19).at(15, 27, 29, 999_999_999);
assert_eq!(
    dt.round((Unit::Minute, 5))?,
    date(2024, 6, 19).at(15, 25, 0, 0),
);
// rounds up
let dt = date(2024, 6, 19).at(15, 27, 30, 0);
assert_eq!(
    dt.round((Unit::Minute, 5))?,
    date(2024, 6, 19).at(15, 30, 0, 0),
);
§Example: overflow error

This example demonstrates that it’s possible for this operation to result in an error from datetime arithmetic overflow.

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

let dt = DateTime::MAX;
assert!(dt.round(Unit::Day).is_err());

This occurs because rounding to the nearest day for the maximum datetime would result in rounding up to the next day. But the next day is greater than the maximum, and so this returns an error.

If one were to use a rounding mode like RoundMode::Trunc (which will never round up), always set a correct increment and always used units less than or equal to days, then this routine is guaranteed to never fail:

use jiff::{civil::{DateTime, DateTimeRound, date}, RoundMode, Unit};

let round = DateTimeRound::new()
    .smallest(Unit::Day)
    .mode(RoundMode::Trunc);
assert_eq!(
    DateTime::MAX.round(round)?,
    date(9999, 12, 31).at(0, 0, 0, 0),
);
assert_eq!(
    DateTime::MIN.round(round)?,
    date(-9999, 1, 1).at(0, 0, 0, 0),
);
source

pub fn series(self, period: Span) -> DateTimeSeries

Return an iterator of periodic datetimes determined by the given span.

The given span may be negative, in which case, the iterator will move backwards through time. The iterator won’t stop until either the span itself overflows, or it would otherwise exceed the minimum or maximum DateTime value.

§Example: when to check a glucose monitor

When my cat had diabetes, my veterinarian installed a glucose monitor and instructed me to scan it about every 5 hours. This example lists all of the times I need to scan it for the 2 days following its installation:

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

let start = datetime(2023, 7, 15, 16, 30, 0, 0);
let end = start.checked_add(2.days())?;
let mut scan_times = vec![];
for dt in start.series(5.hours()).take_while(|&dt| dt <= end) {
    scan_times.push(dt);
}
assert_eq!(scan_times, vec![
    datetime(2023, 7, 15, 16, 30, 0, 0),
    datetime(2023, 7, 15, 21, 30, 0, 0),
    datetime(2023, 7, 16, 2, 30, 0, 0),
    datetime(2023, 7, 16, 7, 30, 0, 0),
    datetime(2023, 7, 16, 12, 30, 0, 0),
    datetime(2023, 7, 16, 17, 30, 0, 0),
    datetime(2023, 7, 16, 22, 30, 0, 0),
    datetime(2023, 7, 17, 3, 30, 0, 0),
    datetime(2023, 7, 17, 8, 30, 0, 0),
    datetime(2023, 7, 17, 13, 30, 0, 0),
]);
source§

impl DateTime

Parsing and formatting using a “printf”-style API.

source

pub fn strptime( format: impl AsRef<[u8]>, input: impl AsRef<[u8]>, ) -> Result<DateTime, Error>

Parses a civil datetime in input matching the given format.

The format string uses a “printf”-style API where conversion specifiers can be used as place holders to match components of a datetime. For details on the specifiers supported, see the fmt::strtime module documentation.

§Errors

This returns an error when parsing failed. This might happen because the format string itself was invalid, or because the input didn’t match the format string.

This also returns an error if there wasn’t sufficient information to construct a civil datetime. For example, if an offset wasn’t parsed.

§Example

This example shows how to parse a civil datetime:

use jiff::civil::DateTime;

let dt = DateTime::strptime("%F %H:%M", "2024-07-14 21:14")?;
assert_eq!(dt.to_string(), "2024-07-14T21:14:00");
source

pub fn strftime<'f, F: 'f + ?Sized + AsRef<[u8]>>( &self, format: &'f F, ) -> Display<'f>

Formats this civil datetime according to the given format.

The format string uses a “printf”-style API where conversion specifiers can be used as place holders to format components of a datetime. For details on the specifiers supported, see the fmt::strtime module documentation.

§Errors and panics

While this routine itself does not error or panic, using the value returned may result in a panic if formatting fails. See the documentation on fmt::strtime::Display for more information.

To format in a way that surfaces errors without panicking, use either fmt::strtime::format or fmt::strtime::BrokenDownTime::format.

§Example

This example shows how to format a civil datetime:

use jiff::civil::date;

let dt = date(2024, 7, 15).at(16, 24, 59, 0);
let string = dt.strftime("%A, %B %e, %Y at %H:%M:%S").to_string();
assert_eq!(string, "Monday, July 15, 2024 at 16:24:59");

Trait Implementations§

source§

impl Add<Duration> for DateTime

Adds an unsigned duration 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: UnsignedDuration) -> DateTime

Performs the + operation. Read more
source§

impl Add<SignedDuration> for DateTime

Adds a signed duration 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: SignedDuration) -> DateTime

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 AddAssign<Duration> for DateTime

Adds an unsigned duration 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: UnsignedDuration)

Performs the += operation. Read more
source§

impl AddAssign<SignedDuration> for DateTime

Adds a signed duration 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: SignedDuration)

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 Clone for DateTime

source§

fn clone(&self) -> DateTime

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 DateTime

Converts a DateTime into a human readable datetime string.

(This Debug representation currently emits the same string as the Display representation, but this is not a guarantee.)

Options currently supported:

§Example

use jiff::civil::date;

let dt = date(2024, 6, 15).at(7, 0, 0, 123_000_000);
assert_eq!(format!("{dt:.6?}"), "2024-06-15T07:00:00.123000");
// Precision values greater than 9 are clamped to 9.
assert_eq!(format!("{dt:.300?}"), "2024-06-15T07:00:00.123000000");
// A precision of 0 implies the entire fractional
// component is always truncated.
assert_eq!(format!("{dt:.0?}"), "2024-06-15T07:00:00");
source§

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

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

impl Default for DateTime

source§

fn default() -> DateTime

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

impl<'de> Deserialize<'de> for DateTime

Available on crate feature serde only.
source§

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

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

impl Display for DateTime

Converts a DateTime into an ISO 8601 compliant string.

Options currently supported:

§Example

use jiff::civil::date;

let dt = date(2024, 6, 15).at(7, 0, 0, 123_000_000);
assert_eq!(format!("{dt:.6}"), "2024-06-15T07:00:00.123000");
// Precision values greater than 9 are clamped to 9.
assert_eq!(format!("{dt:.300}"), "2024-06-15T07:00:00.123000000");
// A precision of 0 implies the entire fractional
// component is always truncated.
assert_eq!(format!("{dt:.0}"), "2024-06-15T07:00:00");
source§

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

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

impl<'a> From<&'a Zoned> for DateTime

Converts a &Zoned to a DateTime.

source§

fn from(zdt: &'a Zoned) -> DateTime

Converts to this type from the input type.
source§

impl From<Date> for DateTime

Converts a Date to a DateTime with the time set to midnight.

source§

fn from(date: Date) -> DateTime

Converts to this type from the input type.
source§

impl From<DateTime> for BrokenDownTime

source§

fn from(dt: DateTime) -> BrokenDownTime

Converts to this type from the input type.
source§

impl From<DateTime> for Date

source§

fn from(dt: DateTime) -> Date

Converts to this type from the input type.
source§

impl From<DateTime> for DateDifference

source§

fn from(dt: DateTime) -> DateDifference

Converts to this type from the input type.
source§

impl From<DateTime> for DateTimeDifference

source§

fn from(dt: DateTime) -> DateTimeDifference

Converts to this type from the input type.
source§

impl From<DateTime> for SpanRelativeTo<'static>

source§

fn from(dt: DateTime) -> SpanRelativeTo<'static>

Converts to this type from the input type.
source§

impl From<DateTime> for Time

source§

fn from(dt: DateTime) -> Time

Converts to this type from the input type.
source§

impl From<DateTime> for TimeDifference

source§

fn from(dt: DateTime) -> TimeDifference

Converts to this type from the input type.
source§

impl From<Zoned> for DateTime

Converts a Zoned to a DateTime.

source§

fn from(zdt: Zoned) -> DateTime

Converts to this type from the input type.
source§

impl FromStr for DateTime

source§

type Err = Error

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

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

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

impl Hash for DateTime

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for DateTime

source§

fn cmp(&self, other: &DateTime) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for DateTime

source§

fn eq(&self, other: &DateTime) -> 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 PartialOrd for DateTime

source§

fn partial_cmp(&self, other: &DateTime) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

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

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

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

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · source§

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

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

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

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
source§

impl Serialize for DateTime

Available on crate feature serde only.
source§

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

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

impl Sub<Duration> for DateTime

Subtracts an unsigned duration 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: UnsignedDuration) -> DateTime

Performs the - operation. Read more
source§

impl Sub<SignedDuration> for DateTime

Subtracts a signed duration 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: SignedDuration) -> DateTime

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 for DateTime

Computes the span of time between two datetimes.

This will return a negative span when the datetime being subtracted is greater.

Since this uses the default configuration for calculating a span between two datetimes (no rounding and largest units is days), this will never panic or fail in any way.

To configure the largest unit or enable rounding, use DateTime::since.

If you need a SignedDuration representing the span between two civil datetimes, then use DateTime::duration_since.

source§

type Output = Span

The resulting type after applying the - operator.
source§

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

Performs the - operation. Read more
source§

impl SubAssign<Duration> for DateTime

Subtracts an unsigned duration 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: UnsignedDuration)

Performs the -= operation. Read more
source§

impl SubAssign<SignedDuration> for DateTime

Subtracts a signed duration 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: SignedDuration)

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 Copy for DateTime

source§

impl Eq for DateTime

source§

impl StructuralPartialEq for DateTime

Auto Trait Implementations§

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 T)

🔬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, 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> 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<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,