Fix two bugs in _Timestamp.to_datetime and _Timestamp.from_datetime #534
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I've recently added some property based tests using hypothesis to a project using protobuf messages, which has lead me to discover two distinct bugs in the
_Timestamp.to_datetime
and_Timestamp.from_datetime
conversion function.I've narrowed it down to a basic test for the classic encode / decode invariant pattern, that looked like this:
This test found two failing examples:
datetime(2242, 12, 31, 23, 0, 0, 1, tzinfo=timezone.utc)
and
datetime(1969, 12, 31, 23, 0, 0, 1, tzinfo=timezone.utc)
Let's see whats going on:
Bug 1: Floating point precision error:
Bug 2: Negative timestamps:
The
_Timestamp
we get fromfrom_datetime
should already be one with:_Timestamp(seconds=-3600, nanos=1000)
. That this is the correct way to represent negative timestamps can also be read up here: https://protobuf.dev/reference/protobuf/google.protobuf/#timestampFix
I've implemented a fixed version of the two methods by calculating a
timedelta
from the unix start epoch and then calculating the total_microseconds (not floating point seconds) of that timedelta.I've also added a few test cases for this, but without using hypothesis (I didn't want to add a new dependency, even though property based testing could probably be a cool tool for this project). Instead I manually specified the failing examples from above.