Using local time with Pico W
Using local time with Pico W
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
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
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Using local time with Pico W
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:
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.
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)
To correct for TZ just add or subtract N years worth of seconds.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Using local time with Pico W
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:
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
Thank you!
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Using local time with Pico W
I realised in the early hours of this morning that I'd got my sums wrong: the number should indeed be 946684800.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)
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)
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Using local time with Pico W
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.
Besides that, I changed the module into NTP_DELTA = 2208988800, which is the seconds difference between 1.1.1970 and 1.1.1900.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Using local time with Pico W
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
Sadly a platform-independent way of setting the RTC will have to wait for a portable RTC class
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
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Using local time with Pico W
Updated version here. This adds portability by using select.poll rather than deprecated socket timeouts (see docs).
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
-
- Posts: 144
- Joined: Mon Jul 25, 2022 9:45 pm
Re: Using local time with Pico W
@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
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
https://github.com/micropython/micropyt ... b/datetime