Skip to content

Commit

Permalink
Avoid precision drop in timestamp conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
sug0 committed Jun 18, 2024
1 parent a66136e commit ee22856
Showing 1 changed file with 27 additions and 5 deletions.
32 changes: 27 additions & 5 deletions crates/core/src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,35 @@ impl From<DateTime<Utc>> for DateTimeUtc {
}

impl TryFrom<prost_types::Timestamp> for DateTimeUtc {
type Error = prost_types::TimestampError;
type Error = String;

fn try_from(
timestamp: prost_types::Timestamp,
) -> Result<Self, Self::Error> {
let system_time: std::time::SystemTime = timestamp.try_into()?;
Ok(Self(system_time.into()))
let seconds = timestamp.seconds;
let nanoseconds: u32 = timestamp.nanos.try_into().map_err(|err| {
format!(
"Failed to convert prost_types::Timestamp nanos {} to u32: \
{err}",
timestamp.nanos
)
})?;

let parsed = {
use chrono::format;

let mut p = format::Parsed::new();

p.nanosecond = Some(nanoseconds);
p.timestamp = Some(seconds);
p
};

let dt = parsed.to_datetime_with_timezone(&Utc).map_err(|err| {
format!("Failed to parse {parsed:?} as a chrono::DateTime: {err}")
})?;

Ok(Self(dt))
}
}

Expand All @@ -316,7 +338,7 @@ impl From<DateTimeUtc> for prost_types::Timestamp {
impl TryFrom<crate::tendermint_proto::google::protobuf::Timestamp>
for DateTimeUtc
{
type Error = prost_types::TimestampError;
type Error = String;

fn try_from(
timestamp: crate::tendermint_proto::google::protobuf::Timestamp,
Expand Down Expand Up @@ -357,7 +379,7 @@ impl TryFrom<DateTimeUtc> for crate::tendermint::time::Time {
}

impl TryFrom<crate::tendermint::time::Time> for DateTimeUtc {
type Error = prost_types::TimestampError;
type Error = String;

fn try_from(t: crate::tendermint::time::Time) -> Result<Self, Self::Error> {
crate::tendermint_proto::google::protobuf::Timestamp::from(t).try_into()
Expand Down

0 comments on commit ee22856

Please sign in to comment.