5 releases

0.2.4 Nov 14, 2022
0.2.3 May 24, 2022
0.2.1 Jan 24, 2021
0.2.0 Oct 17, 2020
0.1.0 Jun 20, 2020

#160 in Date and time

Download history 2281/week @ 2025-05-18 1401/week @ 2025-05-25 1830/week @ 2025-06-01 2311/week @ 2025-06-08 2208/week @ 2025-06-15 1240/week @ 2025-06-22 1182/week @ 2025-06-29 1016/week @ 2025-07-06 1152/week @ 2025-07-13 1362/week @ 2025-07-20 1793/week @ 2025-07-27 1042/week @ 2025-08-03 815/week @ 2025-08-10 1167/week @ 2025-08-17 1355/week @ 2025-08-24 1650/week @ 2025-08-31

5,014 downloads per month
Used in 11 crates (3 directly)

BSD-2-Clause

71KB
1.5K SLoC

gregorian docs tests

An implementation of the proleptic Gregorian calendar, compatible with ISO 8601. Amongst others, that means that the calendar has a year zero preceeding the year 1.

This create does not deal with times or time zones.

The Date type represents a date (year, month and day), the Year type represents a calendar year, the Month type represents a calendar month, and the YearMonth type represents a month of a specific year.

Where possible, things are implemented as const fn. Currently, this excludes trait implementations and functions that rely on traits.

Example

use gregorian::{Date, Month::*, Year, YearMonth};

assert!(Year::new(2020).has_leap_day(), true);
assert!(YearMonth::new(1900, February).total_days() == 28);
assert!(YearMonth::new(2000, February).total_days() == 29);

assert!(Year::new(2020).with_month(March).first_day() == Date::new(2020, March, 1).unwrap());
assert!(Year::new(2020).with_month(March).last_day() == Date::new(2020, March, 31).unwrap());

assert!(Year::new(2020).first_day() == Date::new(2020, 1, 1).unwrap());
assert!(Year::new(2020).last_day() == Date::new(2020, 12, 31).unwrap());

assert!(Date::new(2020, 2, 1).unwrap().day_of_year() == 32);

Rounding invalid dates

When you use Date::add_years() or Date::add_months(), you can get invalid dates. These are reported with an InvalidDayOfMonth error which has the next_valid() and prev_valid() methods. Those can be used to get the next or previous valid date instead.

Additionally, there is an extension trait for Result<Date, InvalidDayOfMonth> with the or_next_valid() and or_prev_valid() methods. This allows you to directly round the date on the Result object.

use gregorian::{Date, DateResultExt};
let date = Date::new(2020, 1, 31).unwrap();
assert!(date.add_months(1).or_next_valid() == Date::new(2020, 3, 1).unwrap());
assert!(date.add_months(1).or_prev_valid() == Date::new(2020, 2, 29).unwrap());

Dependencies

~155KB