Page 1 of 2

Using local time with Pico W

Posted: Sat Jul 16, 2022 12:08 pm
by ebolisa
Hi,

I noticed the ntptime lib is not included with the uOS for the Raspberry Pico W version.
Is there a way to get around it to obtain the local time?

TIA

Re: Using local time with Pico W

Posted: Sat Jul 16, 2022 12:43 pm
by pythoncoder
Firstly MicroPython doesn't support timezones. However you can get UTC and convert it to local time yourself.

Copy ntptime.py to the Pico W filesystem and use it as follows:

Code: Select all

>>> time.localtime(ntptime.time() + 946702080)
(2022, 7, 16, 17, 25, 50, 5, 197)
Note the factor 946702080 which is 30 year's worth of seconds. This is because the epoch for ESP8266 is 2000 while that for RP2 is 1970.

To correct for TZ just add or subtract N years worth of seconds.

Re: Using local time with Pico W

Posted: Sat Jul 16, 2022 12:58 pm
by Roberthh
You can as well use the ntptime.py referenced by @pythoncoder and change in line 10:

NTP_DELTA = 2208988800 #

and use nptime.settime().

@pythoncoder: I might be wrong, but calculating the difference between 1.1.2000 - 1.1.1970 using LibreOffice Calc returns here 946702080 seconds. And using your code causes an overflow error. Probably you mean:

Code: Select all

time.localtime(ntptime.time() - 946684800)

Re: Using local time with Pico W

Posted: Sat Jul 16, 2022 1:01 pm
by ebolisa
Thank you!

Re: Using local time with Pico W

Posted: Sun Jul 17, 2022 3:19 pm
by pythoncoder
Roberthh wrote:
Sat Jul 16, 2022 12:58 pm
...
@pythoncoder: I might be wrong, but calculating the difference between 1.1.2000 - 1.1.1970 using LibreOffice Calc returns here 946702080 seconds. And using your code causes an overflow error. Probably you mean:

Code: Select all

time.localtime(ntptime.time() - 946684800)
I realised in the early hours of this morning that I'd got my sums wrong: the number should indeed be 946684800.

But I do think addition is correct. The NTP query returns seconds from 1900 to now, and the library subtracts an offset to shift the datum to 2000. This offset is too large if our epoch is to be 1970 so we need to add an offset. This is borne out by the following on my Pico W which is cut and pasted verbatim:

Code: Select all

>>> time.localtime(ntptime.time() + 946684800)
(2022, 7, 17, 14, 58, 43, 6, 198)
Subtraction produces a ridiculous result from the start of the swinging sixties ;)

Re: Using local time with Pico W

Posted: Sun Jul 17, 2022 4:35 pm
by Roberthh
You're right. Using the ntptime.py from the esp8266 port, one has to add 946684800.
Besides that, I changed the module into NTP_DELTA = 2208988800, which is the seconds difference between 1.1.1970 and 1.1.1900.

Re: Using local time with Pico W

Posted: Mon Jul 18, 2022 12:37 pm
by pythoncoder
Here is a version of ntptime.py which is platform-independent. Tested on Unix, ESP8266, Pico W. It also allows for a local time offset. Hopefully it will be of use to someone ;)

Code: Select all

import socket
import struct
from time import gmtime

# (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60
# (date(1970, 1, 1) - date(1900, 1, 1)).days * 24*60*60
NTP_DELTA = 3155673600 if gmtime(0)[0] == 2000 else 2208988800

# The NTP host can be configured at runtime by doing: ntptime.host = 'myhost.org'
host = "pool.ntp.org"

def time(hrs_offset=0):  # Local time offset in hrs relative to UTC
    NTP_QUERY = bytearray(48)
    NTP_QUERY[0] = 0x1B
    addr = socket.getaddrinfo(host, 123)[0][-1]
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        s.settimeout(1)
        res = s.sendto(NTP_QUERY, addr)
        msg = s.recv(48)
    finally:
        s.close()
    val = struct.unpack("!I", msg[40:44])[0]
    return val - NTP_DELTA + hrs_offset * 3600
Sadly a platform-independent way of setting the RTC will have to wait for a portable RTC class :(

Re: Using local time with Pico W

Posted: Wed Jul 27, 2022 10:00 am
by pythoncoder
Updated version here. This adds portability by using select.poll rather than deprecated socket timeouts (see docs).

Re: Using local time with Pico W

Posted: Wed Jul 27, 2022 1:34 pm
by Jibun no kage
@Peter, where is the example? Of how to use select.poll? Oh... the 'here' is link. Missed that!

Re: Using local time with Pico W

Posted: Wed Jul 27, 2022 2:24 pm
by p_j
I haven't tested it out but I believe datetime with tz support was added to micropython-lib a few months ago?

https://github.com/micropython/micropyt ... b/datetime