@@ -5,7 +5,7 @@ use crate::{
5
5
iso:: { IsoDate , IsoDateSlots , IsoDateTime , IsoTime } ,
6
6
options:: {
7
7
ArithmeticOverflow , DifferenceOperation , DifferenceSettings , ResolvedRoundingOptions ,
8
- TemporalUnit ,
8
+ RoundingOptions , TemporalUnit ,
9
9
} ,
10
10
parsers:: parse_date_time,
11
11
temporal_assert, Sign , TemporalError , TemporalResult , TemporalUnwrap ,
@@ -463,6 +463,19 @@ impl DateTime {
463
463
pub fn since ( & self , other : & Self , settings : DifferenceSettings ) -> TemporalResult < Duration > {
464
464
self . diff ( DifferenceOperation :: Since , other, settings)
465
465
}
466
+
467
+ /// Rounds the current datetime based on provided options.
468
+ pub fn round ( & self , options : RoundingOptions ) -> TemporalResult < Self > {
469
+ let resolved = ResolvedRoundingOptions :: from_dt_options ( options) ?;
470
+
471
+ if resolved. is_noop ( ) {
472
+ return Ok ( self . clone ( ) ) ;
473
+ }
474
+
475
+ let result = self . iso . round ( resolved) ?;
476
+
477
+ Ok ( Self :: new_unchecked ( result, self . calendar . clone ( ) ) )
478
+ }
466
479
}
467
480
468
481
// ==== Trait impls ====
@@ -530,7 +543,10 @@ mod tests {
530
543
use crate :: {
531
544
components:: { calendar:: Calendar , duration:: DateDuration , Duration } ,
532
545
iso:: { IsoDate , IsoTime } ,
533
- options:: { DifferenceSettings , RoundingIncrement , TemporalRoundingMode , TemporalUnit } ,
546
+ options:: {
547
+ DifferenceSettings , RoundingIncrement , RoundingOptions , TemporalRoundingMode ,
548
+ TemporalUnit ,
549
+ } ,
534
550
primitive:: FiniteF64 ,
535
551
} ;
536
552
@@ -716,4 +732,60 @@ mod tests {
716
732
assert_eq ! ( result. hours( ) , 4.0 ) ;
717
733
assert_eq ! ( result. minutes( ) , 30.0 ) ;
718
734
}
735
+
736
+ #[ test]
737
+ fn dt_round_basic ( ) {
738
+ let assert_datetime = |dt : DateTime , expected : ( i32 , u8 , u8 , u8 , u8 , u8 , u16 , u16 , u16 ) | {
739
+ assert_eq ! ( dt. iso_year( ) , expected. 0 ) ;
740
+ assert_eq ! ( dt. iso_month( ) , expected. 1 ) ;
741
+ assert_eq ! ( dt. iso_day( ) , expected. 2 ) ;
742
+ assert_eq ! ( dt. hour( ) , expected. 3 ) ;
743
+ assert_eq ! ( dt. minute( ) , expected. 4 ) ;
744
+ assert_eq ! ( dt. second( ) , expected. 5 ) ;
745
+ assert_eq ! ( dt. millisecond( ) , expected. 6 ) ;
746
+ assert_eq ! ( dt. microsecond( ) , expected. 7 ) ;
747
+ assert_eq ! ( dt. nanosecond( ) , expected. 8 ) ;
748
+ } ;
749
+
750
+ let gen_rounding_options = |smallest : TemporalUnit , increment : u32 | -> RoundingOptions {
751
+ RoundingOptions {
752
+ largest_unit : None ,
753
+ smallest_unit : Some ( smallest) ,
754
+ increment : Some ( RoundingIncrement :: try_new ( increment) . unwrap ( ) ) ,
755
+ rounding_mode : None ,
756
+ }
757
+ } ;
758
+ let dt =
759
+ DateTime :: new ( 1976 , 11 , 18 , 14 , 23 , 30 , 123 , 456 , 789 , Calendar :: default ( ) ) . unwrap ( ) ;
760
+
761
+ let result = dt
762
+ . round ( gen_rounding_options ( TemporalUnit :: Hour , 4 ) )
763
+ . unwrap ( ) ;
764
+ assert_datetime ( result, ( 1976 , 11 , 18 , 16 , 0 , 0 , 0 , 0 , 0 ) ) ;
765
+
766
+ let result = dt
767
+ . round ( gen_rounding_options ( TemporalUnit :: Minute , 15 ) )
768
+ . unwrap ( ) ;
769
+ assert_datetime ( result, ( 1976 , 11 , 18 , 14 , 30 , 0 , 0 , 0 , 0 ) ) ;
770
+
771
+ let result = dt
772
+ . round ( gen_rounding_options ( TemporalUnit :: Second , 30 ) )
773
+ . unwrap ( ) ;
774
+ assert_datetime ( result, ( 1976 , 11 , 18 , 14 , 23 , 30 , 0 , 0 , 0 ) ) ;
775
+
776
+ let result = dt
777
+ . round ( gen_rounding_options ( TemporalUnit :: Millisecond , 10 ) )
778
+ . unwrap ( ) ;
779
+ assert_datetime ( result, ( 1976 , 11 , 18 , 14 , 23 , 30 , 120 , 0 , 0 ) ) ;
780
+
781
+ let result = dt
782
+ . round ( gen_rounding_options ( TemporalUnit :: Microsecond , 10 ) )
783
+ . unwrap ( ) ;
784
+ assert_datetime ( result, ( 1976 , 11 , 18 , 14 , 23 , 30 , 123 , 460 , 0 ) ) ;
785
+
786
+ let result = dt
787
+ . round ( gen_rounding_options ( TemporalUnit :: Nanosecond , 10 ) )
788
+ . unwrap ( ) ;
789
+ assert_datetime ( result, ( 1976 , 11 , 18 , 14 , 23 , 30 , 123 , 456 , 790 ) ) ;
790
+ }
719
791
}
0 commit comments