@@ -44,6 +44,7 @@ of debounce time.
44
44
#include "filesystem.h"
45
45
#include "movement.h"
46
46
#include "shell.h"
47
+ #include "watch_utility.h"
47
48
48
49
#ifndef MOVEMENT_FIRMWARE
49
50
#include "movement_config.h"
@@ -130,6 +131,11 @@ of debounce time.
130
131
#define MOVEMENT_DEFAULT_BIRTHDATE_DAY 0
131
132
#endif
132
133
134
+ // Default to having DST get set
135
+ #ifndef MOVEMENT_DEFAULT_DST_ACTIVE
136
+ #define MOVEMENT_DEFAULT_DST_ACTIVE true
137
+ #endif
138
+
133
139
#if __EMSCRIPTEN__
134
140
#include <emscripten.h>
135
141
#endif
@@ -141,7 +147,8 @@ const int32_t movement_le_inactivity_deadlines[8] = {INT_MAX, 600, 3600, 7200, 2
141
147
const int16_t movement_timeout_inactivity_deadlines [4 ] = {60 , 120 , 300 , 1800 };
142
148
movement_event_t event ;
143
149
144
- const int16_t movement_timezone_offsets [] = {
150
+ #define NUM_TIME_ZONES 41
151
+ const int16_t movement_timezone_offsets [NUM_TIME_ZONES ] = {
145
152
0 , // 0 : 0:00:00 (UTC)
146
153
60 , // 1 : 1:00:00 (Central European Time)
147
154
120 , // 2 : 2:00:00 (South African Standard Time)
@@ -198,94 +205,50 @@ const int16_t movement_timezone_offsets[] = {
198
205
* having to separately change the hour and timezone info
199
206
* in the time set face.
200
207
*/
201
- const uint8_t movement_dst_jump_table [ ] = {
202
- 1 , // 0 UTC + 1 = CET
203
- 2 , // 1 CET + 1 = SAST
204
- 3 , // 2 SAST + 1 = AST
205
- 5 , // 3 AST + 1 = GST
206
- 6 , // 4 IST + 1 = AT
207
- 7 , // 5 GST + 1 = PST
208
- 8 , // 6 AT + 1 = IST
209
- 10 , // 7 PST + 1 = KT
210
- 11 , // 8 IST + 1 = MT
211
- 9 , // 9 Nepal has no equivalent DST timezone, but they don't observe DST anyway
212
- 12 , // 10 KT + 1 = TST
213
- 11 , // 11 Myanmar has no equivalent DST timezone, but they don't observe DST anyway
214
- 13 , // 12 TST + 1 = CST
215
- 15 , // 13 CST + 1 = JST
216
- 14 , // 14 ACWST has no equivalent DST timezone, but they don't observe DST anyway
217
- 17 , // 15 JST + 1 = AEST
218
- 18 , // 16 ACST + 1 = LHST
219
- 19 , // 17 AEST + 1 = SIT
220
- 18 , // 18 LHST has no equivalent DST timezone, but they don't observe DST anyway
221
- 20 , // 19 SIT + 1 = NZST
222
- 22 , // 20 NZST + 1 = TT
223
- 23 , // 21 CST + 1 = CDT
224
- 24 , // 22 TT + 1 = LIT
225
- 23 , // 23 CDT is already a daylight timezone
226
- 24 , // 24 LIT has no equivalent DST timezone, but they don't observe DST anyway
227
- 26 , // 25 BIT + 1 = NT
228
- 27 , // 26 NT + 1 = HAST
229
- 29 , // 27 HAST + 1 = AST
230
- 28 , // 28 MIT has no equivalent DST timezone, but they don't observe DST anyway
231
- 30 , // 29 AST + 1 = PST
232
- 31 , // 30 PST + 1 = MST
233
- 32 , // 31 MST + 1 = CST
234
- 33 , // 32 CST + 1 = EST
235
- 35 , // 33 EST + 1 = AST
236
- 36 , // 34 VST + 1 = NST
237
- 37 , // 35 AST + 1 = BT
238
- 38 , // 36 NST + 1 = NDT
239
- 39 , // 37 BT + 1 = 39
240
- 38 , // 38 NDT is already a daylight timezone
241
- 40 , // 39 FNT + 1 = AST
208
+ const int16_t movement_timezone_dst_offsets [ NUM_TIME_ZONES ] = {
209
+ 60 , // 0 UTC + 1 = CET
210
+ 120 , // 1 CET + 1 = SAST
211
+ 189 , // 2 SAST + 1 = AST
212
+ 240 , // 3 AST + 1 = GST
213
+ 270 , // 4 IST + 1 = AT
214
+ 300 , // 5 GST + 1 = PST
215
+ 330 , // 6 AT + 1 = IST
216
+ 360 , // 7 PST + 1 = KT
217
+ 390 , // 8 IST + 1 = MT
218
+ 345 , // 9 Nepal has no equivalent DST timezone, but they don't observe DST anyway
219
+ 420 , // 10 KT + 1 = TST
220
+ 390 , // 11 Myanmar has no equivalent DST timezone, but they don't observe DST anyway
221
+ 480 , // 12 TST + 1 = CST
222
+ 540 , // 13 CST + 1 = JST
223
+ 525 , // 14 ACWST has no equivalent DST timezone, but they don't observe DST anyway
224
+ 600 , // 15 JST + 1 = AEST
225
+ 630 , // 16 ACST + 1 = LHST
226
+ 660 , // 17 AEST + 1 = SIT
227
+ 630 , // 18 LHST has no equivalent DST timezone, but they don't observe DST anyway
228
+ 720 , // 19 SIT + 1 = NZST
229
+ 780 , // 20 NZST + 1 = TT
230
+ 825 , // 21 CST + 1 = CDT
231
+ 840 , // 22 TT + 1 = LIT
232
+ 825 , // 23 CDT is already a daylight timezone
233
+ 840 , // 24 LIT has no equivalent DST timezone, but they don't observe DST anyway
234
+ -660 , // 25 BIT + 1 = NT
235
+ -600 , // 26 NT + 1 = HAST
236
+ -540 , // 27 HAST + 1 = AST
237
+ -570 , // 28 MIT has no equivalent DST timezone, but they don't observe DST anyway
238
+ -480 , // 29 AST + 1 = PST
239
+ -420 , // 30 PST + 1 = MST
240
+ -360 , // 31 MST + 1 = CST
241
+ -300 , // 32 CST + 1 = EST
242
+ -240 , // 33 EST + 1 = AST
243
+ -210 , // 34 VST + 1 = NST
244
+ -180 , // 35 AST + 1 = BT
245
+ -150 , // 36 NST + 1 = NDT
246
+ -120 , // 37 BT + 1 = 39
247
+ -150 , // 38 NDT is already a daylight timezone
248
+ -60 , // 39 FNT + 1 = AST
242
249
0 // 40 AST + 1 = UTC
243
250
};
244
251
245
- const uint8_t movement_dst_inverse_jump_table [] = {
246
- 40 , // 0
247
- 0 , // 1
248
- 1 , // 2
249
- 2 , // 3
250
- 4 , // 4
251
- 3 , // 5
252
- 4 , // 6
253
- 5 , // 7
254
- 6 , // 8
255
- 9 , // 9
256
- 7 , // 10
257
- 8 , // 11
258
- 10 , // 12
259
- 12 , // 13
260
- 14 , // 14
261
- 13 , // 15
262
- 16 , // 16
263
- 15 , // 17
264
- 16 , // 18
265
- 17 , // 19
266
- 19 , // 20
267
- 21 , // 21
268
- 20 , // 22
269
- 21 , // 23
270
- 24 , // 24
271
- 25 , // 25
272
- 25 , // 26
273
- 26 , // 27
274
- 28 , // 28
275
- 27 , // 29
276
- 29 , // 30
277
- 30 , // 31
278
- 31 , // 32
279
- 32 , // 33
280
- 34 , // 34
281
- 33 , // 35
282
- 34 , // 36
283
- 35 , // 37
284
- 36 , // 38
285
- 37 , // 39
286
- 39 // 40
287
- };
288
-
289
252
const char movement_valid_position_0_chars [] = " AaBbCcDdEeFGgHhIiJKLMNnOoPQrSTtUuWXYZ-='+\\/0123456789" ;
290
253
const char movement_valid_position_1_chars [] = " ABCDEFHlJLNORTtUX-='01378" ;
291
254
@@ -323,6 +286,31 @@ static inline void _movement_disable_fast_tick_if_possible(void) {
323
286
}
324
287
}
325
288
289
+ static bool _check_and_act_on_daylight_savings (void ) {
290
+ if (!movement_state .settings .bit .dst_active ) return false;
291
+ watch_date_time date_time = watch_rtc_get_date_time ();
292
+ // No need for all of the unix time calculations for times not at the beginning or end of the hour
293
+ if (date_time .unit .minute > 1 && date_time .unit .minute < 59 ) return false;
294
+ uint8_t dst_result = get_dst_status (date_time );
295
+ bool dst_skip_rolling_back = get_dst_skip_rolling_back ();
296
+
297
+ if (dst_skip_rolling_back && (dst_result == DST_ENDED )) {
298
+ clear_dst_skip_rolling_back ();
299
+ }
300
+ else if (dst_result == DST_ENDING && !dst_skip_rolling_back ) {
301
+ date_time .unit .hour = (date_time .unit .hour + 24 - 1 ) % 24 ;
302
+ watch_rtc_set_date_time (date_time );
303
+ set_dst_skip_rolling_back ();
304
+ return true;
305
+ }
306
+ else if (dst_result == DST_STARTING ) {
307
+ date_time .unit .hour = (date_time .unit .hour + 1 ) % 24 ;
308
+ watch_rtc_set_date_time (date_time );
309
+ return true;
310
+ }
311
+ return false;
312
+ }
313
+
326
314
static void _movement_handle_background_tasks (void ) {
327
315
for (uint8_t i = 0 ; i < MOVEMENT_NUM_FACES ; i ++ ) {
328
316
// For each face, if the watch face wants a background task...
@@ -332,6 +320,7 @@ static void _movement_handle_background_tasks(void) {
332
320
watch_faces [i ].loop (background_event , & movement_state .settings , watch_face_contexts [i ]);
333
321
}
334
322
}
323
+ _check_and_act_on_daylight_savings ();
335
324
movement_state .needs_background_tasks_handled = false;
336
325
}
337
326
@@ -529,6 +518,12 @@ uint8_t movement_claim_backup_register(void) {
529
518
return movement_state .next_available_backup_register ++ ;
530
519
}
531
520
521
+ int16_t get_timezone_offset (uint8_t timezone_idx , watch_date_time date_time ) {
522
+ if (movement_state .settings .bit .dst_active && dst_occurring (date_time ))
523
+ return movement_timezone_dst_offsets [timezone_idx ];
524
+ return movement_timezone_offsets [timezone_idx ];
525
+ }
526
+
532
527
void app_init (void ) {
533
528
#if defined(NO_FREQCORR )
534
529
watch_rtc_freqcorr_write (0 , 0 );
@@ -551,6 +546,20 @@ void app_init(void) {
551
546
movement_state .birthdate .bit .year = MOVEMENT_DEFAULT_BIRTHDATE_YEAR ;
552
547
movement_state .birthdate .bit .month = MOVEMENT_DEFAULT_BIRTHDATE_MONTH ;
553
548
movement_state .birthdate .bit .day = MOVEMENT_DEFAULT_BIRTHDATE_DAY ;
549
+ movement_state .settings .bit .dst_active = MOVEMENT_DEFAULT_DST_ACTIVE ;
550
+
551
+ #ifdef MAKEFILE_TIMEZONE
552
+ timezone_offsets = dst_occurring (watch_rtc_get_date_time ()) ? movement_timezone_dst_offsets : movement_timezone_offsets ;
553
+ for (int i = 0 ; i < NUM_TIME_ZONES ; i ++ ) {
554
+ if (timezone_offsets [i ] == MAKEFILE_TIMEZONE ) {
555
+ movement_state .settings .bit .time_zone = i ;
556
+ break ;
557
+ }
558
+ }
559
+ #else
560
+ movement_state .settings .bit .time_zone = 35 ; // Atlantic Time as default
561
+ #endif
562
+
554
563
movement_state .light_ticks = -1 ;
555
564
movement_state .alarm_ticks = -1 ;
556
565
movement_state .next_available_backup_register = 4 ;
@@ -559,11 +568,13 @@ void app_init(void) {
559
568
filesystem_init ();
560
569
561
570
#if __EMSCRIPTEN__
571
+ const int16_t * timezone_offsets ;
562
572
int32_t time_zone_offset = EM_ASM_INT ({
563
573
return - new Date ().getTimezoneOffset ();
564
574
});
565
- for (int i = 0 , count = sizeof (movement_timezone_offsets ) / sizeof (movement_timezone_offsets [0 ]); i < count ; i ++ ) {
566
- if (movement_timezone_offsets [i ] == time_zone_offset ) {
575
+ timezone_offsets = dst_occurring (watch_rtc_get_date_time ()) ? movement_timezone_dst_offsets : movement_timezone_offsets ;
576
+ for (int i = 0 ; i < NUM_TIME_ZONES ; i ++ ) {
577
+ if (timezone_offsets [i ] == time_zone_offset ) {
567
578
movement_state .settings .bit .time_zone = i ;
568
579
break ;
569
580
}
0 commit comments