timezone support in MicroPython ?
-
- Posts: 2
- Joined: Wed Sep 05, 2018 1:21 pm
Re: timezone support in MicroPython ? DST/EST
def dstTime():
year = time.localtime()[0] #get current year
# print(year)
HHMarch = time.mktime((year,3 ,(14-(int(5*year/4+1))%7),1,0,0,0,0,0)) #Time of March change to DST
HHNovember = time.mktime((year,10,(7-(int(5*year/4+1))%7),1,0,0,0,0,0)) #Time of October change to EST
# print(HHNovember)
now=time.time()
if now < HHMarch : # we are before last sunday of march
dst=time.localtime(now-18000) # EST: UTC-5H
elif now < HHNovember : # we are before last sunday of october
dst=time.localtime(now-14400) # DST: UTC-4H
else: # we are after last sunday of october
dst=time.localtime(now-18000) # EST: UTC-5H
return(dst)
year = time.localtime()[0] #get current year
# print(year)
HHMarch = time.mktime((year,3 ,(14-(int(5*year/4+1))%7),1,0,0,0,0,0)) #Time of March change to DST
HHNovember = time.mktime((year,10,(7-(int(5*year/4+1))%7),1,0,0,0,0,0)) #Time of October change to EST
# print(HHNovember)
now=time.time()
if now < HHMarch : # we are before last sunday of march
dst=time.localtime(now-18000) # EST: UTC-5H
elif now < HHNovember : # we are before last sunday of october
dst=time.localtime(now-14400) # DST: UTC-4H
else: # we are after last sunday of october
dst=time.localtime(now-18000) # EST: UTC-5H
return(dst)
Re: timezone support in MicroPython ?
Easiest way I found is changing ntptimes internal NTP_DELTA Variable, so it calculates it right.
Run ntptime.settime() after boardinit to have the correct time before execution.
Get tuple afterwards with utime.localtime()
Run ntptime.settime() after boardinit to have the correct time before execution.
Get tuple afterwards with utime.localtime()
Code: Select all
def getntptime(timer):
year = utime.localtime()[0] #get current year
now=ntptime.time()
HHMarch = utime.mktime((year,3 ,(31-(int(5*year/4+4))%7),1,0,0,0,0,0)) #Time of March change to CEST
HHOctober = utime.mktime((year,10,(31-(int(5*year/4+1))%7),1,0,0,0,0,0)) #Time of October change to CET
if now < HHMarch : # we are before last sunday of march
ntptime.NTP_DELTA = 3155673600-3600 # CET: UTC+1H
elif now < HHOctober : # we are before last sunday of october
ntptime.NTP_DELTA = 3155673600-7200 # CEST: UTC+2H
else: # we are after last sunday of october
ntptime.NTP_DELTA = 3155673600-3600 # CET: UTC+1H
ntptime.settime() # set the rtc datetime from the remote server
Re: timezone support in MicroPython ?
Great workaround!kwtf wrote: ↑Fri Apr 03, 2020 10:14 amEasiest way I found is changing ntptimes internal NTP_DELTA Variable, so it calculates it right.
Run ntptime.settime() after boardinit to have the correct time before execution.
Get tuple afterwards with utime.localtime()
Code: Select all
def getntptime(timer): year = utime.localtime()[0] #get current year now=ntptime.time() HHMarch = utime.mktime((year,3 ,(31-(int(5*year/4+4))%7),1,0,0,0,0,0)) #Time of March change to CEST HHOctober = utime.mktime((year,10,(31-(int(5*year/4+1))%7),1,0,0,0,0,0)) #Time of October change to CET if now < HHMarch : # we are before last sunday of march ntptime.NTP_DELTA = 3155673600-3600 # CET: UTC+1H elif now < HHOctober : # we are before last sunday of october ntptime.NTP_DELTA = 3155673600-7200 # CEST: UTC+2H else: # we are after last sunday of october ntptime.NTP_DELTA = 3155673600-3600 # CET: UTC+1H ntptime.settime() # set the rtc datetime from the remote server
Please, can you tell why I get this error:
" File "ntptime.py", line 35, in settime
OverflowError: overflow converting long int to machine word"
When I run it on my ESP 8266 NODEMCU?
Thanks for your time!
Re: timezone support in MicroPython ?
Same error here.
Code: Select all
File "ntptime.py", line 35, in settime
OverflowError: overflow converting long int to machine word
- pythoncoder
- Posts: 4940
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: timezone support in MicroPython ?
What firmware are you guys using? I can't replicate this with firmware built today.
Peter Hinch
Re: timezone support in MicroPython ?
kwtf,
Thanks for posting your solution.
Unfortunately, NZ change back to NZST on the first Sunday in April at 3AM, which left me wondering if:
would be correct. I couldn't find any Google hits on what appears to be a "magic" formula:
Did find some information suggesting that Robert Harry van Gent was responsible for the CET forumlaes but searched all around his website without finding out how to calculate the mday number.
Can someone post a link to how to work this out?
Thanks.
Thanks for posting your solution.
Unfortunately, NZ change back to NZST on the first Sunday in April at 3AM, which left me wondering if:
Code: Select all
HHApril = utime.mktime((year,4,(7-(int(5*year/4+4))%7),3,0,0,0,0,0))
Code: Select all
31-(int(5*year/4+4))%7
Can someone post a link to how to work this out?
Thanks.
-
- Posts: 1
- Joined: Sun Oct 11, 2020 9:58 pm
Re: timezone support in MicroPython ?
the timzone had not bothered me with my projects until i made a neopixel clock and we switched to daylight savings recently.
So this is what I have come up with for my timezone calculations based on the input from the earlier posts by davef and enzo
The different months, March, April, September and October / first and last sunday all have a different offsets based so you will need to play around with those for your timezone. This has have been check against https://www.timeanddate.com/ for the NZ timezone up to 2030.
there is probably some additions that could be included but this met my needs for now
https://en.wikipedia.org/wiki/List_of_UTC_time_offsets
https://www.iana.org/time-zones
I basically run this code on boot, and once a day to keep the RTC in sync correctly
So this is what I have come up with for my timezone calculations based on the input from the earlier posts by davef and enzo
The different months, March, April, September and October / first and last sunday all have a different offsets based so you will need to play around with those for your timezone. This has have been check against https://www.timeanddate.com/ for the NZ timezone up to 2030.
there is probably some additions that could be included but this met my needs for now
https://en.wikipedia.org/wiki/List_of_UTC_time_offsets
https://www.iana.org/time-zones
I basically run this code on boot, and once a day to keep the RTC in sync correctly
Code: Select all
# ###################################################################### #
# Set RTC localTime from UTC and apply DST offset
# Requires import machine, utime, ntptime
# assumes active network, otherwise will raise error whch is not currently dealt with
# Note: dstOffset should be between -12 and +14
# ###################################################################### #
def setLocalTime ( dstOffset ):
# get the YEAR to use in calculation
year, month, day, hour, minute, second, ms, dayinyear = utime.localtime()
if year < 2020:
# probably just booted, so get the time for calculation
now=ntptime.time()
# reload current time
year, month, day, hour, minute, second, ms, dayinyear = utime.localtime()
# szTime = "{:4}-{:02}-{:02} {:02}:{:02}:{:02}".format( year, month, day, hour, minute, second )
# print( "Time : " , szTime )
# define DST change dates for this year
# NZDT Starts : 2:00 Last Sunday September
dstDT = utime.mktime((year, 9, (30 -(int(5*year/4+4))%7),2,0,0,0,0,0)) #Time of September change to NZDT
# NZST Starts : 3:00 1st Sunday April
dstST = utime.mktime((year, 4, ( 7 -(int(5*year/4+5))%7),3,0,0,0,0,0)) #Time of April change to NZST
if dstOffset >= 0 : #
# print( "Positive DST timezones" )
if now > dstST and now < dstDT:
# print( "Standard Time")
ntptime.NTP_DELTA = 3155673600-( dstOffset * 3600)
else:
# print( "Daylight Time")
ntptime.NTP_DELTA = 3155673600-( (dstOffset+1) * 3600)
else:
# print( "Negative DST timezones" )
if now > dstDT and now < dstST :
# print( "Standard Time")
ntptime.NTP_DELTA = 3155673600-( dstOffset * 3600)
else:
# print( "Daylight Time")
ntptime.NTP_DELTA = 3155673600-( (dstOffset+1) * 3600)
# set the RTC to correct time
ntptime.settime()
# year, month, day, hour, minute, second, ms, dayinyear = utime.localtime()
# szTime = "{:4}-{:02}-{:02} {:02}:{:02}:{:02}".format( year, month, day, hour, minute, second )
# print( "setTime : " , szTime )
-
- Posts: 67
- Joined: Fri Sep 04, 2020 9:27 am
- Location: Hanko, Finland
- Contact:
Re: timezone support in MicroPython ?
I made this for Finland. I fixed second last in date tuple to 6, because 0 is Monday. TIMEZONE_DIFFERENCE is normal (winter) time difference, like 2 for Finland.Stephen Betts wrote: ↑Thu Oct 22, 2020 8:38 amthe timzone had not bothered me with my projects until i made a neopixel clock and we switched to daylight savings recently.
So this is what I have come up with for my timezone calculations based on the input from the earlier posts by davef and enzo
The different months, March, April, September and October / first and last sunday all have a different offsets based so you will need to play around with those for your timezone. This has have been check against https://www.timeanddate.com/ for the NZ timezone up to 2030.
there is probably some additions that could be included but this met my needs for now
https://en.wikipedia.org/wiki/List_of_UTC_time_offsets
https://www.iana.org/time-zones
I basically run this code on boot, and once a day to keep the RTC in sync correctly
Code: Select all
# ###################################################################### # # Set RTC localTime from UTC and apply DST offset # Requires import machine, utime, ntptime # assumes active network, otherwise will raise error whch is not currently dealt with # Note: dstOffset should be between -12 and +14 # ###################################################################### # def setLocalTime ( dstOffset ): # get the YEAR to use in calculation year, month, day, hour, minute, second, ms, dayinyear = utime.localtime() if year < 2020: # probably just booted, so get the time for calculation now=ntptime.time() # reload current time year, month, day, hour, minute, second, ms, dayinyear = utime.localtime() # szTime = "{:4}-{:02}-{:02} {:02}:{:02}:{:02}".format( year, month, day, hour, minute, second ) # print( "Time : " , szTime ) # define DST change dates for this year # NZDT Starts : 2:00 Last Sunday September dstDT = utime.mktime((year, 9, (30 -(int(5*year/4+4))%7),2,0,0,0,0,0)) #Time of September change to NZDT # NZST Starts : 3:00 1st Sunday April dstST = utime.mktime((year, 4, ( 7 -(int(5*year/4+5))%7),3,0,0,0,0,0)) #Time of April change to NZST if dstOffset >= 0 : # # print( "Positive DST timezones" ) if now > dstST and now < dstDT: # print( "Standard Time") ntptime.NTP_DELTA = 3155673600-( dstOffset * 3600) else: # print( "Daylight Time") ntptime.NTP_DELTA = 3155673600-( (dstOffset+1) * 3600) else: # print( "Negative DST timezones" ) if now > dstDT and now < dstST : # print( "Standard Time") ntptime.NTP_DELTA = 3155673600-( dstOffset * 3600) else: # print( "Daylight Time") ntptime.NTP_DELTA = 3155673600-( (dstOffset+1) * 3600) # set the RTC to correct time ntptime.settime() # year, month, day, hour, minute, second, ms, dayinyear = utime.localtime() # szTime = "{:4}-{:02}-{:02} {:02}:{:02}:{:02}".format( year, month, day, hour, minute, second ) # print( "setTime : " , szTime )
Global dst_on is needed for Suntime calculation, perhaps I change it so that timezone is not actually needed.
Code: Select all
def resolve_dst_and_set_time():
global TIMEZONE_DIFFERENCE
global dst_on
# This is most stupid thing what humans can do!
# Rules for Finland: DST ON: March last Sunday at 03:00 + 1h, DST OFF: October last Sunday at 04:00 - 1h
# Sets localtime to DST localtime
if network.WLAN(network.STA_IF).config('essid') == '':
now = mktime(localtime())
if DEBUG_ENABLED == 1:
print("Network down! Can not set time from NTP!")
else:
now = ntptime.time()
(year, month, mdate, hour, minute, second, wday, yday) = localtime(now)
if year < 2020:
if DEBUG_ENABLED == 1:
print("Time not set correctly!")
return False
dstend = mktime((year, 10, (31 - (int(5 * year / 4 + 1)) % 7), 4, 0, 0, 0, 6, 0))
dstbegin = mktime((year, 3, (31 - (int(5 * year / 4 + 4)) % 7), 3, 0, 0, 0, 6, 0)))
if TIMEZONE_DIFFERENCE >= 0:
if (now > dstbegin) and (now < dstend):
dst_on = True
ntptime.NTP_DELTA = 3155673600 - ((TIMEZONE_DIFFERENCE + 1) * 3600)
else:
dst_on = False
ntptime.NTP_DELTA = 3155673600 - (TIMEZONE_DIFFERENCE * 3600)
else:
if (now > dstend) and (now < dstbegin):
dst_on = False
ntptime.NTP_DELTA = 3155673600 - (TIMEZONE_DIFFERENCE * 3600)
else:
dst_on = True
ntptime.NTP_DELTA = 3155673600 - ((TIMEZONE_DIFFERENCE + 1) * 3600)
if dst_on is None:
if DEBUG_ENABLED == 1:
print("DST calculation failed!")
return False
else:
ntptime.settime()
-
- Posts: 67
- Joined: Fri Sep 04, 2020 9:27 am
- Location: Hanko, Finland
- Contact:
Re: timezone support in MicroPython ?
npttime.settime() error overflow converting long int to machine wordpythoncoder wrote: ↑Wed Aug 19, 2020 12:45 pmWhat firmware are you guys using? I can't replicate this with firmware built today.
with ESP32, sys.version = 3.4.0
esp32-idf4-20200902-v1.13.bin
How to repeat? Execute multiple times ntptime.settime()
>>> ntptime.settime()
>>> ntptime.settime()
>>> ntptime.settime()
>>> ntptime.settime()
>>> ntptime.settime()
>>> ntptime.settime()
>>> ntptime.settime()
>>> ntptime.settime()
>>> ntptime.settime()
>>> ntptime.settime()
>>> ntptime.settime()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "ntptime.py", line 39, in settime
OverflowError: overflow converting long int to machine word
>>> ntptime.settime()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "ntptime.py", line 35, in settime
File "ntptime.py", line 25, in time
OSError: [Errno 110] ETIMEDOUT
>>> ntptime.settime()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "ntptime.py", line 35, in settime
File "ntptime.py", line 25, in time
OSError: [Errno 110] ETIMEDOUT
>>> ntptime.settime()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "ntptime.py", line 35, in settime
File "ntptime.py", line 25, in time
OSError: [Errno 110] ETIMEDOUT
-----
Not related to ntphosts:
>>> ntptime.host = 'test.nothin.com'
>>> ntptime.settime()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "ntptime.py", line 35, in settime
File "ntptime.py", line 20, in time
OSError: -202
>>>
>>>
>>>
>>> resolve_dst_and_set_time()
NTP time not set! Error -202
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "main.py", line 322, in resolve_dst_and_set_time
ValueError:
>>> resolve_dst_and_set_time()
NTP time not set! Error -202
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "main.py", line 322, in resolve_dst_and_set_time
ValueError:
>>> resolve_dst_and_set_time()
NTP time not set! Error -202
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "main.py", line 322, in resolve_dst_and_set_time
ValueError:
>>> ntptime.host = 'pool.ntp.org'
>>> resolve_dst_and_set_time()
>>> resolve_dst_and_set_time()
>>> ntptime.settime()
>>> ntptime.settime()
>>> localtime()
(2021, 2, 28, 10, 30, 40, 6, 59)
----
trying this:
Code: Select all
n = 0
while (settime_complete is False) and (n <= 20):
if n >= 20:
f4.write("npttime.settime() tried 20 times. Giving up\n")
f4.close()
reset()
else:
try:
ntptime.settime()
except Exception as e:
n += 1
# npttime.settime() error overflow converting long int to machine word
f4.write("npttime.settime() error %s\n" % e)
sleep(10)
settime_complete = True