opendata-stuttgart / meta

Opendata Stuttgart organisiert und reguliert.
124 stars 20 forks source link

How to manage sensor timezone in API? #143

Open tommasosansone91 opened 4 years ago

tommasosansone91 commented 4 years ago

I am building an app in Django making requests to https://data.sensor.community/static/v2/data.json, parsing the content, and then exctracting data only from sensor within certain areas (I implemented a custom filter working on downloaded data). However, from the API, I get the timestamp with 2 hours of delay with respect to my timezone (Europe/Berlin / UTC+1). What could be the problem?

In Django settings I have:

TIME_ZONE = 'Europe/Berlin'

USE_I18N = True

USE_L10N = True

USE_TZ = True

Time settings with just my app should be fine, because when I get time from timezone.now() I get the exact time of my timezone (Europe/Berlin / UTC+1).

ricki-z commented 4 years ago

All sensor data has timestamps in UTC. This is easier to handle as we don't have to think about summer/winter time or the timezones of sensors.

ricki-z commented 4 years ago

And actually Berlin has the time CEST (Central European Summer Time, UTC+2).

tommasosansone91 commented 4 years ago

To whoever might need it, here is some code that helps to deal with time translation from one timezone to another and from non-summertime (default server setting) to summertime.

# translates date_and_time_input registered in timezone tz1 into time and date valid for timezone t2 and returns it as dt
def convert_datetime_timezone(date_and_time_input, tz1, tz2):
    tz1 = pytz.timezone(tz1)
    tz2 = pytz.timezone(tz2)
    dt = datetime.datetime.strptime(date_and_time_input,"%Y-%m-%d %H:%M:%S")
    dt = tz1.localize(dt)
    dt = dt.astimezone(tz2)
    dt = dt.strftime("%Y-%m-%d %H:%M:%S")
    return dt

# adds one hour to the date_and_time_input and returns it as dt
def add_one_hour(date_and_time_input):
    dt = convert_datetime_timezone(date_and_time_input, "Europe/London", "Europe/Berlin")
    return dt

# gets the timestamp from luftdaten api https://data.sensor.community/static/v2/data.json
timestamp_value = sensor['timestamp']

timestamp_value = convert_datetime_timezone(timestamp_value, "Europe/London", "Europe/Berlin")      

# check if summertime is active on the machine where this script is running              
if time.localtime().tm_isdst != 0:
    timestamp_value = add_one_hour(timestamp_value)
buckfast-beekeeper commented 4 years ago

The easiest way is to leave database data in UTC. UTC is identical over the whole world. From normal time to daylight saving in spring, there isn't a problem. There is a gap from one hour but it doesn't destroy the data. From daylight saving to normal time there is a problem. You have twice data between 2:00 and 3:00. A query with ordering on time, should be give wrong data order. Ordering on id is not good practice. First rule for a database, the order of the records in the database make no difference for the result query.

Maybe this problem is a non issue end of 2021 if the change is definitive history.