this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

"closest noon" fixes, specs

alice 7478aa05 3f0d0ac6

+508 -335
+50
closest_noon_logic.md
··· 1 + # TidFace Clock Logic: Closest to Noon (with DST and Randomization) 2 + 3 + ## Core Goal 4 + 5 + Display a continuously updating time in the format `[CityName]:[MM]:[SS]`. The chosen `CityName` is determined by finding the timezone whose *current local time* is closest to 12:00:00 noon at specific intervals. 6 + 7 + ## Key Principles 8 + 9 + 1. **Base Time:** The system operates based on the current Coordinated Universal Time (UTC), also referred to as GMT. 10 + 2. **Re-evaluation Intervals:** The process of choosing the "best" timezone/city occurs precisely when the UTC time hits **:00, :15, or :30** minutes past the hour. 11 + * *Reasoning:* We evaluate at these specific intervals to catch timezones hitting exactly 12:00:00 local time. 12 + * `:00` UTC is needed for integer offsets (e.g., UTC+5 -> 12:00 at 07:00 UTC). 13 + * `:15` UTC is needed for `:45` offsets (e.g., UTC+5:45 -> 12:00 at 06:15 UTC; UTC+12:45 -> 12:00 at 23:15 UTC). 14 + * `:30` UTC is needed for `:30` offsets (e.g., UTC+5:30 -> 12:00 at 06:30 UTC). 15 + * The `:45` UTC evaluation is omitted as no standard timezones have `:15` offsets that would hit noon precisely at XX:45 UTC. 16 + 3. **DST Awareness:** Daylight Saving Time rules, as defined for the year 2025 in `tz_list.c`, *must* be considered when calculating local times. 17 + 4. **Randomization:** If multiple timezones are equally "close" to noon, one is chosen randomly. Subsequently, a city name within that chosen timezone is selected randomly. 18 + 5. **Continuous Display:** Between re-evaluation intervals, the displayed time (`MM:SS`) simply ticks forward second-by-second based on the *currently selected* city's timezone offset. The city name remains constant during this period. 19 + 6. **Allowed Time Jumps:** When a new city/timezone is selected at a re-evaluation interval, the displayed `MM:SS` will jump to reflect the *new* local time. This can result in the displayed minutes/seconds appearing to go backward or jump forward significantly. 20 + 21 + ## Re-evaluation Logic (Executed at UTC XX:00:00, XX:15:00, XX:30:00) 22 + 23 + 1. **Get Current UTC:** Obtain the current UTC time as a timestamp (`current_utc_t`, e.g., a `time_t`). 24 + 2. **Define Noon:** Define the target time as 12:00:00 (represented as seconds past midnight, e.g., `NOON_SECONDS = 12 * 3600`). 25 + 3. **Iterate Through Timezones (`tz_list`) - Find Minimum Valid Time:** 26 + * Initialize `min_valid_local_seconds` to a very large value (e.g., `DAY_SECONDS`). 27 + * Create a temporary list/array (`candidates`) to store potential winners. 28 + * For each `TzInfo` entry in `tz_list`: 29 + * **Determine Active Offset:** Check if `current_utc_t` falls within the `dst_start_utc` and `dst_end_utc` for that entry. Use `dst_offset_hours` if true, `std_offset_hours` otherwise. 30 + * **Calculate Local Time:** Determine the local time for this timezone at `current_utc_t`, expressed as seconds past local midnight (`local_seconds_today`). Ensure the result is correctly handled (e.g., modulo `DAY_SECONDS`, handle negative results). 31 + * **Filter for Validity:** Check if `local_seconds_today >= NOON_SECONDS`. 32 + * **If Valid:** 33 + * Store the `TzInfo` index, `local_seconds_today`, and the `active_offset_hours` in the `candidates` list. 34 + * Compare `local_seconds_today` with `min_valid_local_seconds`. If it's smaller, update `min_valid_local_seconds`. 35 + 4. **Collect Best Candidates:** 36 + * Create a new list (`best_candidates`). 37 + * Iterate through the `candidates` list gathered in step 3. 38 + * If a candidate's `local_seconds_today` equals `min_valid_local_seconds`, add its index (or a reference to it) to the `best_candidates` list. 39 + 5. **Handle No Valid Candidates:** If `best_candidates` is empty (meaning no timezone had local time >= noon), set a fallback state (e.g., `selected_city_name = "Wait..."`, `selected_offset_hours = 0.0`). 40 + 6. **Select Winning Timezone (if candidates exist):** Randomly choose one entry from the `best_candidates` list. This gives you the winning candidate structure (containing the `TzInfo` index and active offset). 41 + 7. **Select Winning City:** Get the `TzInfo` entry using the index from the winning candidate. Randomly choose a city name (`selected_city_name`) from the `names` array within that `TzInfo`. 42 + 8. **Store Results:** Store the `selected_city_name` and the `active_offset_hours` from the winning candidate (`selected_offset_hours`). These will be used for display until the next re-evaluation. If a fallback state was set in step 5, store those values instead. 43 + 44 + ## Continuous Display Logic (Executed Every Second) 45 + 46 + 1. **Get Current UTC:** Obtain the current UTC timestamp (`current_utc_t`). 47 + 2. **Calculate Current Local Time:** Use the *stored* `selected_offset_hours` from the last re-evaluation. 48 + `current_local_time = current_utc_t + (selected_offset_hours * 3600)` 49 + 3. **Format Time:** Extract the minutes (`MM`) and seconds (`SS`) from `current_local_time`. 50 + 4. **Display:** Output the string `selected_city_name:MM:SS`.
+34 -14
generate_tz_list.py
··· 126 126 available_zones = zoneinfo.available_timezones() 127 127 print(f"Found {len(available_zones)} available timezones.") 128 128 129 - processed_zones = {} # Key: std_offset_hours, Value: Dict of zone data 129 + processed_zones = {} # Key: TUPLE(std_offset_s, dst_offset_s, start_utc, end_utc), Value: Dict of zone data 130 130 131 131 for tz_name in available_zones: 132 132 # Basic filtering (no dead code here) ··· 136 136 std_offset_s, dst_offset_s, start_utc, end_utc = find_dst_transitions_accurate(tz_name, target_year) 137 137 city_name = tz_name.split('/')[-1].replace('_', ' ') 138 138 139 - # Convert offsets back to hours 139 + # --- Filter out generic names --- 140 + # Comprehensive list based on review of tz_list.c 141 + generic_names_to_exclude = { 142 + "Samoa", "Hawaii", "Aleutian", "Alaska", "Pacific", "Arizona", "Yukon", 143 + "Mountain", "General", "Saskatchewan", "Central", "Knox IN", "EasterIsland", 144 + "Acre", "Jamaica", "Michigan", "Eastern", "East-Indiana", "Atlantic", 145 + "Continental", "Newfoundland", "East", "Bahia", "Noronha", "South Georgia", 146 + "Canary", "Faeroe", "Faroe", "Guernsey", "Isle of Man", "Jersey", 147 + "Madeira", "Jan Mayen", "West", "North", "South", "ACT", "NSW", 148 + "Tasmania", "Victoria", "Queensland", "Yap", "South Pole", "Kanton", 149 + # Add or remove names as needed 150 + } 151 + # Case-insensitive check for exclusion 152 + if city_name.lower() in {name.lower() for name in generic_names_to_exclude}: 153 + continue # Skip this generic name 154 + 155 + # Convert offsets back to hours for potential display, but keep seconds for key 140 156 std_offset_h = std_offset_s / 3600.0 141 157 dst_offset_h = dst_offset_s / 3600.0 142 158 143 - # Group by standard offset 144 - key_offset = std_offset_h 159 + # Group by the unique combination of std offset, dst offset, and transitions 160 + key_tuple = (std_offset_s, dst_offset_s, start_utc, end_utc) 145 161 if city_name and city_name[0].isupper(): 146 - if key_offset not in processed_zones: 147 - processed_zones[key_offset] = { 148 - "std_offset": std_offset_h, 149 - "dst_offset": dst_offset_h, 162 + if key_tuple not in processed_zones: 163 + processed_zones[key_tuple] = { 164 + "std_offset_s": std_offset_s, # Store seconds internally 165 + "dst_offset_s": dst_offset_s, 150 166 "start_utc": start_utc, 151 167 "end_utc": end_utc, 152 168 "names": [] 153 169 } 154 170 # Add city name if not already present 155 - if city_name not in processed_zones[key_offset]["names"]: 156 - processed_zones[key_offset]["names"].append(city_name) 171 + if city_name not in processed_zones[key_tuple]["names"]: 172 + processed_zones[key_tuple]["names"].append(city_name) 157 173 158 - # Convert dict values to a list and sort by standard offset 159 - tz_data_list = sorted(processed_zones.values(), key=lambda x: x["std_offset"]) 160 - print(f"Generated data for {len(tz_data_list)} unique standard offsets.") 174 + # Convert dict values to a list and sort primarily by standard offset, then DST offset 175 + # Sort key uses the seconds offset stored in the dictionary value 176 + tz_data_list = sorted(processed_zones.values(), key=lambda x: (x["std_offset_s"], x["dst_offset_s"])) 177 + print(f"Generated data for {len(tz_data_list)} unique offset/DST rule combinations.") 161 178 162 179 # --- C Code Generation --- 163 180 # Build C code string (no obvious dead code here) ··· 199 216 c_code += "// Main list mapping offsets/DST info to their respective name arrays\n" 200 217 c_code += "static const TzInfo tz_list[] = {\n" 201 218 for zone_data in tz_data_list: 219 + # Convert offsets to hours ONLY for C code generation 220 + std_offset_h_c = zone_data['std_offset_s'] / 3600.0 221 + dst_offset_h_c = zone_data['dst_offset_s'] / 3600.0 202 222 c_array_name = zone_data["c_array_name"] 203 223 name_count = len(zone_data["names"]) 204 224 # Use 'LL' suffix for int64_t timestamp constants in C 205 - c_code += (f" {{ {zone_data['std_offset']:.2f}f, {zone_data['dst_offset']:.2f}f, " 225 + c_code += (f" {{ {std_offset_h_c:.2f}f, {dst_offset_h_c:.2f}f, " 206 226 f"{zone_data['start_utc']}LL, {zone_data['end_utc']}LL, " 207 227 f"{c_array_name}, {name_count} }},\n") 208 228
+160 -120
src/c/clock_closest_noon.c
··· 2 2 #include <pebble.h> // Always include pebble for device builds 3 3 #include <stdlib.h> // For rand() 4 4 #include <stdint.h> // For uint32_t, int64_t 5 - #include <time.h> // For time_t, struct tm, gmtime 5 + #include <time.h> // For time_t, struct tm, gmtime, strcmp, strncmp 6 6 #include <stdbool.h>// For bool 7 + #include <limits.h> // For LONG_MAX // Not strictly needed anymore, but harmless 8 + #include <string.h> // For strcmp, strncmp 7 9 8 10 // Include the generated timezone data structure definitions and list 9 11 // This must contain TzInfo, tz_list[], and TZ_LIST_COUNT 10 12 #include "tz_list.c" 11 13 12 - #define DAY_LENGTH 86400 14 + #define DAY_SECONDS (24 * 3600L) 13 15 #define NOON_SECONDS (12 * 3600L) 14 16 15 17 // --- Static variables specific to Closest Noon Clock --- 16 - static char s_closest_noon_buffer[32]; 17 - static int last_closest_noon_update_secs = -1; 18 + static char s_closest_noon_buffer[40]; // Increased size for potentially longer names + MM:SS 19 + static time_t s_last_update_time = -1; 20 + static time_t s_last_re_evaluation_time = -1; 18 21 19 - // Cache for stabilization 20 - static int last_chosen_zone_index = -1; // Index in tz_list of the last chosen zone 21 - static const char* last_displayed_name = NULL; // Specific name displayed last time 22 + // Stores the results of the last re-evaluation 23 + static const char *s_selected_city_name = "Wait..."; 24 + static float s_selected_offset_hours = 0.0f; // Store the active offset 22 25 23 26 // --- Static helper functions --- 27 + 24 28 /** 25 - * Helper function to find the current noon-hour zone, handle stabilization, 26 - * and calculate display values. Switches proactively to the zone(s) 27 - * closest to 12:00:00 local time. 29 + * @brief Re-evaluates and selects the timezone whose local time is >= 12:00:00 30 + * and closest to 12:00:00, based on current UTC. 31 + * Updates the static s_selected_city_name and s_selected_offset_hours. 32 + * Should only be called at :00, :15, :30, :45 minutes past the hour (UTC). 28 33 * 29 - * Returns: true if a zone was found and display values calculated, false otherwise. 30 - * Outputs: Pointers to store the chosen display name, minutes past noon, and seconds past noon. 34 + * @param current_utc_t The current UTC time as time_t. 31 35 */ 32 - static bool calculate_noon_zone_display(time_t current_seconds_utc, 33 - const char** out_display_name, 34 - long* out_display_minutes, 35 - long* out_display_seconds) 36 - { 37 - time_t current_time_t = (time_t)current_seconds_utc; 38 - uint32_t utc_seconds_today = current_seconds_utc % DAY_LENGTH; 36 + static void update_selected_timezone_and_city(time_t current_utc_t) { 37 + // Seed random number generator (important for random selection) 38 + srand(current_utc_t); 39 39 40 - // --- Find candidate zones currently in the noon hour (12:00:00 - 12:59:59) --- 40 + // Find the minimum local time that is >= noon 41 + long min_valid_local_seconds = DAY_SECONDS; // Initialize higher than any possible time 42 + 43 + // Structure to hold candidate timezone info 41 44 typedef struct { 42 - int index; 43 - long local_secs; 44 - } NoonCandidate; 45 - NoonCandidate current_candidates[TZ_LIST_COUNT]; 46 - int current_candidate_count = 0; 47 - long min_local_secs_in_noon_hour = DAY_LENGTH; // Find the earliest time past 12:00 45 + int index; // Index in tz_list 46 + long local_secs_today; // Local time in seconds past midnight 47 + float active_offset_h; // The offset used for calculation 48 + } ZoneCandidate; 49 + 50 + ZoneCandidate candidates[TZ_LIST_COUNT]; 51 + int candidate_count = 0; // Count of zones with time >= noon 52 + 53 + uint32_t utc_seconds_today = current_utc_t % DAY_SECONDS; 48 54 55 + // --- Pass 1: Calculate local time for all zones, filter >= noon, find minimum valid time --- 49 56 for (int i = 0; i < TZ_LIST_COUNT; ++i) { 50 57 const TzInfo *tz = &tz_list[i]; 51 58 bool is_dst_active = false; 52 - // --- Determine if DST is active --- 59 + 60 + // --- Determine if DST is active --- 53 61 if (tz->dst_start_utc != 0LL && tz->dst_end_utc != 0LL) { 54 62 int64_t start_time = tz->dst_start_utc; 55 63 int64_t end_time = tz->dst_end_utc; 56 - int64_t current_time_64 = (int64_t)current_time_t; 64 + int64_t current_time_64 = (int64_t)current_utc_t; 65 + // Standard check for non-wrapping interval 57 66 if (start_time <= end_time) { 58 - if (current_time_64 >= start_time && current_time_64 < end_time) is_dst_active = true; 59 - } else { 60 - if (current_time_64 >= start_time || current_time_64 < end_time) is_dst_active = true; 67 + if (current_time_64 >= start_time && current_time_64 < end_time) { 68 + is_dst_active = true; 69 + } 61 70 } 62 - } 63 - float chosen_offset_hours = is_dst_active ? tz->dst_offset_hours : tz->std_offset_hours; 64 - long offset_seconds = (long)(chosen_offset_hours * 3600.0f); 65 - long local_seconds_today = ((long)utc_seconds_today + offset_seconds) % DAY_LENGTH; 66 - if (local_seconds_today < 0) local_seconds_today += DAY_LENGTH; 67 - 68 - // --- Check if this zone is in the noon hour --- 69 - if (local_seconds_today >= NOON_SECONDS && local_seconds_today < (NOON_SECONDS + 3600)) { 70 - if (current_candidate_count < TZ_LIST_COUNT) { 71 - current_candidates[current_candidate_count].index = i; 72 - current_candidates[current_candidate_count].local_secs = local_seconds_today; 73 - current_candidate_count++; 74 - // Track the minimum local time among candidates 75 - if (local_seconds_today < min_local_secs_in_noon_hour) { 76 - min_local_secs_in_noon_hour = local_seconds_today; 71 + // Check for wrapping interval (e.g., Southern Hemisphere DST) 72 + else { 73 + if (current_time_64 >= start_time || current_time_64 < end_time) { 74 + is_dst_active = true; 77 75 } 78 76 } 79 77 } 80 - } 78 + 79 + float active_offset_hours = is_dst_active ? tz->dst_offset_hours : tz->std_offset_hours; 80 + long offset_seconds = (long)(active_offset_hours * 3600.0f); 81 81 82 - // --- Identify the "Best" Candidates (those with the minimum local time) --- 83 - NoonCandidate best_candidates[TZ_LIST_COUNT]; 84 - int best_candidate_count = 0; 85 - if (current_candidate_count > 0) { 86 - for (int k = 0; k < current_candidate_count; ++k) { 87 - if (current_candidates[k].local_secs == min_local_secs_in_noon_hour) { 88 - if (best_candidate_count < TZ_LIST_COUNT) { 89 - best_candidates[best_candidate_count++] = current_candidates[k]; 90 - } 82 + // Calculate local time in seconds past local midnight 83 + long local_seconds_today = ((long)utc_seconds_today + offset_seconds); 84 + // Ensure positive modulo result within the day 85 + local_seconds_today %= DAY_SECONDS; 86 + if (local_seconds_today < 0) { 87 + local_seconds_today += DAY_SECONDS; 88 + } 89 + 90 + // --- Check if local time is at or after noon --- 91 + if (local_seconds_today >= NOON_SECONDS) { 92 + // Store as a potential candidate 93 + if (candidate_count < TZ_LIST_COUNT) { 94 + candidates[candidate_count].index = i; 95 + candidates[candidate_count].local_secs_today = local_seconds_today; 96 + candidates[candidate_count].active_offset_h = active_offset_hours; 97 + candidate_count++; // Increment count of valid candidates 98 + } 99 + // Update the minimum valid local time found so far 100 + if (local_seconds_today < min_valid_local_seconds) { 101 + min_valid_local_seconds = local_seconds_today; 91 102 } 92 103 } 93 104 } 94 105 95 - // --- Select the zone and name to display --- 96 - int chosen_zone_index = -1; 97 - long chosen_local_seconds = -1; 98 - const char *current_display_name = "Wait..."; 99 - 100 - bool use_last_chosen = false; 101 - if (last_chosen_zone_index != -1 && best_candidate_count > 0) { 102 - // Check if the last chosen zone is among the *best* current candidates 103 - for (int k = 0; k < best_candidate_count; ++k) { 104 - if (best_candidates[k].index == last_chosen_zone_index) { 105 - chosen_zone_index = last_chosen_zone_index; 106 - chosen_local_seconds = best_candidates[k].local_secs; 107 - current_display_name = last_displayed_name; // Reuse the specific name 108 - use_last_chosen = true; 109 - break; 106 + // --- Pass 2: Collect all candidates matching the minimum valid local time --- 107 + int best_candidates_indices[TZ_LIST_COUNT]; // Stores indices into 'candidates' array 108 + int best_candidate_count = 0; 109 + if (candidate_count > 0) { // Only proceed if we found any zones >= noon 110 + for (int k = 0; k < candidate_count; ++k) { 111 + // Check if this candidate's time is the minimum valid time we found 112 + if (candidates[k].local_secs_today == min_valid_local_seconds) { 113 + if (best_candidate_count < TZ_LIST_COUNT) { 114 + best_candidates_indices[best_candidate_count++] = k; // Store index into 'candidates' array 115 + } 110 116 } 111 117 } 112 118 } 113 119 114 - if (!use_last_chosen) { // If last wasn't valid *among the best*, or first run, or no candidates 115 - if (best_candidate_count > 0) { 116 - // Select an index randomly *from the best candidates* 117 - int list_pos = (best_candidate_count == 1) ? 0 : (rand() % best_candidate_count); 118 - chosen_zone_index = best_candidates[list_pos].index; 119 - chosen_local_seconds = best_candidates[list_pos].local_secs; 120 + 121 + // --- Select the winning timezone and city --- 122 + if (best_candidate_count > 0) { 123 + // Randomly select one of the best candidates 124 + int list_pos = (best_candidate_count == 1) ? 0 : (rand() % best_candidate_count); 125 + int winning_candidate_idx_in_candidates = best_candidates_indices[list_pos]; // Index in 'candidates' array 120 126 121 - // Select a specific city name from that chosen zone's list 122 - const TzInfo *chosen_tz = &tz_list[chosen_zone_index]; 123 - if (chosen_tz->name_count > 0) { 124 - int name_index = (chosen_tz->name_count == 1) ? 0 : (rand() % chosen_tz->name_count); 125 - if (name_index < chosen_tz->name_count) { 126 - current_display_name = chosen_tz->names[name_index].name; 127 - } else { current_display_name = "ERR:NAME"; } // Safety fallback 128 - } else { current_display_name = "ERR:NO_NM"; } // Safety fallback 127 + int chosen_zone_list_index = candidates[winning_candidate_idx_in_candidates].index; // Index in tz_list 128 + const TzInfo *chosen_tz = &tz_list[chosen_zone_list_index]; 129 129 130 - // Update static cache for next time 131 - last_chosen_zone_index = chosen_zone_index; 132 - last_displayed_name = current_display_name; 130 + // Randomly select a city name from the winning timezone 131 + if (chosen_tz->name_count > 0) { 132 + int name_index = (chosen_tz->name_count == 1) ? 0 : (rand() % chosen_tz->name_count); 133 + // Basic bounds check (should always be true if rand() works correctly) 134 + if (name_index >= 0 && name_index < chosen_tz->name_count) { 135 + s_selected_city_name = chosen_tz->names[name_index].name; 136 + } else { 137 + s_selected_city_name = "ERR:NAME"; // Safety fallback 138 + } 133 139 } else { 134 - // No zones currently in noon hour - reset static cache 135 - last_chosen_zone_index = -1; 136 - last_displayed_name = NULL; 137 - current_display_name = "Wait..."; // Explicitly set placeholder 138 - chosen_zone_index = -1; // Ensure calculation is skipped 140 + s_selected_city_name = "ERR:NO_NM"; // Safety fallback 139 141 } 140 - } 142 + // Store the active offset that was used for this winning timezone 143 + s_selected_offset_hours = candidates[winning_candidate_idx_in_candidates].active_offset_h; 141 144 142 - // --- Calculate display values and return --- 143 - if (chosen_zone_index != -1) { 144 - long seconds_since_noon_in_zone = chosen_local_seconds - NOON_SECONDS; 145 - *out_display_minutes = seconds_since_noon_in_zone / 60; 146 - *out_display_seconds = seconds_since_noon_in_zone % 60; 147 - *out_display_name = current_display_name; 148 - return true; // Success 149 145 } else { 150 - *out_display_name = current_display_name; // Return "Wait..." or error 151 - return false; // Indicate failure 146 + // This case handles when NO timezone has local time >= 12:00:00 PM 147 + s_selected_city_name = "Wait..."; // Indicate searching or fallback state 148 + s_selected_offset_hours = 0.0f; // Reset offset 152 149 } 150 + s_last_re_evaluation_time = current_utc_t; // Record when we last did this 153 151 } 152 + 154 153 155 154 // --- Interface Functions (Pebble only) --- 156 155 ··· 158 157 TextLayer* layer = text_layer_create(bounds); 159 158 text_layer_set_background_color(layer, GColorClear); 160 159 text_layer_set_text_color(layer, GColorBlack); 161 - text_layer_set_text(layer, "City:--:--"); // Initial placeholder 160 + text_layer_set_text(layer, "Wait..."); // Initial placeholder 162 161 #define CLOSEST_FONT FONT_KEY_GOTHIC_18_BOLD // Keep font definitions near usage 163 162 text_layer_set_font(layer, fonts_get_system_font(CLOSEST_FONT)); 164 163 text_layer_set_text_alignment(layer, GTextAlignmentCenter); 165 164 layer_add_child(window_layer, text_layer_get_layer(layer)); 165 + 166 + // Initialize static vars 167 + s_selected_city_name = "Wait..."; 168 + s_selected_offset_hours = 0.0f; 169 + s_last_update_time = -1; 170 + s_last_re_evaluation_time = -1; // Force re-evaluation on first update 171 + 166 172 return layer; 167 173 } 168 174 ··· 172 178 } 173 179 } 174 180 175 - void clock_closest_noon_update(TextLayer *layer, time_t current_seconds_utc) { 181 + void clock_closest_noon_update(TextLayer *layer, time_t current_utc_t) { 176 182 if (!layer) return; 177 183 178 - // Avoid update if time hasn't changed 179 - if (current_seconds_utc == last_closest_noon_update_secs) { 184 + // Avoid redundant updates for the same second 185 + if (current_utc_t == s_last_update_time) { 180 186 return; 181 187 } 188 + s_last_update_time = current_utc_t; 182 189 183 - const char *display_name; 184 - long display_minutes; 185 - long display_seconds; 190 + // --- Check if it's time for re-evaluation --- 191 + struct tm *utc_tm_struct = gmtime(&current_utc_t); // Use a different name to avoid shadowing 192 + bool needs_re_evaluation = false; 186 193 187 - bool found_zone = calculate_noon_zone_display(current_seconds_utc, 188 - &display_name, 189 - &display_minutes, 190 - &display_seconds); 194 + // Check if gmtime succeeded and if it's a re-evaluation time point (:00, :15, :30) 195 + if (utc_tm_struct && (utc_tm_struct->tm_min % 15 == 0) && (utc_tm_struct->tm_min != 45) && (utc_tm_struct->tm_sec == 0)) { 196 + // Avoid re-evaluating multiple times within the same second if update is called rapidly 197 + if (current_utc_t != s_last_re_evaluation_time) { 198 + needs_re_evaluation = true; 199 + } 200 + } else if (s_last_re_evaluation_time == -1) { 201 + // Ensure initial evaluation happens if starting between intervals 202 + needs_re_evaluation = true; 203 + } 191 204 192 - if (found_zone) { 193 - snprintf(s_closest_noon_buffer, sizeof(s_closest_noon_buffer), 194 - "%s:%02ld:%02ld", display_name, display_minutes, display_seconds); 205 + if (needs_re_evaluation) { 206 + update_selected_timezone_and_city(current_utc_t); 207 + } 208 + 209 + 210 + // --- Calculate current local time based on selected zone --- 211 + // Use the stored offset from the last re-evaluation 212 + long current_offset_seconds = (long)(s_selected_offset_hours * 3600.0f); 213 + time_t local_time_epoch = current_utc_t + current_offset_seconds; // Use a distinct name 214 + 215 + // --- Format and display the time --- 216 + struct tm *current_local_tm_struct = gmtime(&local_time_epoch); // Use gmtime to format based on the calculated local epoch time 217 + 218 + // Check if a valid city was selected in the last evaluation or if it's fallback 219 + if (s_selected_city_name && strcmp(s_selected_city_name, "Wait...") != 0 && 220 + strncmp(s_selected_city_name, "ERR:", 4) != 0) 221 + { 222 + if (current_local_tm_struct) { 223 + // Display format: CityName:MM:SS using actual local time 224 + snprintf(s_closest_noon_buffer, sizeof(s_closest_noon_buffer), 225 + "%s:%02d:%02d", 226 + s_selected_city_name, // Already checked for null/error states 227 + current_local_tm_struct->tm_min, 228 + current_local_tm_struct->tm_sec); 229 + } else { 230 + // Handle gmtime failure for a selected city 231 + snprintf(s_closest_noon_buffer, sizeof(s_closest_noon_buffer), "%s:ERR:TIME", 232 + s_selected_city_name); 233 + } 195 234 } else { 196 - // Use the placeholder/error name returned by the helper 197 - snprintf(s_closest_noon_buffer, sizeof(s_closest_noon_buffer), "%s", display_name); 235 + // Display the fallback/error name directly (e.g., "Wait...", "ERR:NOZONE") 236 + snprintf(s_closest_noon_buffer, sizeof(s_closest_noon_buffer), "%s", 237 + s_selected_city_name ? s_selected_city_name : "ERR:NULL"); 198 238 } 199 239 240 + 200 241 text_layer_set_text(layer, s_closest_noon_buffer); 201 - last_closest_noon_update_secs = current_seconds_utc; 202 242 }
+263 -200
src/c/tz_list.c
··· 23 23 { "Midway" }, 24 24 { "Niue" }, 25 25 { "Pago Pago" }, 26 - { "Samoa" }, 27 26 }; 28 27 29 28 static const TzCityName tz_names_1[] = { 30 - { "Adak" }, 31 - { "Aleutian" }, 32 - { "Atka" }, 33 - { "Hawaii" }, 34 29 { "Honolulu" }, 35 30 { "Johnston" }, 36 31 { "Rarotonga" }, ··· 38 33 }; 39 34 40 35 static const TzCityName tz_names_2[] = { 36 + { "Adak" }, 37 + { "Atka" }, 38 + }; 39 + 40 + static const TzCityName tz_names_3[] = { 41 41 { "Marquesas" }, 42 42 }; 43 43 44 - static const TzCityName tz_names_3[] = { 45 - { "Alaska" }, 44 + static const TzCityName tz_names_4[] = { 45 + { "Gambier" }, 46 + }; 47 + 48 + static const TzCityName tz_names_5[] = { 46 49 { "Anchorage" }, 47 - { "Gambier" }, 48 50 { "Juneau" }, 49 51 { "Metlakatla" }, 50 52 { "Nome" }, ··· 52 54 { "Yakutat" }, 53 55 }; 54 56 55 - static const TzCityName tz_names_4[] = { 57 + static const TzCityName tz_names_6[] = { 58 + { "Pitcairn" }, 59 + }; 60 + 61 + static const TzCityName tz_names_7[] = { 56 62 { "BajaNorte" }, 57 63 { "Ensenada" }, 58 64 { "Los Angeles" }, 59 - { "Pacific" }, 60 - { "Pitcairn" }, 61 65 { "Santa Isabel" }, 62 66 { "Tijuana" }, 63 67 { "Vancouver" }, 64 68 }; 65 69 66 - static const TzCityName tz_names_5[] = { 67 - { "Arizona" }, 70 + static const TzCityName tz_names_8[] = { 68 71 { "BajaSur" }, 69 - { "Boise" }, 70 - { "Cambridge Bay" }, 71 - { "Ciudad Juarez" }, 72 72 { "Creston" }, 73 73 { "Dawson" }, 74 74 { "Dawson Creek" }, 75 - { "Denver" }, 76 - { "Edmonton" }, 77 75 { "Fort Nelson" }, 78 76 { "Hermosillo" }, 79 - { "Inuvik" }, 80 77 { "Mazatlan" }, 81 - { "Mountain" }, 82 78 { "Phoenix" }, 79 + { "Whitehorse" }, 80 + }; 81 + 82 + static const TzCityName tz_names_9[] = { 83 + { "Boise" }, 84 + { "Cambridge Bay" }, 85 + { "Ciudad Juarez" }, 86 + { "Denver" }, 87 + { "Edmonton" }, 88 + { "Inuvik" }, 83 89 { "Shiprock" }, 84 - { "Whitehorse" }, 85 90 { "Yellowknife" }, 86 - { "Yukon" }, 87 91 }; 88 92 89 - static const TzCityName tz_names_6[] = { 93 + static const TzCityName tz_names_10[] = { 90 94 { "Bahia Banderas" }, 91 95 { "Belize" }, 92 - { "Beulah" }, 93 - { "Center" }, 94 - { "Central" }, 95 - { "Chicago" }, 96 96 { "Chihuahua" }, 97 97 { "Costa Rica" }, 98 - { "Easter" }, 99 - { "EasterIsland" }, 100 98 { "El Salvador" }, 101 99 { "Galapagos" }, 102 - { "General" }, 103 100 { "Guatemala" }, 104 - { "Indiana-Starke" }, 105 - { "Knox" }, 106 - { "Knox IN" }, 107 101 { "Managua" }, 108 - { "Matamoros" }, 109 - { "Menominee" }, 110 102 { "Merida" }, 111 103 { "Mexico City" }, 112 104 { "Monterrey" }, 105 + { "Regina" }, 106 + { "Swift Current" }, 107 + { "Tegucigalpa" }, 108 + }; 109 + 110 + static const TzCityName tz_names_11[] = { 111 + { "Beulah" }, 112 + { "Center" }, 113 + { "Chicago" }, 114 + { "Indiana-Starke" }, 115 + { "Knox" }, 116 + { "Matamoros" }, 117 + { "Menominee" }, 113 118 { "New Salem" }, 114 119 { "Ojinaga" }, 115 120 { "Rainy River" }, 116 121 { "Rankin Inlet" }, 117 - { "Regina" }, 118 122 { "Resolute" }, 119 - { "Saskatchewan" }, 120 - { "Swift Current" }, 121 - { "Tegucigalpa" }, 122 123 { "Tell City" }, 123 124 { "Winnipeg" }, 124 125 }; 125 126 126 - static const TzCityName tz_names_7[] = { 127 - { "Acre" }, 127 + static const TzCityName tz_names_12[] = { 128 + { "Easter" }, 129 + }; 130 + 131 + static const TzCityName tz_names_13[] = { 128 132 { "Atikokan" }, 129 133 { "Bogota" }, 130 134 { "Cancun" }, 131 135 { "Cayman" }, 132 136 { "Coral Harbour" }, 133 - { "Detroit" }, 134 - { "East-Indiana" }, 135 - { "Eastern" }, 136 137 { "Eirunepe" }, 138 + { "Guayaquil" }, 139 + { "Lima" }, 140 + { "Panama" }, 141 + { "Porto Acre" }, 142 + { "Rio Branco" }, 143 + }; 144 + 145 + static const TzCityName tz_names_14[] = { 146 + { "Detroit" }, 137 147 { "Fort Wayne" }, 138 148 { "Grand Turk" }, 139 - { "Guayaquil" }, 140 - { "Havana" }, 141 149 { "Indianapolis" }, 142 150 { "Iqaluit" }, 143 - { "Jamaica" }, 144 - { "Lima" }, 145 151 { "Louisville" }, 146 152 { "Marengo" }, 147 - { "Michigan" }, 148 153 { "Monticello" }, 149 154 { "Montreal" }, 150 155 { "Nassau" }, 151 156 { "New York" }, 152 157 { "Nipigon" }, 153 - { "Panama" }, 154 158 { "Pangnirtung" }, 155 159 { "Petersburg" }, 156 160 { "Port-au-Prince" }, 157 - { "Porto Acre" }, 158 - { "Rio Branco" }, 159 161 { "Thunder Bay" }, 160 162 { "Toronto" }, 161 163 { "Vevay" }, ··· 163 165 { "Winamac" }, 164 166 }; 165 167 166 - static const TzCityName tz_names_8[] = { 168 + static const TzCityName tz_names_15[] = { 169 + { "Havana" }, 170 + }; 171 + 172 + static const TzCityName tz_names_16[] = { 167 173 { "Anguilla" }, 168 174 { "Antigua" }, 169 175 { "Aruba" }, 170 - { "Atlantic" }, 171 176 { "Barbados" }, 172 - { "Bermuda" }, 173 177 { "Blanc-Sablon" }, 174 178 { "Boa Vista" }, 175 179 { "Campo Grande" }, 176 180 { "Caracas" }, 177 - { "Continental" }, 178 181 { "Cuiaba" }, 179 182 { "Curacao" }, 180 183 { "Dominica" }, 181 - { "Glace Bay" }, 182 - { "Goose Bay" }, 183 184 { "Grenada" }, 184 185 { "Guadeloupe" }, 185 186 { "Guyana" }, 186 - { "Halifax" }, 187 187 { "Kralendijk" }, 188 188 { "La Paz" }, 189 189 { "Lower Princes" }, 190 190 { "Manaus" }, 191 191 { "Marigot" }, 192 192 { "Martinique" }, 193 - { "Moncton" }, 194 193 { "Montserrat" }, 195 194 { "Port of Spain" }, 196 195 { "Porto Velho" }, 197 196 { "Puerto Rico" }, 198 - { "Santiago" }, 199 197 { "Santo Domingo" }, 200 198 { "St Barthelemy" }, 201 199 { "St Kitts" }, 202 200 { "St Lucia" }, 203 201 { "St Thomas" }, 204 202 { "St Vincent" }, 205 - { "Thule" }, 206 203 { "Tortola" }, 207 204 { "Virgin" }, 208 - { "West" }, 205 + }; 206 + 207 + static const TzCityName tz_names_17[] = { 208 + { "Bermuda" }, 209 + { "Glace Bay" }, 210 + { "Goose Bay" }, 211 + { "Halifax" }, 212 + { "Moncton" }, 213 + { "Thule" }, 214 + }; 215 + 216 + static const TzCityName tz_names_18[] = { 217 + { "Santiago" }, 209 218 }; 210 219 211 - static const TzCityName tz_names_9[] = { 212 - { "Newfoundland" }, 220 + static const TzCityName tz_names_19[] = { 213 221 { "St Johns" }, 214 222 }; 215 223 216 - static const TzCityName tz_names_10[] = { 224 + static const TzCityName tz_names_20[] = { 217 225 { "Araguaina" }, 218 226 { "Asuncion" }, 219 - { "Bahia" }, 220 227 { "Belem" }, 221 228 { "Buenos Aires" }, 222 229 { "Catamarca" }, 223 230 { "Cayenne" }, 224 231 { "ComodRivadavia" }, 225 232 { "Cordoba" }, 226 - { "East" }, 227 233 { "Fortaleza" }, 228 234 { "Jujuy" }, 229 235 { "La Rioja" }, 230 236 { "Maceio" }, 231 237 { "Mendoza" }, 232 - { "Miquelon" }, 233 238 { "Montevideo" }, 234 239 { "Palmer" }, 235 240 { "Paramaribo" }, ··· 248 253 { "Ushuaia" }, 249 254 }; 250 255 251 - static const TzCityName tz_names_11[] = { 256 + static const TzCityName tz_names_21[] = { 257 + { "Miquelon" }, 258 + }; 259 + 260 + static const TzCityName tz_names_22[] = { 252 261 { "DeNoronha" }, 262 + }; 263 + 264 + static const TzCityName tz_names_23[] = { 253 265 { "Godthab" }, 254 - { "Noronha" }, 255 266 { "Nuuk" }, 256 267 { "Scoresbysund" }, 257 - { "South Georgia" }, 268 + }; 269 + 270 + static const TzCityName tz_names_24[] = { 271 + { "Cape Verde" }, 258 272 }; 259 273 260 - static const TzCityName tz_names_12[] = { 274 + static const TzCityName tz_names_25[] = { 261 275 { "Azores" }, 262 - { "Cape Verde" }, 263 276 }; 264 277 265 - static const TzCityName tz_names_13[] = { 278 + static const TzCityName tz_names_26[] = { 266 279 { "Abidjan" }, 267 280 { "Accra" }, 268 281 { "Bamako" }, 269 282 { "Banjul" }, 270 - { "Belfast" }, 271 283 { "Bissau" }, 272 - { "Canary" }, 273 - { "Casablanca" }, 274 284 { "Conakry" }, 275 285 { "Dakar" }, 276 286 { "Danmarkshavn" }, 277 - { "Dublin" }, 278 - { "El Aaiun" }, 279 - { "Faeroe" }, 280 - { "Faroe" }, 281 287 { "Freetown" }, 282 - { "Guernsey" }, 283 - { "Isle of Man" }, 284 - { "Jersey" }, 285 - { "Lisbon" }, 286 288 { "Lome" }, 287 - { "London" }, 288 - { "Madeira" }, 289 289 { "Monrovia" }, 290 290 { "Nouakchott" }, 291 291 { "Ouagadougou" }, ··· 293 293 { "Sao Tome" }, 294 294 { "St Helena" }, 295 295 { "Timbuktu" }, 296 + }; 297 + 298 + static const TzCityName tz_names_27[] = { 299 + { "Belfast" }, 300 + { "Dublin" }, 301 + { "Lisbon" }, 302 + { "London" }, 303 + }; 304 + 305 + static const TzCityName tz_names_28[] = { 306 + { "Casablanca" }, 307 + { "El Aaiun" }, 308 + }; 309 + 310 + static const TzCityName tz_names_29[] = { 296 311 { "Troll" }, 297 312 }; 298 313 299 - static const TzCityName tz_names_14[] = { 314 + static const TzCityName tz_names_30[] = { 300 315 { "Algiers" }, 316 + { "Bangui" }, 317 + { "Brazzaville" }, 318 + { "Douala" }, 319 + { "Kinshasa" }, 320 + { "Lagos" }, 321 + { "Libreville" }, 322 + { "Luanda" }, 323 + { "Malabo" }, 324 + { "Ndjamena" }, 325 + { "Niamey" }, 326 + { "Porto-Novo" }, 327 + { "Tunis" }, 328 + }; 329 + 330 + static const TzCityName tz_names_31[] = { 301 331 { "Amsterdam" }, 302 332 { "Andorra" }, 303 - { "Bangui" }, 304 333 { "Belgrade" }, 305 334 { "Berlin" }, 306 335 { "Bratislava" }, 307 - { "Brazzaville" }, 308 336 { "Brussels" }, 309 337 { "Budapest" }, 310 338 { "Busingen" }, 311 339 { "Ceuta" }, 312 340 { "Copenhagen" }, 313 - { "Douala" }, 314 341 { "Gibraltar" }, 315 - { "Jan Mayen" }, 316 - { "Kinshasa" }, 317 - { "Lagos" }, 318 - { "Libreville" }, 319 342 { "Ljubljana" }, 320 343 { "Longyearbyen" }, 321 - { "Luanda" }, 322 344 { "Luxembourg" }, 323 345 { "Madrid" }, 324 - { "Malabo" }, 325 346 { "Malta" }, 326 347 { "Monaco" }, 327 - { "Ndjamena" }, 328 - { "Niamey" }, 329 348 { "Oslo" }, 330 349 { "Paris" }, 331 350 { "Podgorica" }, 332 - { "Porto-Novo" }, 333 351 { "Prague" }, 334 352 { "Rome" }, 335 353 { "San Marino" }, ··· 337 355 { "Skopje" }, 338 356 { "Stockholm" }, 339 357 { "Tirane" }, 340 - { "Tunis" }, 341 358 { "Vaduz" }, 342 359 { "Vatican" }, 343 360 { "Vienna" }, ··· 346 363 { "Zurich" }, 347 364 }; 348 365 349 - static const TzCityName tz_names_15[] = { 350 - { "Athens" }, 351 - { "Beirut" }, 366 + static const TzCityName tz_names_32[] = { 352 367 { "Blantyre" }, 353 - { "Bucharest" }, 354 368 { "Bujumbura" }, 355 - { "Cairo" }, 356 - { "Chisinau" }, 357 - { "Famagusta" }, 358 369 { "Gaborone" }, 359 - { "Gaza" }, 360 370 { "Harare" }, 361 - { "Hebron" }, 362 - { "Helsinki" }, 363 - { "Jerusalem" }, 364 371 { "Johannesburg" }, 365 372 { "Juba" }, 366 373 { "Kaliningrad" }, 367 374 { "Khartoum" }, 368 - { "Kiev" }, 369 375 { "Kigali" }, 370 - { "Kyiv" }, 371 376 { "Lubumbashi" }, 372 377 { "Lusaka" }, 373 378 { "Maputo" }, 374 - { "Mariehamn" }, 375 379 { "Maseru" }, 376 380 { "Mbabane" }, 381 + { "Tripoli" }, 382 + { "Windhoek" }, 383 + }; 384 + 385 + static const TzCityName tz_names_33[] = { 386 + { "Jerusalem" }, 387 + { "Tel Aviv" }, 388 + }; 389 + 390 + static const TzCityName tz_names_34[] = { 391 + { "Athens" }, 392 + { "Bucharest" }, 393 + { "Famagusta" }, 394 + { "Helsinki" }, 395 + { "Kiev" }, 396 + { "Kyiv" }, 397 + { "Mariehamn" }, 377 398 { "Nicosia" }, 378 399 { "Riga" }, 379 400 { "Sofia" }, 380 401 { "Tallinn" }, 381 - { "Tel Aviv" }, 382 - { "Tiraspol" }, 383 - { "Tripoli" }, 384 402 { "Uzhgorod" }, 385 403 { "Vilnius" }, 386 - { "Windhoek" }, 387 404 { "Zaporozhye" }, 388 405 }; 389 406 390 - static const TzCityName tz_names_16[] = { 407 + static const TzCityName tz_names_35[] = { 408 + { "Gaza" }, 409 + { "Hebron" }, 410 + }; 411 + 412 + static const TzCityName tz_names_36[] = { 413 + { "Cairo" }, 414 + }; 415 + 416 + static const TzCityName tz_names_37[] = { 417 + { "Chisinau" }, 418 + { "Tiraspol" }, 419 + }; 420 + 421 + static const TzCityName tz_names_38[] = { 422 + { "Beirut" }, 423 + }; 424 + 425 + static const TzCityName tz_names_39[] = { 391 426 { "Addis Ababa" }, 392 427 { "Aden" }, 393 428 { "Amman" }, ··· 416 451 { "Volgograd" }, 417 452 }; 418 453 419 - static const TzCityName tz_names_17[] = { 454 + static const TzCityName tz_names_40[] = { 420 455 { "Tehran" }, 421 456 }; 422 457 423 - static const TzCityName tz_names_18[] = { 458 + static const TzCityName tz_names_41[] = { 424 459 { "Astrakhan" }, 425 460 { "Baku" }, 426 461 { "Dubai" }, ··· 435 470 { "Yerevan" }, 436 471 }; 437 472 438 - static const TzCityName tz_names_19[] = { 473 + static const TzCityName tz_names_42[] = { 439 474 { "Kabul" }, 440 475 }; 441 476 442 - static const TzCityName tz_names_20[] = { 477 + static const TzCityName tz_names_43[] = { 443 478 { "Almaty" }, 444 479 { "Aqtau" }, 445 480 { "Aqtobe" }, ··· 460 495 { "Yekaterinburg" }, 461 496 }; 462 497 463 - static const TzCityName tz_names_21[] = { 498 + static const TzCityName tz_names_44[] = { 464 499 { "Calcutta" }, 465 500 { "Colombo" }, 466 501 { "Kolkata" }, 467 502 }; 468 503 469 - static const TzCityName tz_names_22[] = { 504 + static const TzCityName tz_names_45[] = { 470 505 { "Kathmandu" }, 471 506 { "Katmandu" }, 472 507 }; 473 508 474 - static const TzCityName tz_names_23[] = { 509 + static const TzCityName tz_names_46[] = { 475 510 { "Bishkek" }, 476 511 { "Chagos" }, 477 512 { "Dacca" }, ··· 483 518 { "Urumqi" }, 484 519 }; 485 520 486 - static const TzCityName tz_names_24[] = { 521 + static const TzCityName tz_names_47[] = { 487 522 { "Cocos" }, 488 523 { "Rangoon" }, 489 524 { "Yangon" }, 490 525 }; 491 526 492 - static const TzCityName tz_names_25[] = { 527 + static const TzCityName tz_names_48[] = { 493 528 { "Bangkok" }, 494 529 { "Barnaul" }, 495 530 { "Christmas" }, ··· 507 542 { "Vientiane" }, 508 543 }; 509 544 510 - static const TzCityName tz_names_26[] = { 545 + static const TzCityName tz_names_49[] = { 511 546 { "Brunei" }, 512 547 { "Casey" }, 513 548 { "Choibalsan" }, ··· 529 564 { "Ujung Pandang" }, 530 565 { "Ulaanbaatar" }, 531 566 { "Ulan Bator" }, 532 - { "West" }, 533 567 }; 534 568 535 - static const TzCityName tz_names_27[] = { 569 + static const TzCityName tz_names_50[] = { 536 570 { "Eucla" }, 537 571 }; 538 572 539 - static const TzCityName tz_names_28[] = { 573 + static const TzCityName tz_names_51[] = { 540 574 { "Chita" }, 541 575 { "Dili" }, 542 576 { "Jayapura" }, ··· 548 582 { "Yakutsk" }, 549 583 }; 550 584 551 - static const TzCityName tz_names_29[] = { 585 + static const TzCityName tz_names_52[] = { 586 + { "Darwin" }, 587 + }; 588 + 589 + static const TzCityName tz_names_53[] = { 552 590 { "Adelaide" }, 553 591 { "Broken Hill" }, 554 - { "Darwin" }, 555 - { "North" }, 556 - { "South" }, 557 592 { "Yancowinna" }, 558 593 }; 559 594 560 - static const TzCityName tz_names_30[] = { 561 - { "ACT" }, 595 + static const TzCityName tz_names_54[] = { 562 596 { "Brisbane" }, 563 - { "Canberra" }, 564 597 { "Chuuk" }, 565 - { "Currie" }, 566 598 { "DumontDUrville" }, 567 599 { "Guam" }, 568 - { "Hobart" }, 569 600 { "Lindeman" }, 570 - { "Macquarie" }, 571 - { "Melbourne" }, 572 - { "NSW" }, 573 601 { "Port Moresby" }, 574 - { "Queensland" }, 575 602 { "Saipan" }, 576 - { "Sydney" }, 577 - { "Tasmania" }, 578 603 { "Truk" }, 579 604 { "Ust-Nera" }, 580 - { "Victoria" }, 581 605 { "Vladivostok" }, 582 - { "Yap" }, 606 + }; 607 + 608 + static const TzCityName tz_names_55[] = { 609 + { "Canberra" }, 610 + { "Currie" }, 611 + { "Hobart" }, 612 + { "Macquarie" }, 613 + { "Melbourne" }, 614 + { "Sydney" }, 583 615 }; 584 616 585 - static const TzCityName tz_names_31[] = { 617 + static const TzCityName tz_names_56[] = { 586 618 { "LHI" }, 587 619 { "Lord Howe" }, 588 620 }; 589 621 590 - static const TzCityName tz_names_32[] = { 622 + static const TzCityName tz_names_57[] = { 591 623 { "Bougainville" }, 592 624 { "Efate" }, 593 625 { "Guadalcanal" }, 594 626 { "Kosrae" }, 595 627 { "Magadan" }, 596 - { "Norfolk" }, 597 628 { "Noumea" }, 598 629 { "Pohnpei" }, 599 630 { "Ponape" }, ··· 601 632 { "Srednekolymsk" }, 602 633 }; 603 634 604 - static const TzCityName tz_names_33[] = { 635 + static const TzCityName tz_names_58[] = { 636 + { "Norfolk" }, 637 + }; 638 + 639 + static const TzCityName tz_names_59[] = { 605 640 { "Anadyr" }, 606 - { "Auckland" }, 607 641 { "Fiji" }, 608 642 { "Funafuti" }, 609 643 { "Kamchatka" }, 610 644 { "Kwajalein" }, 611 645 { "Majuro" }, 612 - { "McMurdo" }, 613 646 { "Nauru" }, 614 - { "South Pole" }, 615 647 { "Tarawa" }, 616 648 { "Wake" }, 617 649 { "Wallis" }, 618 650 }; 619 651 620 - static const TzCityName tz_names_34[] = { 652 + static const TzCityName tz_names_60[] = { 653 + { "Auckland" }, 654 + { "McMurdo" }, 655 + }; 656 + 657 + static const TzCityName tz_names_61[] = { 621 658 { "Chatham" }, 622 659 }; 623 660 624 - static const TzCityName tz_names_35[] = { 661 + static const TzCityName tz_names_62[] = { 625 662 { "Apia" }, 626 663 { "Enderbury" }, 627 664 { "Fakaofo" }, 628 - { "Kanton" }, 629 665 { "Tongatapu" }, 630 666 }; 631 667 632 - static const TzCityName tz_names_36[] = { 668 + static const TzCityName tz_names_63[] = { 633 669 { "Kiritimati" }, 634 670 }; 635 671 636 672 // Main list mapping offsets/DST info to their respective name arrays 637 673 static const TzInfo tz_list[] = { 638 - { -11.00f, -11.00f, 0LL, 0LL, tz_names_0, 4 }, 639 - { -10.00f, -10.00f, 0LL, 0LL, tz_names_1, 8 }, 640 - { -9.50f, -9.50f, 0LL, 0LL, tz_names_2, 1 }, 641 - { -9.00f, -8.00f, 1741489200LL, 1762048800LL, tz_names_3, 8 }, 642 - { -8.00f, -7.00f, 1741489200LL, 1762048800LL, tz_names_4, 8 }, 643 - { -7.00f, -6.00f, 1741489200LL, 1762048800LL, tz_names_5, 20 }, 644 - { -6.00f, -6.00f, 0LL, 0LL, tz_names_6, 34 }, 645 - { -5.00f, -4.00f, 1741489200LL, 1762048800LL, tz_names_7, 37 }, 646 - { -4.00f, -3.00f, 1741489200LL, 1762048800LL, tz_names_8, 42 }, 647 - { -3.50f, -2.50f, 1741489200LL, 1762048800LL, tz_names_9, 2 }, 648 - { -3.00f, -3.00f, 0LL, 0LL, tz_names_10, 32 }, 649 - { -2.00f, -1.00f, 1743292800LL, 1761436800LL, tz_names_11, 6 }, 650 - { -1.00f, 0.00f, 1743296400LL, 1761440400LL, tz_names_12, 2 }, 651 - { 0.00f, 1.00f, 1743300000LL, 1761444000LL, tz_names_13, 31 }, 652 - { 1.00f, 2.00f, 1743303600LL, 1761447600LL, tz_names_14, 47 }, 653 - { 2.00f, 3.00f, 1745542800LL, 1761868800LL, tz_names_15, 38 }, 654 - { 3.00f, 3.00f, 0LL, 0LL, tz_names_16, 26 }, 655 - { 3.50f, 3.50f, 0LL, 0LL, tz_names_17, 1 }, 656 - { 4.00f, 4.00f, 0LL, 0LL, tz_names_18, 12 }, 657 - { 4.50f, 4.50f, 0LL, 0LL, tz_names_19, 1 }, 658 - { 5.00f, 5.00f, 0LL, 0LL, tz_names_20, 18 }, 659 - { 5.50f, 5.50f, 0LL, 0LL, tz_names_21, 3 }, 660 - { 5.75f, 5.75f, 0LL, 0LL, tz_names_22, 2 }, 661 - { 6.00f, 6.00f, 0LL, 0LL, tz_names_23, 9 }, 662 - { 6.50f, 6.50f, 0LL, 0LL, tz_names_24, 3 }, 663 - { 7.00f, 7.00f, 0LL, 0LL, tz_names_25, 15 }, 664 - { 8.00f, 8.00f, 0LL, 0LL, tz_names_26, 22 }, 665 - { 8.75f, 8.75f, 0LL, 0LL, tz_names_27, 1 }, 666 - { 9.00f, 9.00f, 0LL, 0LL, tz_names_28, 9 }, 667 - { 9.50f, 10.50f, 1759633200LL, 1743908400LL, tz_names_29, 6 }, 668 - { 10.00f, 10.00f, 0LL, 0LL, tz_names_30, 22 }, 669 - { 10.50f, 11.00f, 1759633200LL, 1743904800LL, tz_names_31, 2 }, 670 - { 11.00f, 11.00f, 0LL, 0LL, tz_names_32, 11 }, 671 - { 12.00f, 12.00f, 0LL, 0LL, tz_names_33, 13 }, 672 - { 12.75f, 13.75f, 1759032000LL, 1743912000LL, tz_names_34, 1 }, 673 - { 13.00f, 13.00f, 0LL, 0LL, tz_names_35, 5 }, 674 - { 14.00f, 14.00f, 0LL, 0LL, tz_names_36, 1 }, 674 + { -11.00f, -11.00f, 0LL, 0LL, tz_names_0, 3 }, 675 + { -10.00f, -10.00f, 0LL, 0LL, tz_names_1, 4 }, 676 + { -10.00f, -9.00f, 1741489200LL, 1762048800LL, tz_names_2, 2 }, 677 + { -9.50f, -9.50f, 0LL, 0LL, tz_names_3, 1 }, 678 + { -9.00f, -9.00f, 0LL, 0LL, tz_names_4, 1 }, 679 + { -9.00f, -8.00f, 1741489200LL, 1762048800LL, tz_names_5, 6 }, 680 + { -8.00f, -8.00f, 0LL, 0LL, tz_names_6, 1 }, 681 + { -8.00f, -7.00f, 1741489200LL, 1762048800LL, tz_names_7, 6 }, 682 + { -7.00f, -7.00f, 0LL, 0LL, tz_names_8, 9 }, 683 + { -7.00f, -6.00f, 1741489200LL, 1762048800LL, tz_names_9, 8 }, 684 + { -6.00f, -6.00f, 0LL, 0LL, tz_names_10, 14 }, 685 + { -6.00f, -5.00f, 1741489200LL, 1762048800LL, tz_names_11, 14 }, 686 + { -6.00f, -5.00f, 1757199600LL, 1743890400LL, tz_names_12, 1 }, 687 + { -5.00f, -5.00f, 0LL, 0LL, tz_names_13, 11 }, 688 + { -5.00f, -4.00f, 1741489200LL, 1762048800LL, tz_names_14, 20 }, 689 + { -5.00f, -4.00f, 1741482000LL, 1762045200LL, tz_names_15, 1 }, 690 + { -4.00f, -4.00f, 0LL, 0LL, tz_names_16, 32 }, 691 + { -4.00f, -3.00f, 1741489200LL, 1762048800LL, tz_names_17, 6 }, 692 + { -4.00f, -3.00f, 1757206800LL, 1743897600LL, tz_names_18, 1 }, 693 + { -3.50f, -2.50f, 1741489200LL, 1762048800LL, tz_names_19, 1 }, 694 + { -3.00f, -3.00f, 0LL, 0LL, tz_names_20, 29 }, 695 + { -3.00f, -2.00f, 1741489200LL, 1762048800LL, tz_names_21, 1 }, 696 + { -2.00f, -2.00f, 0LL, 0LL, tz_names_22, 1 }, 697 + { -2.00f, -1.00f, 1743292800LL, 1761436800LL, tz_names_23, 3 }, 698 + { -1.00f, -1.00f, 0LL, 0LL, tz_names_24, 1 }, 699 + { -1.00f, 0.00f, 1743296400LL, 1761440400LL, tz_names_25, 1 }, 700 + { 0.00f, 0.00f, 0LL, 0LL, tz_names_26, 17 }, 701 + { 0.00f, 1.00f, 1743300000LL, 1761444000LL, tz_names_27, 4 }, 702 + { 0.00f, 1.00f, 1743908400LL, 1740279600LL, tz_names_28, 2 }, 703 + { 0.00f, 2.00f, 1743303600LL, 1761447600LL, tz_names_29, 1 }, 704 + { 1.00f, 1.00f, 0LL, 0LL, tz_names_30, 13 }, 705 + { 1.00f, 2.00f, 1743303600LL, 1761447600LL, tz_names_31, 33 }, 706 + { 2.00f, 2.00f, 0LL, 0LL, tz_names_32, 16 }, 707 + { 2.00f, 3.00f, 1743130800LL, 1761444000LL, tz_names_33, 2 }, 708 + { 2.00f, 3.00f, 1743307200LL, 1761451200LL, tz_names_34, 14 }, 709 + { 2.00f, 3.00f, 1744426800LL, 1761357600LL, tz_names_35, 2 }, 710 + { 2.00f, 3.00f, 1745542800LL, 1761868800LL, tz_names_36, 1 }, 711 + { 2.00f, 3.00f, 1743303600LL, 1761447600LL, tz_names_37, 2 }, 712 + { 2.00f, 3.00f, 1743296400LL, 1761436800LL, tz_names_38, 1 }, 713 + { 3.00f, 3.00f, 0LL, 0LL, tz_names_39, 26 }, 714 + { 3.50f, 3.50f, 0LL, 0LL, tz_names_40, 1 }, 715 + { 4.00f, 4.00f, 0LL, 0LL, tz_names_41, 12 }, 716 + { 4.50f, 4.50f, 0LL, 0LL, tz_names_42, 1 }, 717 + { 5.00f, 5.00f, 0LL, 0LL, tz_names_43, 18 }, 718 + { 5.50f, 5.50f, 0LL, 0LL, tz_names_44, 3 }, 719 + { 5.75f, 5.75f, 0LL, 0LL, tz_names_45, 2 }, 720 + { 6.00f, 6.00f, 0LL, 0LL, tz_names_46, 9 }, 721 + { 6.50f, 6.50f, 0LL, 0LL, tz_names_47, 3 }, 722 + { 7.00f, 7.00f, 0LL, 0LL, tz_names_48, 15 }, 723 + { 8.00f, 8.00f, 0LL, 0LL, tz_names_49, 21 }, 724 + { 8.75f, 8.75f, 0LL, 0LL, tz_names_50, 1 }, 725 + { 9.00f, 9.00f, 0LL, 0LL, tz_names_51, 9 }, 726 + { 9.50f, 9.50f, 0LL, 0LL, tz_names_52, 1 }, 727 + { 9.50f, 10.50f, 1759633200LL, 1743908400LL, tz_names_53, 3 }, 728 + { 10.00f, 10.00f, 0LL, 0LL, tz_names_54, 10 }, 729 + { 10.00f, 11.00f, 1759633200LL, 1743908400LL, tz_names_55, 6 }, 730 + { 10.50f, 11.00f, 1759633200LL, 1743904800LL, tz_names_56, 2 }, 731 + { 11.00f, 11.00f, 0LL, 0LL, tz_names_57, 10 }, 732 + { 11.00f, 12.00f, 1759633200LL, 1743908400LL, tz_names_58, 1 }, 733 + { 12.00f, 12.00f, 0LL, 0LL, tz_names_59, 10 }, 734 + { 12.00f, 13.00f, 1759028400LL, 1743908400LL, tz_names_60, 2 }, 735 + { 12.75f, 13.75f, 1759032000LL, 1743912000LL, tz_names_61, 1 }, 736 + { 13.00f, 13.00f, 0LL, 0LL, tz_names_62, 4 }, 737 + { 14.00f, 14.00f, 0LL, 0LL, tz_names_63, 1 }, 675 738 }; 676 739 677 - #define TZ_LIST_COUNT 37 740 + #define TZ_LIST_COUNT 64
+1 -1
src/c/watchface.c
··· 1 1 #include <pebble.h> 2 2 #include <stdlib.h> 3 - #include <time.h> // Required for time_t, rand(), srand() 3 + #include <time.h> 4 4 5 5 // --- Clock Module Includes --- 6 6 #include "clock_beat.h"