Skip to content

Commit 36fd78e

Browse files
committed
Extend YearFlags documentation/constants
1 parent c0a20df commit 36fd78e

File tree

1 file changed

+37
-31
lines changed

1 file changed

+37
-31
lines changed

src/naive/year_flags.rs

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,55 @@
11
// This is a part of Chrono.
22
// See README.md and LICENSE.txt for details.
33

4-
//! The internal implementation of the calendar and ordinal date.
5-
//!
6-
//! The current implementation is optimized for determining year, month, day and day of week.
7-
//! 4-bit `YearFlags` map to one of 14 possible classes of year in the Gregorian calendar,
8-
//! which are included in every packed `NaiveDate` instance.
9-
//! The conversion between the packed calendar date (`Mdf`) and the ordinal date (`Of`) is
10-
//! based on the moderately-sized lookup table (~1.5KB)
11-
//! and the packed representation is chosen for the efficient lookup.
12-
//! Every internal data structure does not validate its input,
13-
//! but the conversion keeps the valid value valid and the invalid value invalid
14-
//! so that the user-facing `NaiveDate` can validate the input as late as possible.
4+
//! Helper type for working with year flags.
155
166
#![cfg_attr(feature = "__internal_bench", allow(missing_docs))]
177

188
use core::fmt;
199

20-
/// The year flags (aka the dominical letter).
10+
/// Year flags (aka the dominical letter).
11+
///
12+
/// `YearFlags` are used as the last four bits of `NaiveDate`, `Mdf` and `IsoWeek`.
2113
///
2214
/// There are 14 possible classes of year in the Gregorian calendar:
2315
/// common and leap years starting with Monday through Sunday.
24-
/// The `YearFlags` stores this information into 4 bits `abbb`,
25-
/// where `a` is `1` for the common year (simplifies the `Of` validation)
26-
/// and `bbb` is a non-zero `Weekday` (mapping `Mon` to 7) of the last day in the past year
27-
/// (simplifies the day of week calculation from the 1-based ordinal).
16+
///
17+
/// The `YearFlags` stores this information into 4 bits `abbb`. `a` is the leap year flag, with `1`
18+
/// for the common year (this simplifies validating an ordinal in `NaiveDate`). `bbb` is a non-zero
19+
/// `Weekday` of the last day in the preceding year.
2820
#[allow(unreachable_pub)] // public as an alias for benchmarks only
2921
#[derive(PartialEq, Eq, Copy, Clone, Hash)]
3022
pub struct YearFlags(pub(super) u8);
3123

32-
pub(super) const A: YearFlags = YearFlags(0o15);
33-
pub(super) const AG: YearFlags = YearFlags(0o05);
34-
pub(super) const B: YearFlags = YearFlags(0o14);
35-
pub(super) const BA: YearFlags = YearFlags(0o04);
36-
pub(super) const C: YearFlags = YearFlags(0o13);
37-
pub(super) const CB: YearFlags = YearFlags(0o03);
38-
pub(super) const D: YearFlags = YearFlags(0o12);
39-
pub(super) const DC: YearFlags = YearFlags(0o02);
40-
pub(super) const E: YearFlags = YearFlags(0o11);
41-
pub(super) const ED: YearFlags = YearFlags(0o01);
42-
pub(super) const F: YearFlags = YearFlags(0o17);
43-
pub(super) const FE: YearFlags = YearFlags(0o07);
44-
pub(super) const G: YearFlags = YearFlags(0o16);
45-
pub(super) const GF: YearFlags = YearFlags(0o06);
24+
// Weekday of the last day in the preceding year.
25+
// Allows for quick day of week calculation from the 1-based ordinal).
26+
const YEAR_STARTS_AFTER_MONDAY: u8 = 7; // non-zero to allow use with `NonZero*`.
27+
const YEAR_STARTS_AFTER_THUESDAY: u8 = 1;
28+
const YEAR_STARTS_AFTER_WEDNESDAY: u8 = 2;
29+
const YEAR_STARTS_AFTER_THURSDAY: u8 = 3;
30+
const YEAR_STARTS_AFTER_FRIDAY: u8 = 4;
31+
const YEAR_STARTS_AFTER_SATURDAY: u8 = 5;
32+
const YEAR_STARTS_AFTER_SUNDAY: u8 = 6;
33+
34+
const COMMON_YEAR: u8 = 1 << 3;
35+
const LEAP_YEAR: u8 = 0 << 3;
36+
37+
pub(super) const A: YearFlags = YearFlags(COMMON_YEAR | YEAR_STARTS_AFTER_SATURDAY);
38+
pub(super) const AG: YearFlags = YearFlags(LEAP_YEAR | YEAR_STARTS_AFTER_SATURDAY);
39+
pub(super) const B: YearFlags = YearFlags(COMMON_YEAR | YEAR_STARTS_AFTER_FRIDAY);
40+
pub(super) const BA: YearFlags = YearFlags(LEAP_YEAR | YEAR_STARTS_AFTER_FRIDAY);
41+
pub(super) const C: YearFlags = YearFlags(COMMON_YEAR | YEAR_STARTS_AFTER_THURSDAY);
42+
pub(super) const CB: YearFlags = YearFlags(LEAP_YEAR | YEAR_STARTS_AFTER_THURSDAY);
43+
pub(super) const D: YearFlags = YearFlags(COMMON_YEAR | YEAR_STARTS_AFTER_WEDNESDAY);
44+
pub(super) const DC: YearFlags = YearFlags(LEAP_YEAR | YEAR_STARTS_AFTER_WEDNESDAY);
45+
pub(super) const E: YearFlags = YearFlags(COMMON_YEAR | YEAR_STARTS_AFTER_THUESDAY);
46+
pub(super) const ED: YearFlags = YearFlags(LEAP_YEAR | YEAR_STARTS_AFTER_THUESDAY);
47+
pub(super) const F: YearFlags = YearFlags(COMMON_YEAR | YEAR_STARTS_AFTER_MONDAY);
48+
pub(super) const FE: YearFlags = YearFlags(LEAP_YEAR | YEAR_STARTS_AFTER_MONDAY);
49+
pub(super) const G: YearFlags = YearFlags(COMMON_YEAR | YEAR_STARTS_AFTER_SUNDAY);
50+
pub(super) const GF: YearFlags = YearFlags(LEAP_YEAR | YEAR_STARTS_AFTER_SUNDAY);
4651

52+
/// Table to look up year flags for any year in the 400-year cycle of the Gregorian calendar.
4753
const YEAR_TO_FLAGS: &[YearFlags; 400] = &[
4854
BA, G, F, E, DC, B, A, G, FE, D, C, B, AG, F, E, D, CB, A, G, F, ED, C, B, A, GF, E, D, C, BA,
4955
G, F, E, DC, B, A, G, FE, D, C, B, AG, F, E, D, CB, A, G, F, ED, C, B, A, GF, E, D, C, BA, G,
@@ -115,7 +121,7 @@ impl fmt::Debug for YearFlags {
115121
0o02 => "DC".fmt(f),
116122
0o11 => "E".fmt(f),
117123
0o01 => "ED".fmt(f),
118-
0o10 => "F?".fmt(f),
124+
0o10 => "F?".fmt(f), // non-canonical
119125
0o00 => "FE?".fmt(f), // non-canonical
120126
0o17 => "F".fmt(f),
121127
0o07 => "FE".fmt(f),

0 commit comments

Comments
 (0)