Skip to content

Preserve sub-second precision when serializing unixTimestamp parameters - #10644

Open
jonathan343 wants to merge 1 commit into
aws:v2from
jonathan343:preserve-subsecond-timestamps
Open

jonathan343 wants to merge 1 commit into
aws:v2from
jonathan343:preserve-subsecond-timestamps

Conversation

@jonathan343

@jonathan343 jonathan343 commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Overview

Ports boto/botocore#3796 and fixes the CLI v2 equivalent of boto/botocore#3255.

CLI v2's vendored botocore serializes unixTimestamp request parameters as int(calendar.timegm(...)), dropping any sub-second precision the caller provided. This affects every json, rest-json, and smithy-rpc-v2-cbor body timestamp. iso8601 has always carried microseconds, and rfc822 (HTTP-date) only supports whole seconds, so only the epoch-seconds format had this issue.

This PR preserves the caller's sub-second precision for unixTimestamp. Whole-second timestamps serialize exactly as before.

The CBOR serializer now emits a tagged float64 for fractional timestamps and delegates integer encoding to the shared integer serializer, which also fixes an OverflowError for pre-1970 timestamps.

Testing

Reproduced the scenario from boto/botocore#3255 with kinesis-video-archived-media list-fragments, pointed at an unreachable endpoint so --debug logs the serialized body before the send fails:

aws kinesis-video-archived-media list-fragments \
  --stream-name some-stream \
  --fragment-selector '{
    "FragmentSelectorType": "PRODUCER_TIMESTAMP",
    "TimestampRange": {
      "StartTimestamp": "2024-09-12T10:49:36.500000Z",
      "EndTimestamp": "2024-09-12T10:49:38.833000Z"
    }
  }' \
  --debug 2>&1 | grep -o "'body': b'[^']*'"

Before (v2):

'body': b'{"StreamName": "some-stream", "FragmentSelector": {"FragmentSelectorType": "PRODUCER_TIMESTAMP", "TimestampRange": {"StartTimestamp": 1726138176, "EndTimestamp": 1726138178}}}'

After:

'body': b'{"StreamName": "some-stream", "FragmentSelector": {"FragmentSelectorType": "PRODUCER_TIMESTAMP", "TimestampRange": {"StartTimestamp": 1726138176.5, "EndTimestamp": 1726138178.833}}}'

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Serialize unixTimestamp request parameters with the full sub-second
precision the caller provided instead of truncating to whole seconds.
Timestamps with a fractional component are now emitted as a fractional
value (e.g. 1704110400.123456); whole-second timestamps are unchanged.

Ports boto/botocore#3796.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused implementation preserves compatibility for whole-second values and includes coverage for fractional and pre-epoch timestamps.

Pull request overview

Preserves fractional precision for Unix timestamp request parameters while retaining integer output for whole seconds.

Changes:

  • Serializes fractional Unix timestamps without truncation.
  • Supports fractional and negative timestamps in CBOR.
  • Adds precision and encoding regression tests.
File summaries
File Description
awscli/botocore/serialize.py Updates Unix timestamp and CBOR serialization.
tests/unit/botocore/test_serialize.py Adds timestamp precision and CBOR tests.
.changes/next-release/bugfix-Serialization-52170.json Documents the serialization fix.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 0
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

self.UNSIGNED_INT_MAJOR_TYPE, timestamp
)
serialized.extend(initial_byte)
# Tag 1 permits either an integer or a floating-point epoch seconds

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code seems fine. just for my understanding why did we have all the _get_additional_info_and_num_bytes logic before and why can it be removed now?

@jonathan343 jonathan343 Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _serialize_type_integer we now use calls the same _get_additional_info_and_num_bytes helper under the hood. I'm honestly not sure why this wasn't called in the initial implementation.

But the current behavior is incorrect since we can't serialize negative timestamps. A timestamp value like datetime(1968, 12, 31, 23, 59, 59) currently results in a OverflowError: can't convert negative int to unsigned error which this new approach addresses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants