Moving back to single dates for calendar
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
use crate::date_range::*;
|
|
||||||
use chrono::naive::NaiveDate;
|
use chrono::naive::NaiveDate;
|
||||||
use chrono::{Datelike, Month, Weekday};
|
use chrono::{Datelike, Month, Weekday};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -9,10 +8,9 @@ use std::collections::HashSet;
|
|||||||
|
|
||||||
- workdays are only calculated within a year. If a workday in a prior
|
- workdays are only calculated within a year. If a workday in a prior
|
||||||
year is bumped to the next year, it won't be considered.
|
year is bumped to the next year, it won't be considered.
|
||||||
- workday impact is searched forward. If there is a mix of AdjustmentPolicy's
|
- workday impact is searched forward. If there is a mix of AdjustmentPolicies
|
||||||
then some weird stuff can happen (workdays occur A, B, but end up getting
|
then some weird stuff can happen (workdays occur A, B, but end up getting
|
||||||
observed B, A)
|
observed B, A)
|
||||||
- No support for workday ranges (e.g. Golden Week)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
|
#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
|
||||||
@@ -45,9 +43,9 @@ pub enum DateSpec {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
description: String,
|
description: String,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
since: Option<NaiveDate>,
|
valid_since: Option<NaiveDate>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
until: Option<NaiveDate>,
|
valid_until: Option<NaiveDate>,
|
||||||
},
|
},
|
||||||
NthDayOccurance {
|
NthDayOccurance {
|
||||||
month: Month,
|
month: Month,
|
||||||
@@ -58,51 +56,48 @@ pub enum DateSpec {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
description: String,
|
description: String,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
since: Option<NaiveDate>,
|
valid_since: Option<NaiveDate>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
until: Option<NaiveDate>,
|
valid_until: Option<NaiveDate>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DateSpec {
|
impl DateSpec {
|
||||||
/// Get exact date of event and its policy, if it occured in that year
|
/// Get exact date of event and its policy, if it occured in that year
|
||||||
fn resolve(&self, year: i32) -> Option<(DateRange, AdjustmentPolicy)> {
|
fn resolve(&self, year: i32) -> Option<(NaiveDate, AdjustmentPolicy)> {
|
||||||
use DateSpec::*;
|
use DateSpec::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
SpecificDate { date, .. } => Some((
|
SpecificDate { date, .. } => Some((*date, AdjustmentPolicy::NoAdjustment)),
|
||||||
DateRange::new(*date, date.succ()),
|
|
||||||
AdjustmentPolicy::NoAdjustment,
|
|
||||||
)),
|
|
||||||
DayOfMonth {
|
DayOfMonth {
|
||||||
month,
|
month,
|
||||||
day,
|
day,
|
||||||
since,
|
valid_since,
|
||||||
until,
|
valid_until,
|
||||||
observed,
|
observed,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if since.is_some() && since.unwrap().year() > year {
|
if valid_since.is_some() && valid_since.unwrap().year() > year {
|
||||||
None
|
None
|
||||||
} else if until.is_some() && until.unwrap().year() < year {
|
} else if valid_until.is_some() && valid_until.unwrap().year() < year {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let date = NaiveDate::from_ymd(year, month.number_from_month(), *day);
|
let date = NaiveDate::from_ymd(year, month.number_from_month(), *day);
|
||||||
Some((DateRange::new(date, date.succ()), *observed))
|
Some((date, *observed))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NthDayOccurance {
|
NthDayOccurance {
|
||||||
month,
|
month,
|
||||||
dow,
|
dow,
|
||||||
offset,
|
offset,
|
||||||
since,
|
valid_since,
|
||||||
until,
|
valid_until,
|
||||||
observed,
|
observed,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if since.is_some() && since.unwrap().year() > year {
|
if valid_since.is_some() && valid_since.unwrap().year() > year {
|
||||||
None
|
None
|
||||||
} else if until.is_some() && until.unwrap().year() < year {
|
} else if valid_until.is_some() && valid_until.unwrap().year() < year {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let month_num = month.number_from_month();
|
let month_num = month.number_from_month();
|
||||||
@@ -120,7 +115,7 @@ impl DateSpec {
|
|||||||
date = date.checked_sub_signed(chrono::Duration::days(7)).unwrap();
|
date = date.checked_sub_signed(chrono::Duration::days(7)).unwrap();
|
||||||
off += 1;
|
off += 1;
|
||||||
}
|
}
|
||||||
Some((DateRange::new(date, date.succ()), *observed))
|
Some((date, *observed))
|
||||||
} else {
|
} else {
|
||||||
let mut date = NaiveDate::from_ymd(year, month_num, 1);
|
let mut date = NaiveDate::from_ymd(year, month_num, 1);
|
||||||
while date.weekday() != *dow {
|
while date.weekday() != *dow {
|
||||||
@@ -131,7 +126,7 @@ impl DateSpec {
|
|||||||
date = date.checked_add_signed(chrono::Duration::days(7)).unwrap();
|
date = date.checked_add_signed(chrono::Duration::days(7)).unwrap();
|
||||||
off -= 1;
|
off -= 1;
|
||||||
}
|
}
|
||||||
Some((DateRange::new(date, date.succ()), *observed))
|
Some((date, *observed))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,17 +154,15 @@ pub struct Calendar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Calendar {
|
impl Calendar {
|
||||||
fn adjust_workdays(&self, workdays: &Vec<(DateRange, AdjustmentPolicy)>) -> HashSet<NaiveDate> {
|
fn adjust_workdays(&self, workdays: &Vec<(NaiveDate, AdjustmentPolicy)>) -> HashSet<NaiveDate> {
|
||||||
let mut observed = HashSet::new();
|
let mut observed = HashSet::new();
|
||||||
|
|
||||||
for (date_range, policy) in workdays.iter() {
|
for (date, policy) in workdays.iter() {
|
||||||
for date in date_range {
|
match self.adjust_workday(*date, policy, &observed) {
|
||||||
match self.adjust_workday(date, policy, &observed) {
|
Some(workday) => {
|
||||||
Some(workday) => {
|
observed.insert(workday);
|
||||||
observed.insert(workday);
|
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +222,7 @@ impl Calendar {
|
|||||||
|
|
||||||
/// Get the set of all workdays in a given year
|
/// Get the set of all workdays in a given year
|
||||||
pub fn get_workdays(&self, date: NaiveDate) -> HashSet<NaiveDate> {
|
pub fn get_workdays(&self, date: NaiveDate) -> HashSet<NaiveDate> {
|
||||||
let workdays: Vec<(DateRange, AdjustmentPolicy)> = self
|
let workdays: Vec<(NaiveDate, AdjustmentPolicy)> = self
|
||||||
.exclude
|
.exclude
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| x.resolve(date.year()))
|
.map(|x| x.resolve(date.year()))
|
||||||
@@ -284,16 +277,16 @@ mod tests {
|
|||||||
day: 25u32,
|
day: 25u32,
|
||||||
observed: AdjustmentPolicy::Next,
|
observed: AdjustmentPolicy::Next,
|
||||||
description: "Christmas".to_owned(),
|
description: "Christmas".to_owned(),
|
||||||
since: None,
|
valid_since: None,
|
||||||
until: None,
|
valid_until: None,
|
||||||
},
|
},
|
||||||
DateSpec::DayOfMonth {
|
DateSpec::DayOfMonth {
|
||||||
month: December,
|
month: December,
|
||||||
day: 26u32,
|
day: 26u32,
|
||||||
observed: AdjustmentPolicy::Next,
|
observed: AdjustmentPolicy::Next,
|
||||||
description: "Boxing Day".to_owned(),
|
description: "Boxing Day".to_owned(),
|
||||||
since: None,
|
valid_since: None,
|
||||||
until: None,
|
valid_until: None,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
inherits: vec![],
|
inherits: vec![],
|
||||||
@@ -323,24 +316,24 @@ mod tests {
|
|||||||
day: 25u32,
|
day: 25u32,
|
||||||
observed: AdjustmentPolicy::Next,
|
observed: AdjustmentPolicy::Next,
|
||||||
description: "Christmas".to_owned(),
|
description: "Christmas".to_owned(),
|
||||||
since: None,
|
valid_since: None,
|
||||||
until: None,
|
valid_until: None,
|
||||||
},
|
},
|
||||||
DateSpec::DayOfMonth {
|
DateSpec::DayOfMonth {
|
||||||
month: December,
|
month: December,
|
||||||
day: 26u32,
|
day: 26u32,
|
||||||
observed: AdjustmentPolicy::Next,
|
observed: AdjustmentPolicy::Next,
|
||||||
description: "Boxing Day".to_owned(),
|
description: "Boxing Day".to_owned(),
|
||||||
since: None,
|
valid_since: None,
|
||||||
until: None,
|
valid_until: None,
|
||||||
},
|
},
|
||||||
DateSpec::DayOfMonth {
|
DateSpec::DayOfMonth {
|
||||||
month: January,
|
month: January,
|
||||||
day: 1u32,
|
day: 1u32,
|
||||||
observed: AdjustmentPolicy::Next,
|
observed: AdjustmentPolicy::Next,
|
||||||
description: "New Years Day".to_owned(),
|
description: "New Years Day".to_owned(),
|
||||||
since: None,
|
valid_since: None,
|
||||||
until: None,
|
valid_until: None,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
inherits: vec![],
|
inherits: vec![],
|
||||||
|
|||||||
Reference in New Issue
Block a user