Unverified Commit 5a8fff7a authored by Henrik Sjööh's avatar Henrik Sjööh Committed by GitHub
Browse files

implement `Ord` and `PartialOrd` for `DateTime` (#2653)

## Motivation and Context

This change will allow easy sorting or comparing anything that contains
a DateTime. My example is wanting to sort a list of S3 objects by last
modified.

This PR fixes #2406

## Description
It's a pretty small PR, it implements the `Ord` trait for `DateTime` by
comparing the `seconds` property of `self` and `other`, if they are
equal it compares the `subsec_nanos` properties instead.

The `PartialOrd` trait is implemented by calling the `Ord` trait.

## Testing
I added a unit test that compares a number of `DateTime` values with
different combinations of positive/zero/negative
`seconds`/`subsec_nanos`.

## Checklist
- [x] I have updated `CHANGELOG.next.toml` if I made changes to the AWS
SDK, generated SDK code, or SDK runtime crates

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent a85cef6d
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -17,3 +17,9 @@ author = "rcoh"
references = ["smithy-rs#2612"]
meta = { "breaking" = false, "tada" = false, "bug" = false }


[[smithy-rs]]
message = "Implement `Ord` and `PartialOrd` for `DateTime`."
author = "henriiik"
references = ["smithy-rs#2653"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
+44 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ use crate::date_time::format::rfc3339::AllowOffsets;
use crate::date_time::format::DateTimeParseErrorKind;
use num_integer::div_mod_floor;
use num_integer::Integer;
use std::cmp::Ordering;
use std::convert::TryFrom;
use std::error::Error as StdError;
use std::fmt;
@@ -301,6 +302,21 @@ impl From<SystemTime> for DateTime {
    }
}

impl PartialOrd for DateTime {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for DateTime {
    fn cmp(&self, other: &Self) -> Ordering {
        match self.seconds.cmp(&other.seconds) {
            Ordering::Equal => self.subsecond_nanos.cmp(&other.subsecond_nanos),
            ordering => ordering,
        }
    }
}

/// Failure to convert a `DateTime` to or from another type.
#[derive(Debug)]
#[non_exhaustive]
@@ -552,4 +568,32 @@ mod test {
            SystemTime::try_from(date_time).unwrap()
        );
    }

    #[test]
    fn ord() {
        let first = DateTime::from_secs_and_nanos(-1, 0);
        let second = DateTime::from_secs_and_nanos(0, 0);
        let third = DateTime::from_secs_and_nanos(0, 1);
        let fourth = DateTime::from_secs_and_nanos(1, 0);

        assert!(first == first);
        assert!(first < second);
        assert!(first < third);
        assert!(first < fourth);

        assert!(second > first);
        assert!(second == second);
        assert!(second < third);
        assert!(second < fourth);

        assert!(third > first);
        assert!(third > second);
        assert!(third == third);
        assert!(third < fourth);

        assert!(fourth > first);
        assert!(fourth > second);
        assert!(fourth > third);
        assert!(fourth == fourth);
    }
}