Merge PR #268 - add daylight savings time toggle

Adds a toggle in the preferences face that allows the user
to enable or disable the daylight savings time.

Should help produce the correct results with the sunrise/sunset presets.

A proper solution would be to integrate the tzinfo database
but it's too big for the watch at the time of this writing.
Can't be done unless it can be shrunk down into a subset
the user would be interested. Even then it's a stopgap
since the database is likely to keep growing over time.

Reviewed-by: Matheus Afonso Martins Moreira <matheus@matheusmoreira.com>
GitHub-Pull-Request: https://github.com/joeycastillo/Sensor-Watch/pull/268
This commit is contained in:
Matheus Afonso Martins Moreira 2024-09-08 11:09:10 -03:00
commit 5a8a49a8c7
3 changed files with 125 additions and 4 deletions

View File

@ -185,6 +185,107 @@ const int16_t movement_timezone_offsets[] = {
-60, // 40 : -1:00:00 (Azores Standard Time)
};
/* These are approximate equivalent DST timezones for each
* timezone in the offset table. Unlike the full tzinfo file,
* the time-offsets used above are incomplete, so there are
* cases below where an approximate DST timezone is proposed
* for a timezone where no one observes DST, and cases
* where we can't propose an equivaent DST timezone since
* there isn't an appropriate one in the offset table.
*
* However, this should be good enough for anyone living in
* a DST-observing region to manually toggle DST without
* having to separately change the hour and timezone info
* in the time set face.
*/
const uint8_t movement_dst_jump_table[] = {
1, // 0 UTC + 1 = CET
2, // 1 CET + 1 = SAST
3, // 2 SAST + 1 = AST
5, // 3 AST + 1 = GST
6, // 4 IST + 1 = AT
7, // 5 GST + 1 = PST
8, // 6 AT + 1 = IST
10, // 7 PST + 1 = KT
11, // 8 IST + 1 = MT
9, // 9 Nepal has no equivalent DST timezone, but they don't observe DST anyway
12, // 10 KT + 1 = TST
11, // 11 Myanmar has no equivalent DST timezone, but they don't observe DST anyway
13, // 12 TST + 1 = CST
15, // 13 CST + 1 = JST
14, // 14 ACWST has no equivalent DST timezone, but they don't observe DST anyway
17, // 15 JST + 1 = AEST
18, // 16 ACST + 1 = LHST
19, // 17 AEST + 1 = SIT
18, // 18 LHST has no equivalent DST timezone, but they don't observe DST anyway
20, // 19 SIT + 1 = NZST
22, // 20 NZST + 1 = TT
23, // 21 CST + 1 = CDT
24, // 22 TT + 1 = LIT
23, // 23 CDT is already a daylight timezone
24, // 24 LIT has no equivalent DST timezone, but they don't observe DST anyway
26, // 25 BIT + 1 = NT
27, // 26 NT + 1 = HAST
29, // 27 HAST + 1 = AST
28, // 28 MIT has no equivalent DST timezone, but they don't observe DST anyway
30, // 29 AST + 1 = PST
31, // 30 PST + 1 = MST
32, // 31 MST + 1 = CST
33, // 32 CST + 1 = EST
35, // 33 EST + 1 = AST
36, // 34 VST + 1 = NST
37, // 35 AST + 1 = BT
38, // 36 NST + 1 = NDT
39, // 37 BT + 1 = 39
38, // 38 NDT is already a daylight timezone
40, // 39 FNT + 1 = AST
0 // 40 AST + 1 = UTC
};
const uint8_t movement_dst_inverse_jump_table[] = {
40, // 0
0, // 1
1, // 2
2, // 3
4, // 4
3, // 5
4, // 6
5, // 7
6, // 8
9, // 9
7, // 10
8, // 11
10, // 12
12, // 13
14, // 14
13, // 15
16, // 16
15, // 17
16, // 18
17, // 19
19, // 20
21, // 21
20, // 22
21, // 23
24, // 24
25, // 25
25, // 26
26, // 27
28, // 28
27, // 29
29, // 30
30, // 31
31, // 32
32, // 33
34, // 34
33, // 35
34, // 36
35, // 37
36, // 38
37, // 39
39 // 40
};
const char movement_valid_position_0_chars[] = " AaBbCcDdEeFGgHhIiJKLMNnOoPQrSTtUuWXYZ-='+\\/0123456789";
const char movement_valid_position_1_chars[] = " ABCDEFHlJLNORTtUX-='01378";

