#define MAX_TIMEZONE_HOURS 24
#define TIME_MAX 64
#define TIME_FLOW_PREFIX "[TIME_FLOW][时间链路] "
+#define MIN_VALID_RESTORE_SEC 946684800UL /* 2000-01-01 00:00:00 */
+#define DEFAULT_FALLBACK_UTC_SEC 1735660800UL /* 2025-01-01 00:00:00 */
+#define TIME_BIN_PATH "/user/userdata/time.bin"
+
+static uint32_t build_reasonable_fallback_local_sec(uint16_t timezone_quarters)
+{
+ uint32_t utc_now = get_current_timestamp();
+ uint32_t zone_offset_sec = timezone_quarters * MINUTES_PER_QUARTER * SECONDS_PER_MINUTE;
+
+ /*
+ * Prefer current RTC time when it already looks reasonable; otherwise
+ * fallback to a fixed baseline to avoid 1970/zero timestamp.
+ */
+ if (utc_now >= MIN_VALID_RESTORE_SEC) {
+ return utc_now + zone_offset_sec;
+ }
+ return DEFAULT_FALLBACK_UTC_SEC + zone_offset_sec;
+}
+
+static void save_time_bin(uint32_t utc_sec)
+{
+ FILE *fp = fopen(TIME_BIN_PATH, "wb");
+ if (fp == NULL) {
+ printf(TIME_FLOW_PREFIX "save_time_bin: open failed, path=%s\r\n", TIME_BIN_PATH);
+ return;
+ }
+ size_t write_cnt = fwrite(&utc_sec, sizeof(utc_sec), 1, fp);
+ fclose(fp);
+ if (write_cnt != 1) {
+ printf(TIME_FLOW_PREFIX "save_time_bin: write failed\r\n");
+ return;
+ }
+ printf(TIME_FLOW_PREFIX "save_time_bin: utc_sec=%u\r\n", utc_sec);
+}
+
+static bool load_time_bin(uint32_t *utc_sec)
+{
+ if (utc_sec == NULL) {
+ return false;
+ }
+
+ FILE *fp = fopen(TIME_BIN_PATH, "rb");
+ if (fp == NULL) {
+ return false;
+ }
+ size_t read_cnt = fread(utc_sec, sizeof(*utc_sec), 1, fp);
+ fclose(fp);
+ if (read_cnt != 1 || *utc_sec < MIN_VALID_RESTORE_SEC) {
+ return false;
+ }
+ return true;
+}
void print_time(calendar_t *date)
{
printf(TIME_FLOW_PREFIX "save_time: local_sec=%u, write_calendar_ms=%llu\r\n",
(uint32_t)get_local_timestamp(), (unsigned long long)time_sec);
uapi_calendar_set_timestamp(time_sec);
+ save_time_bin(get_current_timestamp());
}
uint32_t get_current_timestamp(void)
uapi_calendar_get_timestamp(&sec);
printf("callendar timestamp = %lld \r\n", sec);
sec = sec / MSEC_PER_SEC;
+ uint16_t timezone_quarters = uapi_get_timezone();
+ if ((sec < MIN_VALID_RESTORE_SEC) || (sec > UINT32_MAX)) {
+ uint32_t file_utc_sec = 0;
+ if (load_time_bin(&file_utc_sec)) {
+ printf(TIME_FLOW_PREFIX "restore_time: invalid calendar timestamp=%llu, use time.bin utc=%u\r\n",
+ (unsigned long long)sec, file_utc_sec);
+ sync_time_utc(file_utc_sec, timezone_quarters);
+ } else {
+ uint32_t fallback_local_sec = build_reasonable_fallback_local_sec(timezone_quarters);
+ printf(TIME_FLOW_PREFIX "restore_time: invalid calendar timestamp=%llu, use fallback_local=%u\r\n",
+ (unsigned long long)sec, fallback_local_sec);
+ sync_time(fallback_local_sec, timezone_quarters);
+ }
+ } else {
printf(TIME_FLOW_PREFIX "restore_time: read_calendar_sec=%llu, timezone_quarters=%u\r\n",
- (unsigned long long)sec, uapi_get_timezone());
- sync_time(sec, uapi_get_timezone());
- printf(TIME_FLOW_PREFIX "restore_time: after_sync utc_now=%u, local_now=%u\r\n",
- get_current_timestamp(), get_local_timestamp());
+ (unsigned long long)sec, timezone_quarters);
+ sync_time((uint32_t)sec, timezone_quarters);
+ }
+ uint32_t utc_now = get_current_timestamp();
+ uint32_t local_now = get_local_timestamp();
+ printf(TIME_FLOW_PREFIX "restore_time: after_sync utc_now=%u, local_now=%u\r\n", utc_now, local_now);
+
+ struct tm local_tm = {0};
+ time_t utc_sec = (time_t)utc_now;
+ localtime_r(&utc_sec, &local_tm);
+ printf(TIME_FLOW_PREFIX "restore_time: actual_local_time=%04d-%02d-%02d %02d:%02d:%02d\r\n",
+ local_tm.tm_year + 1900, local_tm.tm_mon + 1, local_tm.tm_mday,
+ local_tm.tm_hour, local_tm.tm_min, local_tm.tm_sec);
}
uint32_t sync_time_utc(uint32_t timestamp, uint32_t timezone_quarters)
{