1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//! Exact dates, tenors and periodic frequencies (milestone M2).
//!
//! [`Date`] covers the proleptic Gregorian calendar from 0001-01-01 through
//! 9999-12-31. Arithmetic is checked; adding months clamps the day to the
//! target month's length, and never silently preserves end-of-month status.
//! Dates have neither a time zone nor a time of day. There is no implicit today.
//!
//! [`Period`] has normalized equality and hashing: `12M == 1Y`, `14D == 2W`,
//! and all zero periods are equal. Ordering uses the normalized unit family:
//! months/years and days/weeks are separate, and canonical zero belongs to
//! days/weeks. A zero period and a nonzero month/year period are incomparable.
//! This keeps ordering consistent with equality and transitive.
//!
//! # QuantLib correspondence
//!
//! QuantLib 1.43 `Date`, `Period`, `TimeUnit` and `Frequency` are external
//! behavioral references. SabiQuant has a broader date range, ISO weekday
//! numbers, typed errors and deliberately narrower period comparisons.
//! Excel/QuantLib serial-number conversion is deferred. Compatibility claims
//! apply only to the tested scenario sets listed in the validation report.
//!
//! ```
//! use sabiquant::time::{Date, Period, TimeUnit};
//! let date = Date::from_ymd(2024, 1, 31)?;
//! let maturity = date.checked_add_period(Period::new(1, TimeUnit::Months))?;
//! assert_eq!(maturity.to_string(), "2024-02-29");
//! # Ok::<(), sabiquant::time::DateError>(())
//! ```
pub use ;
pub use ;