Added Daylight Savings Time offset calculation
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
@@ -84,6 +84,47 @@ def calculate_x_spacing(text, scale=1):
|
||||
return (128 - (scaled_text * 8)) // 2
|
||||
|
||||
|
||||
def is_dst(year, month, day, hour_utc, weekday):
|
||||
"""
|
||||
Returns True if UTC time falls within US/Canada Daylight Saving Time:
|
||||
- Starts: 2nd Sunday in March at 02:00 local (07:00 UTC for UTC-5)
|
||||
- Ends: 1st Sunday in November at 02:00 local (06:00 UTC for UTC-4)
|
||||
Note: weekday is 0=Monday ... 6=Sunday.
|
||||
"""
|
||||
# 1. Months completely inside or outside DST
|
||||
if month < 3 or month > 11:
|
||||
return False
|
||||
if 3 < month < 11:
|
||||
return True
|
||||
|
||||
# 2. March (Starts 2nd Sunday)
|
||||
# The 2nd Sunday always falls between March 8 and March 14
|
||||
if month == 3:
|
||||
# Find the day of the 2nd Sunday
|
||||
second_sunday = 14 - ((weekday - day + 14) % 7)
|
||||
if day < second_sunday:
|
||||
return False
|
||||
elif day > second_sunday:
|
||||
return True
|
||||
else:
|
||||
# On the transition day itself, 02:00 EST is 07:00 UTC
|
||||
return hour_utc >= 7
|
||||
|
||||
# 3. November (Ends 1st Sunday)
|
||||
# The 1st Sunday always falls between Nov 1 and Nov 7
|
||||
if month == 11:
|
||||
first_sunday = 7 - ((weekday - day + 7) % 7)
|
||||
if day < first_sunday:
|
||||
return True
|
||||
elif day > first_sunday:
|
||||
return False
|
||||
else:
|
||||
# On the transition day itself, 02:00 EDT (01:00 EST) is 06:00 UTC
|
||||
return hour_utc < 6
|
||||
|
||||
return False
|
||||
|
||||
|
||||
# --- Main Loop ---
|
||||
DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
|
||||
TIME_Y = 12 # Keep vertical placement consistent
|
||||
@@ -91,14 +132,25 @@ TIME_Y = 12 # Keep vertical placement consistent
|
||||
last_second = -1
|
||||
|
||||
while True:
|
||||
# 1. Compute time
|
||||
local_epoch = time.time() + (Config.UTC_OFFSET * 3600)
|
||||
year, month, day, hour_24, minute, second, weekday, _ = time.localtime(local_epoch)
|
||||
# 1. Fast, single-integer read from RTC
|
||||
current_sec = time.time()
|
||||
|
||||
# 2. Only redraw if the second has actually changed
|
||||
if second != last_second:
|
||||
last_second = second
|
||||
# 2. Gate everything behind the 1-second boundary
|
||||
if current_sec != last_second:
|
||||
last_second = current_sec
|
||||
|
||||
# Unpack UTC once per second
|
||||
utc_year, utc_month, utc_day, utc_hour, _, _, utc_weekday, _ = time.gmtime(current_sec)
|
||||
|
||||
# Run DST check
|
||||
dst_offset = 1 if is_dst(utc_year, utc_month, utc_day, utc_hour, utc_weekday) else 0
|
||||
total_offset = Config.UTC_OFFSET + dst_offset
|
||||
|
||||
# Compute local wall-clock components
|
||||
local_epoch = current_sec + (total_offset * 3600)
|
||||
year, month, day, hour_24, minute, second, weekday, _ = time.localtime(local_epoch)
|
||||
|
||||
# --- String formatting and OLED rendering ---
|
||||
sep = ":" if second % 2 == 0 else " "
|
||||
|
||||
if Config.USE_24_HOUR:
|
||||
@@ -121,5 +173,5 @@ while True:
|
||||
|
||||
oled.show()
|
||||
|
||||
# 3. Sleep in small increments to catch the exact second boundary with minimal latency
|
||||
time.sleep_ms(20)
|
||||
# Fast poll to catch the next second boundary immediately
|
||||
time.sleep_ms(25)
|
||||
|
||||
Reference in New Issue
Block a user