jiff::civil

Struct ISOWeekDate

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

A type representing an ISO 8601 week date.

The ISO 8601 week date scheme devises a calendar where days are identified by their year, week number and weekday. All years have either precisely 52 or 53 weeks.

The first week of an ISO 8601 year corresponds to the week containing the first Thursday of the year. For this reason, an ISO 8601 week year can be mismatched with the day’s corresponding Gregorian year. For example, the ISO 8601 week date for 1995-01-01 is 1994-W52-7 (with 7 corresponding to Sunday).

ISO 8601 also considers Monday to be the start of the week, and uses a 1-based numbering system. That is, Monday corresponds to 1 while Sunday corresponds to 7 and is the last day of the week. Weekdays are encapsulated by the Weekday type, which provides routines for easily converting between different schemes (such as weeks where Sunday is the beginning).

§Use case

Some domains use this method of timekeeping. Otherwise, unless you specifically want a week oriented calendar, it’s likely that you’ll never need to care about this type.

§Default value

For convenience, this type implements the Default trait. Its default value is the first day of the zeroth year. i.e., 0000-W1-1.

§Example: sample dates

This example shows a couple ISO 8601 week dates and their corresponding Gregorian equivalents:

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

let d = date(2019, 12, 30);
let weekdate = ISOWeekDate::new(2020, 1, Weekday::Monday).unwrap();
assert_eq!(d.iso_week_date(), weekdate);

let d = date(2024, 3, 9);
let weekdate = ISOWeekDate::new(2024, 10, Weekday::Saturday).unwrap();
assert_eq!(d.iso_week_date(), weekdate);

§Example: overlapping leap and long years

A “long” ISO 8601 week year is a year with 53 weeks. That is, it is a year that includes a leap week. This example shows all years in the 20th century that are both Gregorian leap years and long years.

use jiff::civil::date;

let mut overlapping = vec![];
for year in 1900..=1999 {
    let date = date(year, 1, 1);
    if date.in_leap_year() && date.iso_week_date().in_long_year() {
        overlapping.push(year);
    }
}
assert_eq!(overlapping, vec![
    1904, 1908, 1920, 1932, 1936, 1948, 1960, 1964, 1976, 1988, 1992,
]);

§Example: printing all weeks in a year

The ISO 8601 week calendar can be useful when you want to categorize things into buckets of weeks where all weeks are exactly 7 days, and you don’t care as much about the precise Gregorian year. Here’s an example that prints all of the ISO 8601 weeks in one ISO 8601 week year:

use jiff::{civil::{ISOWeekDate, Weekday}, ToSpan};

let target_year = 2024;
let iso_week_date = ISOWeekDate::new(target_year, 1, Weekday::Monday)?;
// Create a series of dates via the Gregorian calendar. But since a
// Gregorian week and an ISO 8601 week calendar week are both 7 days,
// this works fine.
let weeks = iso_week_date
    .date()
    .series(1.week())
    .map(|d| d.iso_week_date())
    .take_while(|wd| wd.year() == target_year);
for start_of_week in weeks {
    let end_of_week = start_of_week.last_of_week()?;
    println!(
        "ISO week {}: {} - {}",
        start_of_week.week(),
        start_of_week.date(),
        end_of_week.date()
    );
}

Implementations§

Source§

impl ISOWeekDate

Source

pub const MIN: ISOWeekDate = _

The maximum representable ISO week date.

The maximum corresponds to the ISO week date of the maximum Date value. That is, -9999-01-01.

Source

pub const MAX: ISOWeekDate = _

The minimum representable ISO week date.

The minimum corresponds to the ISO week date of the minimum Date value. That is, 9999-12-31.

Source

pub const ZERO: ISOWeekDate = _

The first day of the zeroth year.

This is guaranteed to be equivalent to ISOWeekDate::default(). Note that this is not equivalent to Date::default().

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

assert_eq!(ISOWeekDate::ZERO, ISOWeekDate::default());
// The first day of the 0th year in the ISO week calendar is actually
// the third day of the 0th year in the proleptic Gregorian calendar!
assert_eq!(ISOWeekDate::default().date(), date(0, 1, 3));
Source

