summaryrefslogtreecommitdiffstats
path: root/src/utils/dateutil.rs
blob: 84818ce918a2f1173cbe3de2b19b02a045a4e410 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use chrono::*;

pub fn date_from_str(date_str: &str) -> ParseResult<Date<Local>> {
  if date_str  == "today" || date_str == "now" {
    return Ok(Local::now().date());
  }
  let naive_date = &NaiveDate::parse_from_str(date_str, "%Y-%m-%d")?;
  Ok(Local.from_local_date(naive_date).unwrap())
}

pub fn week_from_str_begin(date_str: &str) -> Result<Date<Local>,String> {
  let now = Local::now();
  if date_str == "toweek" || date_str == "thisweek" {
    return Ok(Local.isoywd(now.year(), now.iso_week().week(), Weekday::Mon));
  }
  if let Ok(date) = &NaiveDate::parse_from_str(&format!("{}-1", date_str), "%G-W%V-%u") {
    return Ok(Local.from_local_date(date).unwrap());
  }
  if let Ok(date) = &NaiveDate::parse_from_str(&format!("{}-{}-1", now.year(), date_str), "%G-W%V-%u") {
    return Ok(Local.from_local_date(date).unwrap());
  }
  Err("Could not parse '{}' as week".to_string())
}

pub fn week_from_str_end(date_str: &str) -> Result<Date<Local>,String> {
  let now = Local::now();
  if date_str == "toweek" || date_str == "thisweek"  {
    return Ok(Local.isoywd(now.year(), now.iso_week().week(), Weekday::Sun));
  }
  if let Ok(date) = &NaiveDate::parse_from_str(&format!("{}-7", date_str), "%G-W%V-%u") {
    return Ok(Local.from_local_date(date).unwrap());
  }
  if let Ok(date) = &NaiveDate::parse_from_str(&format!("{}-{}-7", now.year(), date_str), "%G-W%V-%u") {
    return Ok(Local.from_local_date(date).unwrap());
  }
  Err("Could not parse '{}' as week".to_string())
}

pub fn datetime_from_timestamp(timestamp: &str) -> Option<DateTime<Utc>> {
  let timestamp_i64 = timestamp.parse::<i64>().ok()?;
  let naive_datetime = NaiveDateTime::from_timestamp_opt(timestamp_i64, 0)?;
  Some(DateTime::from_utc(naive_datetime, Utc))
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn test_date_from_str() {
    let date = date_from_str("2018-12-10").unwrap();
    assert_eq!("2018-12-10", format!("{}", date.format("%F")));
    let date = date_from_str("today").unwrap();
    assert_eq!(Local::now().date(), date);
    let date = date_from_str("now").unwrap();
    assert_eq!(Local::now().date(), date);
  }

  #[test]
  #[should_panic]
  fn test_date_from_str_negative() {
    date_from_str("2018-02-30").unwrap();
  }

  #[test]
  fn test_week_from_str_begin() {
    let date = week_from_str_begin("2018-W50").unwrap();
    assert_eq!("2018-12-10", format!("{}", date.format("%F")));
    let date = week_from_str_begin("W50").unwrap();
    assert_eq!("2019-12-09", format!("{}", date.format("%F")));
  }

  #[test]
  fn test_week_from_str_begin_current_year() {
    // TODO test must be adapted once a year. hum.
    let date = week_from_str_begin("W50").unwrap();
    assert_eq!("2019-12-09", format!("{}", date.format("%F")));
  }

  #[test]
  #[should_panic]
  fn test_week_from_str_begin_neg() {
    week_from_str_begin("nonsense").unwrap();
  }

  #[test]
  fn test_week_from_str_end() {
    let date = week_from_str_end("W50").unwrap();
    assert_eq!("2019-12-15", format!("{}", date.format("%F")));
  }
  #[test]
  fn test_week_from_str_end_current_year() {
    // TODO test must be adapted once a year. hum.
    let date = week_from_str_end("W50").unwrap();
    assert_eq!("2019-12-15", format!("{}", date.format("%F")));
  }

  #[test]
  #[should_panic]
  fn test_week_from_str_end_neg() {
    week_from_str_end("nonsense").unwrap();
  }

  #[test]
  fn test_datetime_from_timestamp() {
    let timestamp = "1547234687";
    let dt_from_ts = datetime_from_timestamp(timestamp).unwrap();
    let dt = Utc.ymd(2019, 01, 11).and_hms(19, 24, 47);
    assert_eq!(dt, dt_from_ts);
  }
}