Notifications
Clear all

UTC to standard or daylight times conversion

10 Posts
2 Users
1 Likes
1,814 Views
(@jfabernathy)
Member
Joined: 3 years ago
Posts: 141
Topic starter  

I have a CircuitPython program running on an Adafruit Magtag board which has an eInk display. It displays some data it pulls from a database where the data is timestamped in UTC.  When I wrote the program it was winter time and to get the timezone right I subtracted 5 from my UTC time to get EST. Now it's spring and we are in EDT and I need to change the time to -4. I hate to have to do this twice a year.  I can't use any Linux functions since this is CP without an O/S.

Any ideas?

 

If your code won't compile, have another glass of bourbon. Eventual the problem will be solved.


   
Quote
MadMisha
(@madmisha)
Member
Joined: 4 years ago
Posts: 340
 

I am assuming you are using the built in RTC of the ESP32-S2. I was looking at ways to use gmtime and local time but then I ran across this library and realized it looks so much easier. Timezone Conversion Library  

 

I hope this helps. But I do have to ask, how fast is the updating on the e-ink display on that unit?


   
ReplyQuote
(@jfabernathy)
Member
Joined: 3 years ago
Posts: 141
Topic starter  

@madmisha Not using the RTC as I don't care what time it is. I care about the time in the database for the data I'm displaying. The only thing I have running an an ESP32-S2 is CircuitPython. Arduino and ESP-IDF are really flaky to me on the ESP32-S2.

I really haven't looked at the update time on the e-ink display of the Magtag.  My application wakes from deep sleep every 5 minutes and retrieves the latest temp and humidity from the influxDB where it's being recording and displays the latest readings. 

If your code won't compile, have another glass of bourbon. Eventual the problem will be solved.


   
ReplyQuote
MadMisha
(@madmisha)
Member
Joined: 4 years ago
Posts: 340
 

I wrote that and forgot in the middle of looking things up that you said you were using CircuitPython. Since I have never used it, I can only suggest things in Python that I hope will work. In Python you can use tzinfo and timezone to account for offsets from UTC and tzinfo can account for DST. Both are a part of the datetime library. Python Datetime reference link  If you actually can't use that one then it looks like Adafruit created their own library for circuit python that is based off of the full Python library. adafruit-circuitpython-datetime It does list the ESP32-S2 as being supported.

 

Edit:

Also, this guy made his own were he set the rules about when DST begins and ends. You could do the same with your UTC timestamp and if the date is between 2 dates then make this correction instead. https://emergent.unpythonic.net/01595021837

Edit 2:

The real pain is that fact that the make it something like the second Sunday of a certain month for the time change. That seems like the hardest bit. But, lets say you make a start list with tuples and a stop list of tuples. Each contains the year and date it starts or stops. Then a basic IF statement could be used based off the parsed data you get from the timestamp. Go at least 10 years in the future.


   
ReplyQuote
MadMisha
(@madmisha)
Member
Joined: 4 years ago
Posts: 340
 

   
ReplyQuote
(@jfabernathy)
Member
Joined: 3 years ago
Posts: 141
Topic starter  

@madmisha Thanks, I thought about hard coding it just like your example. Great minds think alike 😀 😀 

 

If your code won't compile, have another glass of bourbon. Eventual the problem will be solved.


   
ReplyQuote
MadMisha
(@madmisha)
Member
Joined: 4 years ago
Posts: 340
 

@jfabernathy

 

Although, now that switch case is coming to Python soon, that might change how I would do this a little.

I don't know how exactly that will work on circuit python/when it will be implemented there.


   
ReplyQuote
(@jfabernathy)
Member
Joined: 3 years ago
Posts: 141
Topic starter  

I came up with an algorithm that seems to work for me for EST to EDT using your dictionary approach.  What I have attached is a test program that I used to check out the corner cases.  It's fine for the spring forward, not sure if on the fallback if you repeat the 1-2 or at 3pm you go back to 2 which is what this code does.  Either way I'm asleep.

I wish I knew how to attach code so you could read it without losing the indents. Everytime I paste in the code it loses it's indention which is 4 spaces for each tab.

Here's the file renames to .txt.

If your code won't compile, have another glass of bourbon. Eventual the problem will be solved.


   
MadMisha reacted
ReplyQuote
MadMisha
(@madmisha)
Member
Joined: 4 years ago
Posts: 340
 

@jfabernathy

I believe both time changes happen at 2am, so technically your hours could say

        if month == 3 and day >= int(dstStart[year])+1 or month == 3 and day == int(dstStart[year]) and hour >= 2:
            timezoneOffset = 4
            
        elif month == 11 and day <= int(dstStop[year]):
            if day <= int(dstStop[year])-1 or day == int(dstStop[year]) and hour <= 2:

 

and it would be correct although the stop day would happen at 3:00am. But since you're asleep, I guess it won't matter. 6 and 7 am seems to me like it might give you a little confusion if you woke up early.

 

As for keeping the tabbing, I hit enter a bunch of time the to make sure there is plenty of space after what I paste and then paste. Sometimes it automatically detects it as code(as in it just did above, I don't remember seeing that happen before).


   
ReplyQuote
(@jfabernathy)
Member
Joined: 3 years ago
Posts: 141
Topic starter  
Posted by: @madmisha

@jfabernathy

I believe both time changes happen at 2am, so technically your hours could say

        if month == 3 and day >= int(dstStart[year])+1 or month == 3 and day == int(dstStart[year]) and hour >= 2:
            timezoneOffset = 4
            
        elif month == 11 and day <= int(dstStop[year]):
            if day <= int(dstStop[year])-1 or day == int(dstStop[year]) and hour <= 2:

 

and it would be correct although the stop day would happen at 3:00am. But since you're asleep, I guess it won't matter. 6 and 7 am seems to me like it might give you a little confusion if you woke up early.

 

As for keeping the tabbing, I hit enter a bunch of time the to make sure there is plenty of space after what I paste and then paste. Sometimes it automatically detects it as code(as in it just did above, I don't remember seeing that happen before).

I found that I needed the time condition to check against 6 or 7 because the time I'm comparing against is UTC so when I see 2 in the hour, it's not EST or EDT 2.  

Basically, the times I'm reading from the database are in UTC but they represent times of events recorded locally in the EST/EDT.  So if I was up at 2AM on the day when daylight saving time started, I see the raw time in UTC as 7am. i.e. the -5 delta that becomes a -4 delta at that precise hour.

This is really an overkill project.  All I need to see the current data is to open a browser on any device in my house and look at the grafana chart I created for all sites temp and humidity data that is being recorded every minute.  grafana is part of my IOTstack and is running on Rasberry Pi OS so it takes care of the time for me. 

However, I had an Adafruit Magtag ESP32-S2 with e-ink display that needed something to do to earn it's keep. So it wakes from deep sleep every 5 minutes and uses http to submit a JSON get to my Nodered hub that causes it to send a query to my influxdb to retrieve the latest reading for one of my remote locations.

The only way I can think of to make it more complicated is to build a robot to ride around and collect the data. 😀  

the project is on github so I can keep from losing all the work:

https://github.com/jfabernathy/MQTT-humidity-and-temperature

If your code won't compile, have another glass of bourbon. Eventual the problem will be solved.


   
ReplyQuote