pub fn new(year: i16, week: i8, weekday: Weekday) -> Result<ISOWeekDate, Error>

Create a new ISO week date from it constituent parts.

If the given values are out of range (based on what is representable as a Date), then this returns an error. This will also return an error if a leap week is given (week number 53) for a year that does not contain a leap week.

§Example

This example shows some the boundary conditions involving minimum and maximum dates:

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

// The year 1949 does not contain a leap week.
assert!(ISOWeekDate::new(1949, 53, Weekday::Monday).is_err());

// Examples of dates at or exceeding the maximum.
let max = ISOWeekDate::new(9999, 52, Weekday::Friday).unwrap();
assert_eq!(max, ISOWeekDate::MAX);
assert_eq!(max.date(), date(9999, 12, 31));
assert!(ISOWeekDate::new(9999, 52, Weekday::Saturday).is_err());
assert!(ISOWeekDate::new(9999, 53, Weekday::Monday).is_err());

// Examples of dates at or exceeding the minimum.
let min = ISOWeekDate::new(-9999, 1, Weekday::Monday).unwrap();
assert_eq!(min, ISOWeekDate::MIN);
assert_eq!(min.date(), date(-9999, 1, 1));
assert!(ISOWeekDate::new(-10000, 52, Weekday::Sunday).is_err());
Source

pub fn from_date(date: Date) -> ISOWeekDate

Converts a Gregorian date to an ISO week date.

The minimum and maximum allowed values of an ISO week date are set based on the minimum and maximum values of a Date. Therefore, converting to and from Date values is non-lossy and infallible.

This routine is equivalent to Date::iso_week_date. This routine is also available via a From<Date> trait implementation for ISOWeekDate.

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

let weekdate = ISOWeekDate::from_date(date(1948, 2, 10));
assert_eq!(
    weekdate,
    ISOWeekDate::new(1948, 7, Weekday::Tuesday).unwrap(),
);
Source

pub fn year(self) -> i16

Returns the year component of this ISO 8601 week date.

The value returned is guaranteed to be in the range -9999..=9999.

§Example
use jiff::civil::date;

let weekdate = date(2019, 12, 30).iso_week_date();
assert_eq!(weekdate.year(), 2020);
Source

pub fn week(self) -> i8

Returns the week component of this ISO 8601 week date.

The value returned is guaranteed to be in the range 1..=53. A value of 53 can only occur for “long” years. That is, years with a leap week. This occurs precisely in cases for which ISOWeekDate::in_long_year returns true.

§Example
use jiff::civil::date;

let weekdate = date(2019, 12, 30).iso_week_date();
assert_eq!(weekdate.year(), 2020);
assert_eq!(weekdate.week(), 1);

let weekdate = date(1948, 12, 31).iso_week_date();
assert_eq!(weekdate.year(), 1948);
assert_eq!(weekdate.week(), 53);
Source

pub fn weekday(self) -> Weekday

Returns the day component of this ISO 8601 week date.

One can use methods on Weekday such as Weekday::to_monday_one_offset and Weekday::to_sunday_zero_offset to convert the weekday to a number.

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

let weekdate = date(1948, 12, 31).iso_week_date();
assert_eq!(weekdate.year(), 1948);
assert_eq!(weekdate.week(), 53);
assert_eq!(weekdate.weekday(), Weekday::Friday);
assert_eq!(weekdate.weekday().to_monday_zero_offset(), 4);
assert_eq!(weekdate.weekday().to_monday_one_offset(), 5);
assert_eq!(weekdate.weekday().to_sunday_zero_offset(), 5);
assert_eq!(weekdate.weekday().to_sunday_one_offset(), 6);
Source

pub fn first_of_week(self) -> Result<ISOWeekDate, Error>

Returns the ISO 8601 week date corresponding to the first day in the week of this week date. The date returned is guaranteed to have a weekday of Weekday::Monday.

§Errors

Since -9999-01-01 falls on a Monday, it follows that the minimum support Gregorian date is exactly equivalent to the minimum supported ISO 8601 week date. This means that this routine can never actually fail, but only insomuch as the minimums line up. For that reason, and for consistency with ISOWeekDate::last_of_week, the API is fallible.

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

