use chrono::{Date, NaiveDate, ParseResult, TimeZone, Utc};
#[cfg(test)]
mod test {
use super::*;
use chrono::{Local, TimeZone};
#[test]
fn age_test() {
let birthday = Local.ymd(2000, 1, 1);
let date = Local.ymd(2022, 2, 1);
let age = age(birthday, date);
assert_eq!(age, Some(22));
}
#[test]
fn age_from_string_test() {
let birthday = "2000-01-01";
let date = "2022-02-01";
let age = age_from_str(birthday, date, None);
assert_eq!(age, Some(22));
}
#[test]
fn date_from_str_test() {
let date = "2008-08-08";
let date = date_utc_from_str(date, None);
assert_eq!(date, Ok(Utc.ymd(2008, 8, 8)));
}
#[test]
fn date_from_str_error() {
let date = "2008-08-08 08:08:08";
let date = date_utc_from_str(date, None);
assert!(date.is_err())
}
#[test]
fn date_from_str_with_time() {
let date = "2008-08-08 08:08:08";
let date = date_utc_from_str(date, Some("%F %T"));
assert_eq!(date, Ok(Utc.ymd(2008, 8, 8)));
}
}
pub fn age_of_now<Tz: TimeZone>(birthday: Date<Tz>) -> Option<u32> {
let today = Utc::today();
let birthday = birthday.with_timezone(&Utc);
age(birthday, today)
}
pub fn age_of_now_str(birthday: &str) -> Option<u32> {
let today = Utc::today();
let birthday = date_utc_from_str(birthday, None).unwrap();
age(birthday, today)
}
pub fn age<Tz: TimeZone>(birthday: Date<Tz>, date: Date<Tz>) -> Option<u32> {
date.years_since(birthday)
}
pub fn age_from_str(birthday: &str, date: &str, formatter: Option<&str>) -> Option<u32> {
let formatter = formatter.unwrap_or("%F");
let birthday = date_utc_from_str(birthday, None).expect("Invalid date");
let date_naive = NaiveDate::parse_from_str(date, formatter).unwrap();
let date = Utc.from_utc_date(&date_naive);
age(birthday, date)
}
fn date_utc_from_str(s: &str, formatter: Option<&str>) -> ParseResult<Date<Utc>> {
let formatter = formatter.unwrap_or("%F");
let naive_date = NaiveDate::parse_from_str(s, formatter)?;
let date = Utc.from_utc_date(&naive_date);
Ok(date)
}