Skip to content

Commit

Permalink
implement Ord and PartialOrd for DateTime (#2653)
Browse files Browse the repository at this point in the history
## 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._
  • Loading branch information
henriiik authored Apr 27, 2023
1 parent a85cef6 commit 5a8fff7
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.next.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 44 additions & 0 deletions rust-runtime/aws-smithy-types/src/date_time/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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);
}
}

0 comments on commit 5a8fff7

Please sign in to comment.