16
16
*
17
17
*/
18
18
19
- use chrono:: { DateTime , NaiveDate , NaiveDateTime , TimeDelta , Timelike , Utc } ;
19
+ use chrono:: { DateTime , Datelike , NaiveDate , NaiveDateTime , TimeDelta , TimeZone , Timelike , Utc } ;
20
20
21
21
#[ derive( Debug , thiserror:: Error ) ]
22
22
pub enum TimeParseError {
@@ -78,8 +78,8 @@ impl TimeRange {
78
78
/// let range = TimeRange::parse_human_time("2023-01-01T12:00:00Z", "2023-01-01T15:00:00Z");
79
79
/// ```
80
80
pub fn parse_human_time ( start_time : & str , end_time : & str ) -> Result < Self , TimeParseError > {
81
- let start: DateTime < Utc > ;
82
- let end: DateTime < Utc > ;
81
+ let mut start: DateTime < Utc > ;
82
+ let mut end: DateTime < Utc > ;
83
83
84
84
if end_time == "now" {
85
85
end = Utc :: now ( ) ;
@@ -89,6 +89,11 @@ impl TimeRange {
89
89
end = DateTime :: parse_from_rfc3339 ( end_time) ?. into ( ) ;
90
90
} ;
91
91
92
+ // Truncate seconds, milliseconds, and nanoseconds to zero
93
+ // to ensure that the time range is aligned to the minute
94
+ start = truncate_to_minute ( start) ;
95
+ end = truncate_to_minute ( end) ;
96
+
92
97
if start > end {
93
98
return Err ( TimeParseError :: StartTimeAfterEndTime ) ;
94
99
}
@@ -287,6 +292,19 @@ impl TimeRange {
287
292
}
288
293
}
289
294
295
+ pub fn truncate_to_minute ( dt : DateTime < Utc > ) -> DateTime < Utc > {
296
+ // Get the date and time components we want to keep
297
+ let year = dt. year ( ) ;
298
+ let month = dt. month ( ) ;
299
+ let day = dt. day ( ) ;
300
+ let hour = dt. hour ( ) ;
301
+ let minute = dt. minute ( ) ;
302
+
303
+ // Create a new DateTime with seconds, milliseconds, and nanoseconds set to 0
304
+ Utc . with_ymd_and_hms ( year, month, day, hour, minute, 0 )
305
+ . unwrap ( ) // This should never fail with valid components
306
+ }
307
+
290
308
/// Represents a minute value (0-59) and provides methods for converting it to a slot range.
291
309
///
292
310
/// # Examples
0 commit comments