NTP time with timezone and DST adjustement #11173
Replies: 6 comments 4 replies
-
Not on every MicroPython platform, though. Hence the checks. |
Beta Was this translation helpful? Give feedback.
-
I don't know does this help, but I just wrote for ESP32 this script:
Idea is to keep system RTC on GMT/UTC updated from the satellite and then on the display show correct time based on DST. I am testing this in this [script] (https://github.com/divergentti/Micropython-for-ESP32/blob/main/esp32-gps-oled-bme680/main.py) |
Beta Was this translation helpful? Give feedback.
-
I wrote a little function for finding the time in Sydney AU. It uses +10 & +11 hrs for the winter / summer offsets & 3am Apr 1st / 2am Oct 1st as the local changeover times but should work for other offsets / change over times with a few edits.
|
Beta Was this translation helpful? Give feedback.
-
I have a small function that returns CET (Central European Time) from time.localtime() # This code returns the Central European Time (CET) including daylight saving
# Winter (CET) is UTC+1H Summer (CEST) is UTC+2H
# Changes happen last Sundays of March (CEST) and October (CET) at 01:00 UTC
# Ref. formulas : http://www.webexhibits.org/daylightsaving/i.html
# Since 1996, valid through 2099
import time
def cettime():
year = time.localtime()[0] #get current year
HHMarch = time.mktime((year,3 ,(31-(int(5*year/4+4))%7),1,0,0,0,0,0)) #Time of March change to CEST
HHOctober = time.mktime((year,10,(31-(int(5*year/4+1))%7),1,0,0,0,0,0)) #Time of October change to CET
now=time.time()
if now < HHMarch : # we are before last sunday of march
cet=time.localtime(now+3600) # CET: UTC+1H
elif now < HHOctober : # we are before last sunday of october
cet=time.localtime(now+7200) # CEST: UTC+2H
else: # we are after last sunday of october
cet=time.localtime(now+3600) # CET: UTC+1H
return(cet) Exemple: >>> from time import localtime
>>> localtime()
(2023, 6, 2, 16, 2, 37, 4, 153)
>>> from MyCetTime import cettime
>>> cettime()
(2023, 6, 2, 18, 3, 7, 4, 153)
>>> |
Beta Was this translation helpful? Give feedback.
-
If you set the RTC to a timezone other than UTC, you will break every existing function that promises to return UTC (like A better solution would be to use the offset only where the function says it would return local time. I have a module import time
TZ_OFFSET = 0
def localtime(secs=None):
"""Convert the time secs expressed in seconds since the Epoch into an 8-tuple which contains: (year, month, mday, hour, minute, second, weekday, yearday) If secs is not provided or None, then the current time from the RTC is used."""
return time.localtime((secs if secs else time.time()) + TZ_OFFSET) |
Beta Was this translation helpful? Give feedback.
-
I agree with @MrEbbinghaus, but why not take it a bit futher. In my projects I have used the abillity to extend a standard library. That way replacing the standard time.localtime() with an own version that returns the local time of my region (Sweden), including the change to/from daylight saving time. That will make the localtime function available to all modules that uses the standard time.localtime() function. My import sys
# Replace standard time.localtime()
#
# For more information about extending built in libraries, see:
# https://docs.micropython.org/en/latest/library/index.html#extending-built-in-libraries-from-python
_path = sys.path
sys.path = ()
try:
from time import *
finally:
sys.path = _path
del _path
def localtime(secs: int | None = None) -> tuple[int, int, int, int, int, int, int, int]:
"""Returns Swedish local time.
According to [Wikipedia](https://en.wikipedia.org/wiki/Time_in_Sweden)
does Sweden observe daylight saving time
from: the last Sunday in March (02:00 CET)
to: the last Sunday in October (03:00 CEST)
"""
def last_sunday(year: int, month: int, hour: int, minute: int) -> int:
"""Get the time of the last sunday of the month
It returns an integer which is the number of seconds since Jan 1, 2000, just like mktime().
"""
# Get the UTC time of the last day of the month
seconds = mktime((year, month + 1, 0, hour, minute, 0, None, None))
# Calculate the offset to the last sunday of the month
(year, month, mday, hour, minute, second, weekday, yearday) = gmtime(seconds)
offset = (weekday + 1) % 7
# Return the time of the last sunday of the month
return mktime((year, month, mday - offset, hour, minute, second, None, None))
utc = gmtime(secs)
# Find start date for daylight saving, i.e. last Sunday in March (01:00 UTC)
start_secs = last_sunday(year=utc[0], month=3, hour=1, minute=0)
# Find stop date for daylight saving, i.e. last Sunday in October (01:00 UTC)
stop_secs = last_sunday(year=utc[0], month=10, hour=1, minute=0)
utc_secs = mktime(utc)
if utc_secs >= start_secs and utc_secs < stop_secs:
delta_secs = 2 * 60 * 60 # Swedish summer time (CEST or UTC + 2h)
else:
delta_secs = 1 * 60 * 60 # Swedish normal time (CET or UTC + 1h)
return gmtime(utc_secs + delta_secs) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi,
Based on: ntptime.py
and: Dutch DST begin/end datetimes
I wrote my own version that accepts a UTC offset(timezone) and adjusts for DST. DST adjustment is done by checking if the current UTC is within a DST-range for each year (2021-2037). The code is below.
There is one thing I don't completely understand though.
I would appreciate if someone could explain the following piece of code.
I know Epoch starts at 1970.01.01 00:00
But where does 'NTP_DELTA' calculated on 1900, 1970 and 2000 come from?
Thanks.
My code:
Beta Was this translation helpful? Give feedback.
All reactions