From 451817e9e0f709b53bdb0a8cb4b2f8a0bd01997d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Christoffer=20Andersen?= Date: Tue, 17 Jan 2017 15:49:50 +0100 Subject: [PATCH 1/2] Fixing rounding errors when inserting microseconds 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. --- influxdb/line_protocol.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/influxdb/line_protocol.py b/influxdb/line_protocol.py index 7c8c8f24..ba41b4ea 100644 --- a/influxdb/line_protocol.py +++ b/influxdb/line_protocol.py @@ -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 + return nanos + + def _convert_timestamp(timestamp, precision=None): if isinstance(timestamp, Integral): return timestamp # assume precision is correct if timestamp is int @@ -24,7 +30,7 @@ def _convert_timestamp(timestamp, precision=None): if isinstance(timestamp, datetime): if not timestamp.tzinfo: timestamp = UTC.localize(timestamp) - ns = (timestamp - EPOCH).total_seconds() * 1e9 + ns = _to_nanos(timestamp) if precision is None or precision == 'n': return ns elif precision == 'u': From 01bc900a9e2f4dde1471f56cdcf34a9394e04d1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Christoffer=20Andersen?= Date: Wed, 26 Apr 2017 03:21:54 +0200 Subject: [PATCH 2/2] Fixing flake8 (89 chars) in `_to_nanos` The `_to_nanos` function had a line which was too long. --- influxdb/line_protocol.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/influxdb/line_protocol.py b/influxdb/line_protocol.py index ba41b4ea..677a085c 100644 --- a/influxdb/line_protocol.py +++ b/influxdb/line_protocol.py @@ -18,8 +18,10 @@ def _to_nanos(timestamp): delta = timestamp - EPOCH - nanos = (delta.days * 86400 + delta.seconds) * 10 ** 9 + delta.microseconds * 10 ** 3 - return nanos + nanos_in_days = delta.days * 86400 * 10 ** 9 + nanos_in_seconds = delta.seconds * 10 ** 9 + nanos_in_micros = delta.microseconds * 10 ** 3 + return nanos_in_days + nanos_in_seconds + nanos_in_micros def _convert_timestamp(timestamp, precision=None):