let wd = ISOWeekDate::new(2025, 5, Weekday::Wednesday).unwrap();
assert_eq!(wd.date(), date(2025, 1, 29));
assert_eq!(
    wd.first_of_week()?,
    ISOWeekDate::new(2025, 5, Weekday::Monday).unwrap(),
);

// Works even for the minimum date.
assert_eq!(
    ISOWeekDate::MIN.first_of_week()?,
    ISOWeekDate::new(-9999, 1, Weekday::Monday).unwrap(),
);
Source

pub fn last_of_week(self) -> Result<ISOWeekDate, Error>

Returns the ISO 8601 week date corresponding to the last day in the week of this week date. The date returned is guaranteed to have a weekday of Weekday::Sunday.

§Errors

This can return an error if the last day of the week exceeds Jiff’s maximum Gregorian date of 9999-12-31. It turns out this can happen since 9999-12-31 falls on a Friday.

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

let wd = ISOWeekDate::new(2025, 5, Weekday::Wednesday).unwrap();
assert_eq!(wd.date(), date(2025, 1, 29));
assert_eq!(
    wd.last_of_week()?,
    ISOWeekDate::new(2025, 5, Weekday::Sunday).unwrap(),
);

// Unlike `first_of_week`, this routine can actually fail on real
// values, although, only when close to the maximum supported date.
assert_eq!(
    ISOWeekDate::MAX.last_of_week().unwrap_err().to_string(),
    "parameter 'weekday' with value 7 is not \
     in the required range of 1..=5",
);
Source

pub fn first_of_year(self) -> Result<ISOWeekDate, Error>

Returns the ISO 8601 week date corresponding to the first day in the year of this week date. The date returned is guaranteed to have a weekday of Weekday::Monday.

§Errors

Since -9999-01-01 falls on a Monday, it follows that the minimum support Gregorian date is exactly equivalent to the minimum supported ISO 8601 week date. This means that this routine can never actually fail, but only insomuch as the minimums line up. For that reason, and for consistency with ISOWeekDate::last_of_year, the API is fallible.

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

let wd = ISOWeekDate::new(2025, 5, Weekday::Wednesday).unwrap();
assert_eq!(wd.date(), date(2025, 1, 29));
assert_eq!(
    wd.first_of_year()?,
    ISOWeekDate::new(2025, 1, Weekday::Monday).unwrap(),
);

// Works even for the minimum date.
assert_eq!(
    ISOWeekDate::MIN.first_of_year()?,
    ISOWeekDate::new(-9999, 1, Weekday::Monday).unwrap(),
);
Source

pub fn last_of_year(self) -> Result<ISOWeekDate, Error>

Returns the ISO 8601 week date corresponding to the last day in the year of this week date. The date returned is guaranteed to have a weekday of Weekday::Sunday.

§Errors

This can return an error if the last day of the year exceeds Jiff’s maximum Gregorian date of 9999-12-31. It turns out this can happen since 9999-12-31 falls on a Friday.

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

let wd = ISOWeekDate::new(2025, 5, Weekday::Wednesday).unwrap();
assert_eq!(wd.date(), date(2025, 1, 29));
assert_eq!(
    wd.last_of_year()?,
    ISOWeekDate::new(2025, 52, Weekday::Sunday).unwrap(),
);

// Works correctly for "long" years.
let wd = ISOWeekDate::new(2026, 5, Weekday::Wednesday).unwrap();
assert_eq!(wd.date(), date(2026, 1, 28));
assert_eq!(
    wd.last_of_year()?,
    ISOWeekDate::new(2026, 53, Weekday::Sunday).unwrap(),
);

// Unlike `first_of_year`, this routine can actually fail on real
// values, although, only when close to the maximum supported date.
assert_eq!(
    ISOWeekDate::MAX.last_of_year().unwrap_err().to_string(),
    "parameter 'weekday' with value 7 is not \
     in the required range of 1..=5",
);
Source

pub fn days_in_year(self) -> i16

Returns the total number of days in the year of this ISO 8601 week date.