View File

@ -63,7 +63,8 @@ typedef union {
bool clock_24h_leading_zero : 1; // indicates whether clock should leading zero to indicate 24 hour mode.
bool use_imperial_units : 1; // indicates whether to use metric units (the default) or imperial.
bool alarm_enabled : 1; // indicates whether there is at least one alarm enabled.
uint8_t reserved : 5; // room for more preferences if needed.
bool dst_active : 1; // indicates whether daylight savings time is active
uint8_t reserved : 4; // room for more preferences if needed.
} bit;
uint32_t reg;
} movement_settings_t;
@ -129,6 +130,8 @@ typedef struct {
} movement_event_t;
extern const int16_t movement_timezone_offsets[];
extern const uint8_t movement_dst_jump_table[];
extern const uint8_t movement_dst_inverse_jump_table[];
extern const char movement_valid_position_0_chars[];
extern const char movement_valid_position_1_chars[];

View File

@ -27,8 +27,8 @@
#include "watch.h"
#include "watch_utility.h"
#define SET_TIME_FACE_NUM_SETTINGS (7)
const char set_time_face_titles[SET_TIME_FACE_NUM_SETTINGS][3] = {"HR", "M1", "SE", "YR", "MO", "DA", "ZO"};
#define SET_TIME_FACE_NUM_SETTINGS (8)
const char set_time_face_titles[SET_TIME_FACE_NUM_SETTINGS][3] = {"HR", "M1", "SE", "YR", "MO", "DA", "ZO", "DS"};
static bool _quick_ticks_running;
@ -59,6 +59,16 @@ static void _handle_alarm_button(movement_settings_t *settings, watch_date_time
settings->bit.time_zone++;
if (settings->bit.time_zone > 40) settings->bit.time_zone = 0;
break;
case 7: // daylight savings time
if (settings->bit.dst_active) { // deactivate DST
date_time.unit.hour = (date_time.unit.hour + 24 - 1) % 24;
settings->bit.time_zone = movement_dst_inverse_jump_table[settings->bit.time_zone];
} else { // activate DST
date_time.unit.hour = (date_time.unit.hour + 1) % 24;
settings->bit.time_zone = movement_dst_jump_table[settings->bit.time_zone];
}
settings->bit.dst_active = !settings->bit.dst_active;
break;
}
if (date_time.unit.day > days_in_month(date_time.unit.month, date_time.unit.year + WATCH_RTC_REFERENCE_YEAR))
date_time.unit.day = 1;
@ -145,7 +155,7 @@ bool set_time_face_loop(movement_event_t event, movement_settings_t *settings, v
watch_clear_indicator(WATCH_INDICATOR_24H);
watch_clear_indicator(WATCH_INDICATOR_PM);
sprintf(buf, "%s %2d%02d%02d", set_time_face_titles[current_page], date_time.unit.year + 20, date_time.unit.month, date_time.unit.day);
} else {
} else if (current_page < 7) { // zone
if (event.subsecond % 2) {
watch_clear_colon();
sprintf(buf, "%s ", set_time_face_titles[current_page]);
@ -153,6 +163,10 @@ bool set_time_face_loop(movement_event_t event, movement_settings_t *settings, v
watch_set_colon();
sprintf(buf, "%s %3d%02d ", set_time_face_titles[current_page], (int8_t) (movement_timezone_offsets[settings->bit.time_zone] / 60), (int8_t) (movement_timezone_offsets[settings->bit.time_zone] % 60) * (movement_timezone_offsets[settings->bit.time_zone] < 0 ? -1 : 1));
}
} else { // daylight savings
watch_clear_colon();
if (settings->bit.dst_active) sprintf(buf, "%s dsT y", set_time_face_titles[current_page]);
else sprintf(buf, "%s dsT n", set_time_face_titles[current_page]);
}
// blink up the parameter we're setting
@ -170,6 +184,9 @@ bool set_time_face_loop(movement_event_t event, movement_settings_t *settings, v
case 5:
buf[8] = buf[9] = ' ';
break;
case 7:
buf[9] = ' ';
break;
}
}