adafruit / Adafruit_CircuitPython_AdafruitIO

Adafruit IO for CircuitPython
http://io.adafruit.com
MIT License
49 stars 33 forks source link

IP-based time using io.receive_time() returning UTC #95

Closed kattni closed 2 hours ago

kattni commented 1 year ago

The AdafruitIO library does not provide the option to provide the tz parameter to specify timezone, which is the first thing IO looks for to return a time when using io.receive_time().

The second thing IO tries is "guessing" your timezone based on your IP address. This does not appear to be working; it is instead defaulting to UTC.

The final thing IO does is return UTC, which as said above, is happening regardless.

I tested it on a Feather ESP32-S3 TFT board, using CircuitPython 8.0.0-beta.4 and this library. I get UTC from io.receive_time(), every time.

cc: @brentru @lorennorman @jwcooper

That said, in my project code, I received a workaround for this issue from @jepler in the form of a class in my code. This really only helps if you want to make a workaround in this library, versus fixing the feature in IO itself. But I thought it was worth including either way.

class TZIO(IO_HTTP):
    def receive_time(self, tz='UTC'):
        """
        Returns a struct_time from the Adafruit IO Server based on the time zone
.
        https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/__init__.html#time.struct_time
        """
        path = self._compose_path("integrations/time/struct.json?tz={}".format(tz))
        time_struct = self._get(path)
        return time.struct_time(
            (
                time_struct["year"],
                time_struct["mon"],
                time_struct["mday"],
                time_struct["hour"],
                time_struct["min"],
                time_struct["sec"],
                time_struct["wday"],
                time_struct["yday"],
                time_struct["isdst"],
            )
        )

Which is used when instantiating the io object as follows:

io = TZIO(AIO_USER, AIO_KEY, requests)
kattni commented 1 year ago

So..... I checked it again, and io.receive_time() is returning ET, which is accurate for me. Not sure what to make of that. It was definitely not working last Wednesday for myself, or Liz (which is to say it wasn't a me-issue).

I'm leaving this open in case it's an intermittent bug. Feel free to close it if you think it was a glitch.

caternuson commented 1 year ago

Possibly related? https://forums.adafruit.com/viewtopic.php?p=985703#p985703

tyeth commented 3 months ago

Just to note I've added an optional timezone argument to the io.receive_time method as part of another PR, so maybe this can be closed by #124, although this issue appears to be more about the incorrect autodetection.

The timezone/tz argument is left off of the request by default so still uses a timezone based on geo-location mapping for the clients IP address, and that falls back to UTC on lookup failure. Separately one can now supply the timezone argument and request "UTC" or "GB", "NZ" etc in accordance with the time service docs https://io.adafruit.com/services/time [must be logged in] or effectively this TZ list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

FoamyGuy commented 2 hours ago

I tested on a Feather S3 TFT and a PicoW with 9.2.0 calling io.receive_time() with no timezone argument and on both devices I get back my current local time in the correct timezone.

That along with the flexibility to pass in a desired timezone argument now is enough to consider this resolved for me. Please feel free to re-open or create new issue if anyone is still having this issue.