From 7bfa80cb0bd8a6fea0a0e68005f6b5503c30f08c Mon Sep 17 00:00:00 2001 From: houseme Date: Mon, 22 Jun 2026 13:53:56 +0800 Subject: [PATCH] fix(notify): normalize event time precision (#3725) --- crates/notify/src/event.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/crates/notify/src/event.rs b/crates/notify/src/event.rs index e3eb80a8e..76732002a 100644 --- a/crates/notify/src/event.rs +++ b/crates/notify/src/event.rs @@ -133,6 +133,7 @@ pub struct Event { /// The AWS region where the event occurred pub aws_region: String, /// The time when the event occurred + #[serde(serialize_with = "serialize_event_time_millis")] pub event_time: DateTime, /// The name of the event pub event_name: EventName, @@ -309,6 +310,13 @@ impl Event { } } +fn serialize_event_time_millis(value: &DateTime, serializer: S) -> Result +where + S: serde::Serializer, +{ + serializer.serialize_str(&value.to_rfc3339_opts(SecondsFormat::Millis, true)) +} + fn initialize_response_elements(elements: &mut HashMap, keys: &[&str]) { for key in keys { elements.entry(key.to_string()).or_default(); @@ -528,6 +536,15 @@ mod tests { assert_eq!(glacier.restore_event_data.lifecycle_restoration_expiry_time, "2023-11-14T22:13:20.000Z"); assert_eq!(glacier.restore_event_data.lifecycle_restore_storage_class, "GLACIER"); } + + #[test] + fn event_time_serializes_with_millisecond_precision() { + let mut event = Event::new_test_event("bucket", "key", EventName::ObjectCreatedPut); + event.event_time = DateTime::::from_timestamp(1_711_423_698, 870_816_000).expect("timestamp should be valid"); + + let json = serde_json::to_value(&event).expect("event should serialize"); + assert_eq!(json.get("eventTime").and_then(|value| value.as_str()), Some("2024-03-26T03:28:18.870Z")); + } } #[cfg(test)]