mirror of
https://github.com/chronotope/chrono.git
synced 2026-05-05 14:13:06 +00:00
Merge pull request #457 from robyoung/pr/209
Add days and weeks iterators for `NaiveDate`
This commit is contained in:
@@ -10,7 +10,11 @@ Versions with only mechanical changes will be omitted from the following list.
|
|||||||
|
|
||||||
## 0.4.14 (unreleased)
|
## 0.4.14 (unreleased)
|
||||||
|
|
||||||
## Improvements
|
### Features
|
||||||
|
|
||||||
|
* Added day and week iterators for `NaiveDate` (@gnzlbg & @robyoung)
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
* Added MIN and MAX values for `NaiveTime`, `NaiveDateTime` and `DateTime<Utc>`.
|
* Added MIN and MAX values for `NaiveTime`, `NaiveDateTime` and `DateTime<Utc>`.
|
||||||
|
|
||||||
|
|||||||
@@ -1048,6 +1048,58 @@ impl NaiveDate {
|
|||||||
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
|
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
|
||||||
self.format_with_items(StrftimeItems::new(fmt))
|
self.format_with_items(StrftimeItems::new(fmt))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator that steps by days until the last representable date.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use chrono::NaiveDate;
|
||||||
|
///
|
||||||
|
/// let expected = [
|
||||||
|
/// NaiveDate::from_ymd(2016, 2, 27),
|
||||||
|
/// NaiveDate::from_ymd(2016, 2, 28),
|
||||||
|
/// NaiveDate::from_ymd(2016, 2, 29),
|
||||||
|
/// NaiveDate::from_ymd(2016, 3, 1),
|
||||||
|
/// ];
|
||||||
|
///
|
||||||
|
/// let mut count = 0;
|
||||||
|
/// for (idx, d) in NaiveDate::from_ymd(2016, 2, 27).iter_days().take(4).enumerate() {
|
||||||
|
/// assert_eq!(d, expected[idx]);
|
||||||
|
/// count += 1;
|
||||||
|
/// }
|
||||||
|
/// assert_eq!(count, 4);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn iter_days(&self) -> NaiveDateDaysIterator {
|
||||||
|
NaiveDateDaysIterator { value: *self }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator that steps by weeks until the last representable date.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use chrono::NaiveDate;
|
||||||
|
///
|
||||||
|
/// let expected = [
|
||||||
|
/// NaiveDate::from_ymd(2016, 2, 27),
|
||||||
|
/// NaiveDate::from_ymd(2016, 3, 5),
|
||||||
|
/// NaiveDate::from_ymd(2016, 3, 12),
|
||||||
|
/// NaiveDate::from_ymd(2016, 3, 19),
|
||||||
|
/// ];
|
||||||
|
///
|
||||||
|
/// let mut count = 0;
|
||||||
|
/// for (idx, d) in NaiveDate::from_ymd(2016, 2, 27).iter_weeks().take(4).enumerate() {
|
||||||
|
/// assert_eq!(d, expected[idx]);
|
||||||
|
/// count += 1;
|
||||||
|
/// }
|
||||||
|
/// assert_eq!(count, 4);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn iter_weeks(&self) -> NaiveDateWeeksIterator {
|
||||||
|
NaiveDateWeeksIterator { value: *self }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Datelike for NaiveDate {
|
impl Datelike for NaiveDate {
|
||||||
@@ -1511,6 +1563,63 @@ impl Sub<NaiveDate> for NaiveDate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Iterator over `NaiveDate` with a step size of one day.
|
||||||
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)]
|
||||||
|
pub struct NaiveDateDaysIterator {
|
||||||
|
value: NaiveDate,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for NaiveDateDaysIterator {
|
||||||
|
type Item = NaiveDate;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.value == MAX_DATE {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
// current < MAX_DATE from here on:
|
||||||
|
let current = self.value;
|
||||||
|
// This can't panic because current is < MAX_DATE:
|
||||||
|
self.value = current.succ();
|
||||||
|
Some(current)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
let exact_size = MAX_DATE.signed_duration_since(self.value).num_days();
|
||||||
|
(exact_size as usize, Some(exact_size as usize))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExactSizeIterator for NaiveDateDaysIterator {}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)]
|
||||||
|
pub struct NaiveDateWeeksIterator {
|
||||||
|
value: NaiveDate,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for NaiveDateWeeksIterator {
|
||||||
|
type Item = NaiveDate;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if MAX_DATE - self.value < OldDuration::weeks(1) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let current = self.value;
|
||||||
|
self.value = current + OldDuration::weeks(1);
|
||||||
|
Some(current)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
let exact_size = MAX_DATE.signed_duration_since(self.value).num_weeks();
|
||||||
|
(exact_size as usize, Some(exact_size as usize))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExactSizeIterator for NaiveDateWeeksIterator {}
|
||||||
|
|
||||||
|
// TODO: NaiveDateDaysIterator and NaiveDateWeeksIterator should implement FusedIterator,
|
||||||
|
// TrustedLen, and Step once they becomes stable.
|
||||||
|
// See: https://github.com/chronotope/chrono/issues/208
|
||||||
|
|
||||||
/// The `Debug` output of the naive date `d` is the same as
|
/// The `Debug` output of the naive date `d` is the same as
|
||||||
/// [`d.format("%Y-%m-%d")`](../format/strftime/index.html).
|
/// [`d.format("%Y-%m-%d")`](../format/strftime/index.html).
|
||||||
///
|
///
|
||||||
@@ -2270,4 +2379,20 @@ mod tests {
|
|||||||
"2009,09,01,00,53"
|
"2009,09,01,00,53"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_day_iterator_limit() {
|
||||||
|
assert_eq!(
|
||||||
|
NaiveDate::from_ymd(262143, 12, 29).iter_days().take(4).collect::<Vec<_>>().len(),
|
||||||
|
2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_week_iterator_limit() {
|
||||||
|
assert_eq!(
|
||||||
|
NaiveDate::from_ymd(262143, 12, 12).iter_weeks().take(4).collect::<Vec<_>>().len(),
|
||||||
|
2
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user