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
impl ISOWeekDate
Sourcepub const MIN: ISOWeekDate = _
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
.
Sourcepub const MAX: ISOWeekDate = _
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
.
Sourcepub const ZERO: ISOWeekDate = _
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));
Sourcepub fn new(year: i16, week: i8, weekday: Weekday) -> Result<ISOWeekDate, Error>
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());
Sourcepub fn from_date(date: Date) -> ISOWeekDate
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(),
);
Sourcepub fn year(self) -> i16
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);
Sourcepub fn week(self) -> i8
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);
Sourcepub fn weekday(self) -> Weekday
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);
Sourcepub fn first_of_week(self) -> Result<ISOWeekDate, Error>
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(),
);
Sourcepub fn last_of_week(self) -> Result<ISOWeekDate, Error>
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",
);
Sourcepub fn first_of_year(self) -> Result<ISOWeekDate, Error>
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(),
);
Sourcepub fn last_of_year(self) -> Result<ISOWeekDate, Error>
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",
);
Sourcepub fn days_in_year(self) -> i16
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);
Sourcepub fn weeks_in_year(self) -> i8
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);
Sourcepub fn in_long_year(self) -> bool
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());
Sourcepub fn tomorrow(self) -> Result<ISOWeekDate, Error>
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());
Sourcepub fn yesterday(self) -> Result<ISOWeekDate, Error>
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());
Sourcepub fn date(self) -> Date
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
impl Clone for ISOWeekDate
Source§fn clone(&self) -> ISOWeekDate
fn clone(&self) -> ISOWeekDate
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more