For an index to all my stories click this text
April 2023 I published a story on this weblog that showed how to get the right time with MicroPython. You can read that story here:
http://lucstechblog.blogspot.com/2023/04/getting-right-time-with-micropython.html
The provided solution gets the actual time from an NTP server. There is only a small problem with this. The NTP server gets the UTC time. UTC stands for Universal Time Coordinated which is the same as GMT. And I am living in the Netherlands which is at CEST which stands for Central European Summer Time.
And of course there is a time difference between UTC and CEST time. Normally that does not pose a problem. But then I had a question of one of the readers on this weblog. On my Discord server he asked how to write a program that performs a daily task every day at the same time.
The program I provided in that story about getting the right time, did not take time zones and summer and winter time (DST) adjustments in account.
So I had some work to do as I did not want to disappoint him.
Time zones.
As I can not now where you are located you do have to fill this in manually. You can find your timezone easily by googling it.
In the new program which you find below there are two lines that look like this:
#adjust for timezone Netherlands local_time = time.localtime(time.mktime(local_time) + 3600)
The Netherlands is in timezone UTC + 1 hour. This line adds 3600 seconds to the local_time which is one hour. If you are for example at timezone UTC+3 just alter 3600 in 3 * 3600 like this:
#adjust for timezone local_time = time.localtime(time.mktime(local_time) + (3 * 3600))
Summertime and Wintertime.
In Europe summertime and wintertime do not start each year at the same date. No that would make things too easy.
Summertime starts the last sunday in March
Wintertime starts the last sunday in October.
So how do I find the last sunday of march or october.
Find last Sunday
Well here is a small program with a function that finds the last sunday in any given year and month.
import time def find_last_sunday(year, month): last_sunday = 0 for week in range(25, 32): if time.localtime(time.mktime((year, month, week, 1, 0, 0, 0, 0, 0)))[6] == 6: last_sunday = week return last_sunday # Here is an example year = 2024 month = 10 print(find_last_sunday(year, month))
Try it yourself with different months and years. You'll see that the outcode is accurate.
You can adjust this for any day of the week by changing the number 6 into another number from 0 to 5 being:
0 = monday
1 = tuesday
2 = wednesday
3 = thursday
4 = friday
5 = monday
So if you want to check for the last wednesday in a month alter the code in:
import time def find_last_sunday(year, month): last_sunday = 0 for week in range(25, 32): if time.localtime(time.mktime((year, month, week, 1, 0, 0, 0, 0, 0)))[6] == 2: last_sunday = week return last_sunday # Here is an example year = 2024 month = 10 print(find_last_sunday(year, month))
Testing if date is in DST
The next step is to test if the current data is within the summertime (DST)
start = time.mktime((year, 3, dst_start, 1, 0, 0, 0, 0, 0)) end = time.mktime((year, 10, dst_end, 1, 0, 0, 0, 0, 0)) now = time.mktime(t) return start <= now < end
Let's have a look at that.
start = time.mktime((year, 3, dst_start, 1, 0, 0, 0, 0, 0))
This line converts the start date of DST into the number of seconds that passed since Jan first 2000 (epoch time). The converted figure is stored into the variable start.
The next line does the same for the end date of DST and stores that figure in the variable end.
And lastly the current date is stored into the variable now.
Then the program compares in one line if now is larger than start and smaller than end. If that is the case then TRUE is returned.
Now we need to add a line that tests if the function returns the value True, and if so an hour is added to the current time.
The complete code
This will (of course) only work on a microcontroller that has wifi like the Raspberry Pi Pico, ESP8266 or ESP32.
Next to that you will need to get the ntptime library which you can find here:
https://github.com/Lucvolders/MicroPython/blob/main/Libraries/NTPtime/ntptime.py
And here is the complete MicroPython code.
import network import ntptime import time import machine # Router credentials ssid = "YOUR-ROUTERS-NAME" pw = "PASSWORD" # wifi connection wifi = network.WLAN(network.STA_IF) wifi.active(True) wifi.connect(ssid, pw) # wait for connection print('Waiting for connection.',end="") while wifi.isconnected() == False: time.sleep(1) print('', end='.') print("") ip = wifi.ifconfig()[0] print("Connected with IP adress : "+ip) time.sleep(1) # Function to check if DST is in effect def is_dst_europe(t): year, month, day, hour, minute, second, weekday, yearday = t print(t) # Last Sunday in March dst_start = 0 for day in range(25, 32): if time.localtime(time.mktime((year, month, day, 1, 0, 0, 0, 0, 0)))[6] == 6: dst_start = day # Last Sunday in October dst_end = 0 for day in range(25, 32): if time.localtime(time.mktime((year, month, day, 1, 0, 0, 0, 0, 0)))[6] == 6: dst_end = day start = time.mktime((year, 3, dst_start, 1, 0, 0, 0, 0, 0)) end = time.mktime((year, 10, dst_end, 1, 0, 0, 0, 0, 0)) now = time.mktime(t) return start <= now < end rtc = machine.RTC() rtc.datetime((2000, 1, 1, 0, 0, 0, 00, 0)) print(time.localtime()) # Set the time from NTP server ntptime.settime() time.sleep(2) # Get the local time local_time = time.localtime() #adjust for timezone Netherlands local_time = time.localtime(time.mktime(local_time) + 3600) # Adjust for DST if necessary if is_dst_europe(local_time): local_time = time.localtime(time.mktime(local_time) + 3600) # Print the adjusted time print("Adjusted time:", local_time)
This gives us the right date and time adjusted for our timezone and DST.
Best thing to do is to turn this into a library for ease of use.
Till next time
have fun
Luc Volders