Skip to main content

rbytes_rust_util/
datetime.rs

1use chrono::{DateTime, Local, Utc, NaiveDate, NaiveDateTime, NaiveTime, ParseError};
2
3/// Retorna a data e hora atual em UTC.
4pub fn now_utc() -> DateTime<Utc> {
5    Utc::now()
6}
7
8/// Retorna a data e hora atual no horário local.
9pub fn now_local() -> DateTime<Local> {
10    Local::now()
11}
12
13/// Formata uma data/hora para string no formato "YYYY-MM-DD HH:MM:SS".
14pub fn format_datetime(dt: &NaiveDateTime) -> String {
15    dt.format("%Y-%m-%d %H:%M:%S").to_string()
16}
17
18/// Faz o parse de uma string para NaiveDateTime no formato "YYYY-MM-DD HH:MM:SS".
19pub fn parse_datetime(s: &str) -> Result<NaiveDateTime, ParseError> {
20    NaiveDateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S")
21}
22
23/// Faz o parse de uma string para NaiveDate no formato "YYYY-MM-DD".
24pub fn parse_date(s: &str) -> Result<NaiveDate, ParseError> {
25    NaiveDate::parse_from_str(s, "%Y-%m-%d")
26}
27
28/// Faz o parse de uma string para NaiveTime no formato "HH:MM:SS".
29pub fn parse_time(s: &str) -> Result<NaiveTime, ParseError> {
30    NaiveTime::parse_from_str(s, "%H:%M:%S")
31}
32
33///retorna o número de dias entre duas datas
34pub fn days_between_dates(start: &str, end: &str) -> Result<i64, chrono::ParseError> {
35    let start_date = chrono::NaiveDate::parse_from_str(start, "%Y-%m-%d")?;
36    let end_date = chrono::NaiveDate::parse_from_str(end, "%Y-%m-%d")?;
37    Ok((end_date - start_date).num_days())
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43    use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
44
45    #[test]
46    fn test_now_utc_and_local() {
47        let utc = now_utc();
48        let local = now_local();
49        // Apenas verifica se não está vazio
50        assert!(!utc.to_string().is_empty());
51        assert!(!local.to_string().is_empty());
52    }
53
54    #[test]
55    fn test_format_and_parse_datetime() {
56        let s = "2024-04-25 15:30:00";
57        let dt = parse_datetime(s).unwrap();
58        assert_eq!(format_datetime(&dt), s);
59    }
60
61    #[test]
62    fn test_parse_date() {
63        let s = "2024-04-25";
64        let date = parse_date(s).unwrap();
65        assert_eq!(date, NaiveDate::from_ymd_opt(2024, 4, 25).unwrap());
66    }
67
68    #[test]
69    fn test_parse_time() {
70        let s = "15:30:00";
71        let time = parse_time(s).unwrap();
72        assert_eq!(time, NaiveTime::from_hms_opt(15, 30, 0).unwrap());
73    }
74
75    #[test]
76    fn test_dias_entre_datas_validas() {
77        // Caso básico
78        assert_eq!(days_between_dates("2023-01-01", "2023-01-10").unwrap(), 9);
79        
80        // Mesmo dia
81        assert_eq!(days_between_dates("2023-05-15", "2023-05-15").unwrap(), 0);
82        
83        // Ordem inversa (deve retornar negativo)
84        assert_eq!(days_between_dates("2023-12-31", "2023-01-01").unwrap(), -364);
85        
86        // Ano bissexto
87        assert_eq!(days_between_dates("2020-02-28", "2020-03-01").unwrap(), 2);
88    }
89
90    #[test]
91    fn test_formatos_invalidos() {
92        // Formato incorreto
93        assert!(days_between_dates("01-01-2023", "2023-01-10").is_err());
94        
95        // Data inexistente
96        assert!(days_between_dates("2023-02-30", "2023-03-01").is_err());
97        
98        // String vazia
99        assert!(days_between_dates("", "2023-01-01").is_err());
100    }
101
102}