]> git.earman.xyz Git - sensor-watch.git/commitdiff
fix: sunrise/set before DST change
authorStephan <99481666+stephan242@users.noreply.github.com>
Sun, 29 Mar 2026 23:52:55 +0000 (00:52 +0100)
committerStephan <99481666+stephan242@users.noreply.github.com>
Sat, 4 Apr 2026 18:27:35 +0000 (19:27 +0100)
The Sunrise and Sunset timezone offset needs to be calculated for the day it's relevant to, since it might experience a timezone  change.

movement.c
movement.h
watch-faces/complication/sunrise_sunset_face.c

index f0fb96093fdf4c6018f8e9aee98a201f0f805ba4..14e8832efa54bd172fd43044e95eb29d7150277a 100644 (file)
@@ -660,6 +660,26 @@ int32_t movement_get_current_timezone_offset(void) {
     return movement_get_current_timezone_offset_for_zone(movement_state.settings.bit.time_zone);
 }
 
+int32_t movement_get_timezone_offset_for_date_in_zone(watch_date_time_t date_time, uint8_t zone_index) {
+    int8_t cached_dst_offset = _movement_dst_offset_cache[zone_index];
+
+    if (cached_dst_offset == TIMEZONE_DOES_NOT_OBSERVE) {
+        return (int32_t)zone_defns[zone_index].offset_inc_minutes * OFFSET_INCREMENT * 60;
+    }
+
+    // Compute the offset for the given date using the zone's DST rules
+    uzone_t local_zone;
+    unpack_zone(&zone_defns[zone_index], "", &local_zone);
+    udatetime_t udt = _movement_convert_date_time_to_udate(date_time);
+    uoffset_t offset;
+    get_current_offset(&local_zone, &udt, &offset);
+    return (int32_t)(offset.hours * 60 + offset.minutes) * 60;
+}
+
+int32_t movement_get_timezone_offset_for_date(watch_date_time_t date_time) {
+    return movement_get_timezone_offset_for_date_in_zone(date_time, movement_state.settings.bit.time_zone);
+}
+
 int32_t movement_get_timezone_index(void) {
     return movement_state.settings.bit.time_zone;
 }
index 1bbd9638837e445c10ee932109b3635eb328b690..7b81e9ec55c6c5357602a9f9bb7cc574733b5f6a 100644 (file)
@@ -341,6 +341,8 @@ uint8_t movement_claim_backup_register(void);
 
 int32_t movement_get_current_timezone_offset_for_zone(uint8_t zone_index);
 int32_t movement_get_current_timezone_offset(void);
+int32_t movement_get_timezone_offset_for_date_in_zone(watch_date_time_t date_time, uint8_t zone_index);
+int32_t movement_get_timezone_offset_for_date(watch_date_time_t date_time);
 
 int32_t movement_get_timezone_index(void);
 void movement_set_timezone_index(uint8_t value);
index 58514848df357bc06522c260fbef6da569dbac8a..5cc5fa3c787f0a310f2916888d97ecee306103d6 100644 (file)
@@ -93,13 +93,9 @@ static void _sunrise_sunset_face_update(sunrise_sunset_state_t *state) {
     double lat = (double)lat_centi / 100.0;
     double lon = (double)lon_centi / 100.0;
 
-    // sunriset returns the rise/set times as signed decimal hours in UTC.
-    // this can mean hours below 0 or above 31, which won't fit into a watch_date_time_t struct.
-    // to deal with this, we set aside the offset in hours, and add it back before converting it to a watch_date_time_t.
-    double hours_from_utc = ((double)movement_get_current_timezone_offset()) / 3600.0;
-
     // we loop twice because if it's after sunset today, we need to recalculate to display values for tomorrow.
     for(int i = 0; i < 2; i++) {
+        double hours_from_utc = ((double)movement_get_timezone_offset_for_date(scratch_time)) / 3600.0;
         uint8_t result = sun_rise_set(scratch_time.unit.year + WATCH_RTC_REFERENCE_YEAR, scratch_time.unit.month, scratch_time.unit.day, lon, lat, &rise, &set);
 
         if (result != 0) {