@@ -250,6 +250,10 @@ pub fn make_now(
250250 }
251251}
252252
253+ fn quarter_month ( date : & NaiveDateTime ) -> u32 {
254+ 1 + 3 * ( ( date. month ( ) - 1 ) / 3 )
255+ }
256+
253257fn date_trunc_single ( granularity : & str , value : i64 ) -> Result < i64 > {
254258 let value = timestamp_ns_to_datetime ( value) . with_nanosecond ( 0 ) ;
255259 let value = match granularity {
@@ -272,6 +276,12 @@ fn date_trunc_single(granularity: &str, value: i64) -> Result<i64> {
272276 . and_then ( |d| d. with_minute ( 0 ) )
273277 . and_then ( |d| d. with_hour ( 0 ) )
274278 . and_then ( |d| d. with_day0 ( 0 ) ) ,
279+ "quarter" => value
280+ . and_then ( |d| d. with_second ( 0 ) )
281+ . and_then ( |d| d. with_minute ( 0 ) )
282+ . and_then ( |d| d. with_hour ( 0 ) )
283+ . and_then ( |d| d. with_day0 ( 0 ) )
284+ . and_then ( |d| d. with_month ( quarter_month ( & d) ) ) ,
275285 "year" => value
276286 . and_then ( |d| d. with_second ( 0 ) )
277287 . and_then ( |d| d. with_minute ( 0 ) )
@@ -495,6 +505,7 @@ mod tests {
495505 "year" ,
496506 "2020-01-01T00:00:00.000000Z" ,
497507 ) ,
508+ // week
498509 (
499510 "2021-01-01T13:42:29.190855Z" ,
500511 "week" ,
@@ -505,13 +516,49 @@ mod tests {
505516 "week" ,
506517 "2019-12-30T00:00:00.000000Z" ,
507518 ) ,
519+ // quarter
520+ (
521+ "2020-01-01T13:42:29.190855Z" ,
522+ "quarter" ,
523+ "2020-01-01T00:00:00.000000Z" ,
524+ ) ,
525+ (
526+ "2020-02-01T13:42:29.190855Z" ,
527+ "quarter" ,
528+ "2020-01-01T00:00:00.000000Z" ,
529+ ) ,
530+ (
531+ "2020-03-01T13:42:29.190855Z" ,
532+ "quarter" ,
533+ "2020-01-01T00:00:00.000000Z" ,
534+ ) ,
535+ (
536+ "2020-04-01T13:42:29.190855Z" ,
537+ "quarter" ,
538+ "2020-04-01T00:00:00.000000Z" ,
539+ ) ,
540+ (
541+ "2020-08-01T13:42:29.190855Z" ,
542+ "quarter" ,
543+ "2020-07-01T00:00:00.000000Z" ,
544+ ) ,
545+ (
546+ "2020-11-01T13:42:29.190855Z" ,
547+ "quarter" ,
548+ "2020-10-01T00:00:00.000000Z" ,
549+ ) ,
550+ (
551+ "2020-12-01T13:42:29.190855Z" ,
552+ "quarter" ,
553+ "2020-10-01T00:00:00.000000Z" ,
554+ ) ,
508555 ] ;
509556
510557 cases. iter ( ) . for_each ( |( original, granularity, expected) | {
511- let original = string_to_timestamp_nanos ( original) . unwrap ( ) ;
512- let expected = string_to_timestamp_nanos ( expected) . unwrap ( ) ;
513- let result = date_trunc_single ( granularity, original ) . unwrap ( ) ;
514- assert_eq ! ( result, expected) ;
558+ let left = string_to_timestamp_nanos ( original) . unwrap ( ) ;
559+ let right = string_to_timestamp_nanos ( expected) . unwrap ( ) ;
560+ let result = date_trunc_single ( granularity, left ) . unwrap ( ) ;
561+ assert_eq ! ( result, right , "{} = {}" , original , expected) ;
515562 } ) ;
516563 }
517564
0 commit comments