Skip to content

Commit

Permalink
Morph elapsed_years() API into years_since()
Browse files Browse the repository at this point in the history
  • Loading branch information
djc committed Jun 8, 2022
1 parent 1d33cbc commit 752e69a
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 61 deletions.
47 changes: 21 additions & 26 deletions src/date.rs
Expand Up @@ -276,21 +276,16 @@ impl<Tz: TimeZone> Date<Tz> {
self.date
}

/// Retrieves the elapsed years from now to the given [`Date`].
#[cfg(feature = "clock")]
pub fn elapsed_years(&self) -> u32 {
let now = Utc::today().with_timezone(&self.timezone());

let years = if (now.month(), now.day()) < (self.month(), self.day()) {
now.year() - self.year() - 1
} else {
now.year() - self.year()
};

if years.is_positive() {
years as u32
} else {
0
/// Returns the number of whole years from the given `base` until `self`.
pub fn years_since(&self, base: Self) -> Option<u32> {
let mut years = self.year() - base.year();
if (self.month(), self.day()) < (base.month(), base.day()) {
years -= 1;
}

match years >= 0 {
true => Some(years as u32),
false => None,
}
}
}
Expand Down Expand Up @@ -519,23 +514,23 @@ where

#[cfg(test)]
mod tests {
use crate::consts::f64;
use crate::offset::Utc;
use crate::oldtime::Duration;
use crate::{Duration, Utc};

#[test]
#[cfg(feature = "clock")]
fn test_years_elapsed() {
const WEEKS_PER_YEAR: f32 = 52.1775;

// This is always at least one year because 1 year = 52.1775 weeks.
let one_year_ago =
Utc::today() - Duration::weeks((f64::WEEKS_PER_YEAR * 1.5).ceil() as i64);
let one_year_ago = Utc::today() - Duration::weeks((WEEKS_PER_YEAR * 1.5).ceil() as i64);
// A bit more than 2 years.
let two_year_ago =
Utc::today() - Duration::weeks((f64::WEEKS_PER_YEAR * 2.5).ceil() as i64);
let two_year_ago = Utc::today() - Duration::weeks((WEEKS_PER_YEAR * 2.5).ceil() as i64);

assert_eq!(Utc::today().years_since(one_year_ago), Some(1));
assert_eq!(Utc::today().years_since(two_year_ago), Some(2));

assert_eq!(one_year_ago.elapsed_years(), 1);
assert_eq!(two_year_ago.elapsed_years(), 2);
// if the given Date is later than now, the function will always return 0.
assert_eq!((Utc::today() + Duration::weeks(12)).elapsed_years(), 0);
// If the given DateTime is later than now, the function will always return 0.
let future = Utc::today() + Duration::weeks(12);
assert_eq!(Utc::today().years_since(future), None);
}
}
27 changes: 13 additions & 14 deletions src/datetime/mod.rs
Expand Up @@ -357,20 +357,19 @@ impl<Tz: TimeZone> DateTime<Tz> {
}

/// Retrieve the elapsed years from now to the given [`DateTime`].
#[cfg(feature = "clock")]
pub fn elapsed_years(&self) -> u32 {
let now = Utc::now().with_timezone(&self.timezone());

let years =
if (now.month(), now.day(), now.time()) < (self.month(), self.day(), self.time()) {
now.year() - self.year() - 1
} else {
now.year() - self.year()
};
if years.is_positive() {
years as u32
} else {
0
pub fn years_since(&self, base: Self) -> Option<u32> {
let mut years = self.year() - base.year();
let earlier_time =
(self.month(), self.day(), self.time()) < (base.month(), base.day(), base.time());

years -= match earlier_time {
true => 1,
false => 0,
};

match years >= 0 {
true => Some(years as u32),
false => None,
}
}
}
Expand Down
15 changes: 8 additions & 7 deletions src/datetime/tests.rs
@@ -1,8 +1,6 @@
use std::time::{SystemTime, UNIX_EPOCH};

use super::DateTime;
#[cfg(feature = "clock")]
use crate::consts::f64;
use crate::naive::{NaiveDate, NaiveTime};
#[cfg(feature = "clock")]
use crate::offset::Local;
Expand Down Expand Up @@ -413,14 +411,17 @@ fn test_datetime_from_local() {
#[test]
#[cfg(feature = "clock")]
fn test_years_elapsed() {
const WEEKS_PER_YEAR: f32 = 52.1775;

// This is always at least one year because 1 year = 52.1775 weeks.
let one_year_ago = Utc::today() - Duration::weeks((f64::WEEKS_PER_YEAR * 1.5).ceil() as i64);
let one_year_ago = Utc::today() - Duration::weeks((WEEKS_PER_YEAR * 1.5).ceil() as i64);
// A bit more than 2 years.
let two_year_ago = Utc::today() - Duration::weeks((f64::WEEKS_PER_YEAR * 2.5).ceil() as i64);
let two_year_ago = Utc::today() - Duration::weeks((WEEKS_PER_YEAR * 2.5).ceil() as i64);

assert_eq!(one_year_ago.elapsed_years(), 1);
assert_eq!(two_year_ago.elapsed_years(), 2);
assert_eq!(Utc::today().years_since(one_year_ago), Some(1));
assert_eq!(Utc::today().years_since(two_year_ago), Some(2));

// If the given DateTime is later than now, the function will always return 0.
assert_eq!((Utc::today() + Duration::weeks(12)).elapsed_years(), 0);
let future = Utc::today() + Duration::weeks(12);
assert_eq!(Utc::today().years_since(future), None);
}
14 changes: 0 additions & 14 deletions src/lib.rs
Expand Up @@ -508,20 +508,6 @@ pub use month::{Month, ParseMonthError};
mod traits;
pub use traits::{Datelike, Timelike};

/// Constants that can be used by all components.
pub mod consts {
/// Constants of type `f32`.
pub mod f32 {
/// Number of weeks in a year.
pub const WEEKS_PER_YEAR: f32 = 52.1775;
}
/// Constants of type `f64`.
pub mod f64 {
/// Number of weeks in a year.
pub const WEEKS_PER_YEAR: f64 = 52.1775;
}
}

#[cfg(feature = "__internal_bench")]
#[doc(hidden)]
pub use naive::__BenchYearFlags;
Expand Down

0 comments on commit 752e69a

Please sign in to comment.