Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CHANGELOG.next.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ references = ["smithy-rs#1929"]
meta = { "breaking" = false, "tada" = true, "bug" = false, "target" = "all"}
author = "Velfi"

[[smithy-rs]]
message = "aws_smithy_types_convert::date_time::DateTimeExt::to_chrono_utc returns a Result<>"
references = ["smithy-rs#1980"]
meta = { "breaking" = true, "tada" = false, "bug" = false, "target" = "all" }
author = "82marbag"

[[smithy-rs]]
message = "Fix cargo audit issue on chrono."
references = ["smithy-rs#1907"]
Expand Down Expand Up @@ -115,4 +121,3 @@ message = "Several breaking changes have been made to errors. See [the upgrade g
references = ["smithy-rs#1926", "smithy-rs#1819"]
meta = { "breaking" = true, "tada" = false, "bug" = false }
author = "jdisanti"

26 changes: 17 additions & 9 deletions rust-runtime/aws-smithy-types-convert/src/date_time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,15 @@ Then import [`DateTimeExt`] to use the conversions:
use aws_smithy_types_convert::date_time::DateTimeExt;
use chrono::{Utc};

let chrono_date_time: chrono::DateTime<Utc> = DateTime::from_secs(5).to_chrono_utc();
let chrono_date_time: chrono::DateTime<Utc> = DateTime::from_secs(5).to_chrono_utc().unwrap();
let date_time: DateTime = DateTime::from_chrono_utc(chrono_date_time);
```
"##
)]
pub trait DateTimeExt {
/// Converts a [`DateTime`] to a [`chrono::DateTime`] with timezone UTC.
#[cfg(feature = "convert-chrono")]
fn to_chrono_utc(&self) -> chrono::DateTime<chrono::Utc>;
fn to_chrono_utc(&self) -> Result<chrono::DateTime<chrono::Utc>, Error>;

/// Converts a [`chrono::DateTime`] with timezone UTC to a [`DateTime`].
#[cfg(feature = "convert-chrono")]
Expand All @@ -113,11 +113,19 @@ pub trait DateTimeExt {

impl DateTimeExt for DateTime {
#[cfg(feature = "convert-chrono")]
fn to_chrono_utc(&self) -> chrono::DateTime<chrono::Utc> {
chrono::DateTime::<chrono::Utc>::from_utc(
chrono::NaiveDateTime::from_timestamp(self.secs(), self.subsec_nanos()),
chrono::Utc,
)
fn to_chrono_utc(&self) -> Result<chrono::DateTime<chrono::Utc>, Error> {
match chrono::NaiveDateTime::from_timestamp_opt(self.secs(), self.subsec_nanos()) {
None => {
let err: Box<dyn StdError + Send + Sync + 'static> = format!(
"Out-of-range seconds {} or invalid nanoseconds {}",
self.secs(),
self.subsec_nanos()
)
.into();
Err(Error::OutOfRange(err))
}
Some(dt) => Ok(chrono::DateTime::<chrono::Utc>::from_utc(dt, chrono::Utc)),
}
}

#[cfg(feature = "convert-chrono")]
Expand Down Expand Up @@ -179,11 +187,11 @@ mod test {

let date_time = DateTime::from_str("2039-07-08T09:03:11.123Z", Format::DateTime).unwrap();
let expected = Utc.ymd(2039, 7, 8).and_hms_nano(9, 3, 11, 123_000_000);
assert_eq!(expected, date_time.to_chrono_utc());
assert_eq!(expected, date_time.to_chrono_utc().unwrap());

let date_time = DateTime::from_str("1000-07-08T09:03:11.456Z", Format::DateTime).unwrap();
let expected = Utc.ymd(1000, 7, 8).and_hms_nano(9, 3, 11, 456_000_000);
assert_eq!(expected, date_time.to_chrono_utc());
assert_eq!(expected, date_time.to_chrono_utc().unwrap());
}

#[test]
Expand Down