Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add elapsed_years to Date and DateTime #557

Merged
merged 34 commits into from Jun 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
4d87d7f
Add elapsed_years() to Date
yozhgoor Apr 21, 2021
b3ee278
Add elapsed_years() to DateTime
yozhgoor Apr 21, 2021
a493f26
Add elapsed_years() to NaiveDateTime
yozhgoor Apr 21, 2021
54274a2
Oops
yozhgoor Apr 21, 2021
fb25a77
Add elapsed_years() to NaiveDateTime
yozhgoor Apr 21, 2021
f059cb3
WIP
yozhgoor Apr 25, 2021
a5ce0b9
Remove elapsed_years from naive Date and DateTime
yozhgoor Apr 26, 2021
73eac80
Add a consts module with WEEK_PER_YEAR
yozhgoor Apr 27, 2021
351c1cf
Add better tests
yozhgoor Apr 27, 2021
767f87a
Change variable name
yozhgoor Apr 27, 2021
6d569fb
Clean up
yozhgoor Apr 27, 2021
6ab485a
Clean up
yozhgoor Apr 27, 2021
5d1af60
Update changelog and authors
yozhgoor Apr 27, 2021
cab008d
Replace the Utc use by the timezone of the Date
yozhgoor Apr 27, 2021
f676c1f
Clean up
yozhgoor Apr 27, 2021
4c52ec7
Adapt changelog
yozhgoor Apr 27, 2021
5e3eba3
Update src/lib.rs
yozhgoor Jun 13, 2021
bd6a7a7
Update src/lib.rs
yozhgoor Jun 13, 2021
3006303
Update CHANGELOG.md
yozhgoor Jun 13, 2021
520d83e
Merge branch 'main' into elapsed-years
Milo123459 Oct 27, 2021
3fa7eaa
Update CHANGELOG.md
Milo123459 Oct 27, 2021
a069d56
Update src/datetime.rs
Milo123459 Oct 27, 2021
a4a026a
Update
yozhgoor Oct 28, 2021
d82afcf
Use the clock feature when using `Utc::now` and `Utc::today`
yozhgoor Nov 12, 2021
b467923
Merge branch 'main' into elapsed-years
yozhgoor Nov 12, 2021
7816be1
New blank line at EOF
yozhgoor Jan 10, 2022
5a90aff
Merge branch 'elapsed-years' of github.com:yozhgoor/chrono into elaps…
yozhgoor Jan 10, 2022
ba17106
Merge branch 'main' into elapsed-years
yozhgoor May 27, 2022
81fabab
Move the code from `datetime.rs` to `datetime/mod.rs` and delete `dat…
yozhgoor May 27, 2022
d893578
Clean up
yozhgoor May 27, 2022
83aab1a
After review
yozhgoor May 28, 2022
07f1e43
Add `crate::` to the use statement
yozhgoor May 28, 2022
22945a2
Replace `TryFrom`
yozhgoor Jun 8, 2022
492c802
Merge branch 'main' into elapsed-years
yozhgoor Jun 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS.txt
Expand Up @@ -39,3 +39,4 @@ Steve Klabnik <steve@steveklabnik.com>
Tom Gallacher <tomgallacher23@gmail.com>
klutzy <klutzytheklutzy@gmail.com>
kud1ing <github@kudling.de>
Yohan Boogaert <yozhgoor@outlook.com>
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -18,6 +18,7 @@ Versions with only mechanical changes will be omitted from the following list.
* Fix `DurationRound` is not TZ aware (#495)
* Implement `DurationRound` for `NaiveDateTime`
* Add `DateTime::from_local()` to construct from given local date and time (#572)
* Add a function that calculates the number of years elapsed between now and a given `Date` or `DateTime` (#557)
* Correct build for wasm32-unknown-emscripten target (#568)
* Change `Local::now()` and `Utc::now()` documentation from "current date" to "current date and time" (#647)
* Fix `duration_round` panic on rounding by `Duration::zero()` (#658)
Expand Down
41 changes: 41 additions & 0 deletions src/date.rs
Expand Up @@ -275,6 +275,24 @@ impl<Tz: TimeZone> Date<Tz> {
pub fn naive_local(&self) -> NaiveDate {
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
}
}
}

/// Maps the local date to other date with given conversion function.
Expand Down Expand Up @@ -498,3 +516,26 @@ where
write!(f, "{}{}", self.naive_local(), self.offset)
}
}

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

#[test]
#[cfg(feature = "clock")]
fn test_years_elapsed() {
// 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);
// A bit more than 2 years.
let two_year_ago =
Utc::today() - Duration::weeks((f64::WEEKS_PER_YEAR * 2.5).ceil() as i64);

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);
}
}
18 changes: 18 additions & 0 deletions src/datetime/mod.rs
Expand Up @@ -355,6 +355,24 @@ impl<Tz: TimeZone> DateTime<Tz> {
pub fn naive_local(&self) -> NaiveDateTime {
self.datetime + self.offset.fix()
}

/// 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
}
}
}

impl Default for DateTime<Utc> {
Expand Down
17 changes: 17 additions & 0 deletions src/datetime/tests.rs
@@ -1,6 +1,8 @@
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 @@ -407,3 +409,18 @@ fn test_datetime_from_local() {
assert_eq!(datetime_east, datetime_utc.with_timezone(&timezone_east));
assert_eq!(datetime_west, datetime_utc.with_timezone(&timezone_west));
}

#[test]
#[cfg(feature = "clock")]
fn test_years_elapsed() {
// 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);
// A bit more than 2 years.
let two_year_ago = Utc::today() - Duration::weeks((f64::WEEKS_PER_YEAR * 2.5).ceil() as i64);

assert_eq!(one_year_ago.elapsed_years(), 1);
assert_eq!(two_year_ago.elapsed_years(), 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);
}
14 changes: 14 additions & 0 deletions src/lib.rs
Expand Up @@ -508,6 +508,20 @@ 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