diff --git a/CHANGES.rst b/CHANGES.rst index 19f5792..01433a1 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -9,6 +9,11 @@ in progress - CI: Update to Grafana 9.3.0 - DAQ: Mask ``PASSKEY`` variable coming from HTTP, emitted by Ecowitt +Breaking changes +---------------- + +- DAQ: Obtain naive timestamps as UTC by default, instead of CET + .. _kotori-0.27.0: diff --git a/kotori/io/protocol/util.py b/kotori/io/protocol/util.py index 71553f4..6ab1803 100644 --- a/kotori/io/protocol/util.py +++ b/kotori/io/protocol/util.py @@ -4,7 +4,7 @@ import arrow import datetime from six import text_type -from dateutil.tz import gettz +from dateutil.tz import gettz, tzutc from dateutil.parser import parse from pyramid.settings import asbool from twisted.web import http @@ -177,23 +177,27 @@ def slugify_datettime(dstring): return arrow.get(dstring).to('utc').format('YYYYMMDDTHHmmss') -def parse_timestamp(timestamp): +def parse_timestamp(timestamp, use_utc=False): if isinstance(timestamp, text_type): # FIXME: Maybe use system timezone here by default. # TODO: Make configurable via channel settings. - # HACK: Assume CET (Europe/Berlin) for human readable timestamp w/o timezone offset + # Handle naive human-readable timestamps w/o timezone offset. qualified = any([token in timestamp for token in ['Z', '+', ' CET', ' CEST']]) if not qualified: - timestamp += ' CET' + # Assume CET (Europe/Berlin) (default), or UTC. + if use_utc: + timestamp += ' UTC' + else: + timestamp += ' CET' # Parse datetime string # Remark: Maybe use pandas.tseries.tools.parse_time_string? # TODO: Cache results of call to gettz to improve performance berlin = gettz('Europe/Berlin') - tzinfos = {'CET': berlin, 'CEST': berlin} + tzinfos = {'UTC': tzutc(), 'CET': berlin, 'CEST': berlin} timestamp = parse(timestamp, tzinfos=tzinfos) return timestamp diff --git a/test/test_ecowitt.py b/test/test_ecowitt.py index 01bf99d..31146e1 100644 --- a/test/test_ecowitt.py +++ b/test/test_ecowitt.py @@ -1,4 +1,6 @@ import json + +from kotori.io.protocol.util import parse_timestamp from test.settings.mqttkit import PROCESS_DELAY_HTTP, influx_sensors, settings from test.util import http_form_sensor, sleep @@ -85,4 +87,8 @@ def test_ecowitt_post(machinery, create_influxdb, reset_influxdb): # Make sure this will not be public. assert "PASSKEY" not in record + # Make sure decoding the timestamp works. + print(record["time"]) + assert parse_timestamp(record["time"]) == parse_timestamp("2023-02-20 16:02:19", use_utc=True) + yield record