This repository was archived by the owner on Oct 29, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 524
Fixing rounding errors when inserting microseconds #407
Closed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
When calculating nanoseconds since EPOCH, `total_seconds()` will give a float representation which when multiplied by 1e9 and cast to `int` will create rounding errors. E.g. inserting `2017-01-17T08:00:12.000001` with a datetime will produce `2017-01-17T08:00:12.000001024Z` in InfluxDB. This commit fixes this by never going via floating seconds, and is based on the `total_seconds()` function itself.
xginn8
suggested changes
Apr 22, 2017
influxdb/line_protocol.py
Outdated
@@ -16,6 +16,12 @@ | |||
EPOCH = UTC.localize(datetime.utcfromtimestamp(0)) | |||
|
|||
|
|||
def _to_nanos(timestamp): | |||
delta = timestamp - EPOCH | |||
nanos = (delta.days * 86400 + delta.seconds) * 10 ** 9 + delta.microseconds * 10 ** 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this line fails flake8 (89 chars), mind splitting it up? otherwise, this looks like a good change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The `_to_nanos` function had a line which was too long.
xginn8
approved these changes
May 7, 2017
Just encountered this rounding error and was about to submit this very patch. In order to ensure that ns stays an int I would also rewrite: if precision is None or precision == 'n':
return ns
elif precision == 'u':
return ns / 1e3
elif precision == 'ms':
return ns / 1e6
elif precision == 's':
return ns / 1e9
elif precision == 'm':
return ns / 1e9 / 60
elif precision == 'h':
return ns / 1e9 / 3600 to if precision is None or precision == 'n':
return ns
elif precision == 'u':
return ns / 10**3
elif precision == 'ms':
return ns / 10**6
elif precision == 's':
return ns / 10**9
elif precision == 'm':
return ns / 10**9 / 60
elif precision == 'h':
return ns / 10**9 / 3600 |
It would probably allow you to close some of those: |
Re-addressed in a new PR that merges this content including fixes from @clslgrnc |
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
When calculating nanoseconds since EPOCH,
total_seconds()
will give a float representation which when multiplied by 1e9 and cast toint
will create rounding errors. E.g. inserting2017-01-17T08:00:12.000001
with a datetime will produce2017-01-17T08:00:12.000001024Z
in InfluxDB. This commit fixes this by never going via floating seconds, and is based on thetotal_seconds()
function itself.