It is guaranteed that the value returned is either 364 or 371. The latter case occurs precisely when ISOWeekDate::in_long_year returns true.

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

let weekdate = ISOWeekDate::new(2025, 7, Weekday::Monday).unwrap();
assert_eq!(weekdate.days_in_year(), 364);
let weekdate = ISOWeekDate::new(2026, 7, Weekday::Monday).unwrap();
assert_eq!(weekdate.days_in_year(), 371);
Source

pub fn weeks_in_year(self) -> i8

Returns the total number of weeks in the year of this ISO 8601 week date.

It is guaranteed that the value returned is either 52 or 53. The latter case occurs precisely when ISOWeekDate::in_long_year returns true.

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

let weekdate = ISOWeekDate::new(2025, 7, Weekday::Monday).unwrap();
assert_eq!(weekdate.weeks_in_year(), 52);
let weekdate = ISOWeekDate::new(2026, 7, Weekday::Monday).unwrap();
assert_eq!(weekdate.weeks_in_year(), 53);
Source

pub fn in_long_year(self) -> bool

Returns true if and only if the year of this week date is a “long” year.

A long year is one that contains precisely 53 weeks. All other years contain precisely 52 weeks.

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

let weekdate = ISOWeekDate::new(1948, 7, Weekday::Monday).unwrap();
assert!(weekdate.in_long_year());
let weekdate = ISOWeekDate::new(1949, 7, Weekday::Monday).unwrap();
assert!(!weekdate.in_long_year());
Source

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

Returns the ISO 8601 date immediately following this one.

§Errors

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

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

let wd = ISOWeekDate::new(2025, 5, Weekday::Wednesday).unwrap();
assert_eq!(
    wd.tomorrow()?,
    ISOWeekDate::new(2025, 5, Weekday::Thursday).unwrap(),
);

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

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

Returns the ISO 8601 week date immediately preceding this one.

§Errors

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

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

let wd = ISOWeekDate::new(2025, 5, Weekday::Wednesday).unwrap();
assert_eq!(
    wd.yesterday()?,
    ISOWeekDate::new(2025, 5, Weekday::Tuesday).unwrap(),
);

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

pub fn date(self) -> Date

Converts this ISO week date to a Gregorian Date.

The minimum and maximum allowed values of an ISO week date are set based on the minimum and maximum values of a Date. Therefore, converting to and from Date values is non-lossy and infallible.

This routine is equivalent to Date::from_iso_week_date.

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

let weekdate = ISOWeekDate::new(1948, 7, Weekday::Tuesday).unwrap();
assert_eq!(weekdate.date(), date(1948, 2, 10));

Trait Implementations§

Source§

impl Clone for ISOWeekDate

Source§

fn clone(&self) -> ISOWeekDate

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 ISOWeekDate

Source§

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

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

impl Default for ISOWeekDate

Source§

fn default() -> ISOWeekDate

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

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

Source§

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

Converts to this type from the input type.
Source§

impl From<Date> for ISOWeekDate

Source§

fn from(date: Date) -> ISOWeekDate

Converts to this type from the input type.
Source§

impl From<DateTime> for ISOWeekDate

Source§

fn from(dt: DateTime) -> ISOWeekDate

Converts to this type from the input type.
Source§

impl From<ISOWeekDate> for BrokenDownTime

Source§

fn from(wd: ISOWeekDate) -> BrokenDownTime

Converts to this type from the input type.
Source§

impl From<ISOWeekDate> for Date

Source§

fn from(weekdate: ISOWeekDate) -> Date

Converts to this type from the input type.
Source§

impl From<Zoned> for ISOWeekDate

Source§

fn from(zdt: Zoned) -> ISOWeekDate

Converts to this type from the input type.
Source§

impl Hash for ISOWeekDate

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 ISOWeekDate

Source§

fn cmp(&self, other: &ISOWeekDate) -> 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,

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

impl PartialEq for ISOWeekDate

Source§

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

Source§

fn partial_cmp(&self, other: &ISOWeekDate) -> 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 Copy for ISOWeekDate

Source§

impl Eq for ISOWeekDate

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 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, 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, 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.