解决计时器因32 位无符号整数溢出导致提前响铃bug
authorluozheng <1732036298@qq.com>
Wed, 18 Mar 2026 08:20:58 +0000 (16:20 +0800)
committerCaisking <Casiking@zhihuishixun.com>
Wed, 18 Mar 2026 08:52:29 +0000 (16:52 +0800)
code/sdk/application/wearable/fd272/nativeapp/nativeui/countdown/include/CountDownModel.h
code/sdk/application/wearable/fd272/nativeapp/nativeui/countdown/src/CountDownModel.cpp

index 41810b9..4cdf795 100644 (file)
@@ -120,13 +120,13 @@ namespace OHOS
         bool GetisPaused(void) const {\r
             return isPaused;\r
         }\r
-        uint32_t get_current_time(); // 获取当前系统时间戳(ms)\r
+        uint64_t get_current_time(); // 获取当前系统时间戳(ms)\r
     public:\r
         static int g_CountDownTimes;\r
         static int totalSeconds;    //要到计时总秒数\r
-        static uint32_t startTime;  // 开始时间戳(ms)\r
-        static uint32_t pauseTime;  // 暂停时间戳(ms)\r
-        static uint32_t endTime;    // 结束时间戳(ms)\r
+        static uint64_t startTime;  // 开始时间戳(ms)\r
+        static uint64_t pauseTime;  // 暂停时间戳(ms)\r
+        static uint64_t endTime;    // 结束时间戳(ms)\r
 \r
     private:\r
         CountDownModel() {}\r
index 818267f..6248567 100644 (file)
@@ -29,9 +29,9 @@ namespace OHOS
     static osTimerId_t g_timer = nullptr;\r
     int CountDownModel::g_CountDownTimes = {0};\r
     int CountDownModel::totalSeconds = 0; //总的倒计时时间\r
-    uint32_t CountDownModel::startTime = 0;\r
-    uint32_t CountDownModel::pauseTime = 0;\r
-    uint32_t CountDownModel::endTime = 0;\r
+    uint64_t CountDownModel::startTime = 0;\r
+    uint64_t CountDownModel::pauseTime = 0;\r
+    uint64_t CountDownModel::endTime = 0;\r
     static constexpr int32 NUM_TEN = 10; // 主要用于格式化输出,当小时、分钟或秒小于10时,在其前面添加一个’0’以保持常规时间格式,例如“09:05:03”。\r
     static constexpr int16 NUM_TIME_MIN = 60;\r
     static constexpr int16 NUM_TIME_HOUR = 3600;\r
@@ -463,27 +463,31 @@ namespace OHOS
 \r
         if (isRunning && !isPaused) \r
         {\r
-            uint32_t currentTime = CountDownModel::GetInstance()->get_current_time();\r
+            uint64_t currentTime = CountDownModel::GetInstance()->get_current_time();\r
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "currentTime(ms):%llu,endTime(ms):%llu",currentTime,CountDownModel::endTime);\r
             if (currentTime >= CountDownModel::endTime) {\r
                 CountDownModel::g_CountDownTimes = 0;\r
                 // 这里可以添加倒计时结束后的操作,比如发出提示音等\r
                 GraphicService::GetInstance()->PostGraphicEvent(std::bind(CountDown_TimerCallbackProc, data));\r
                 return;\r
             }\r
-            uint32_t remainingMs = CountDownModel::endTime - currentTime;\r
+            uint64_t remainingMs = CountDownModel::endTime - currentTime;\r
             CountDownModel::g_CountDownTimes = static_cast<int32_t>((remainingMs + 999) / 1000); // ceil to seconds\r
             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "当前时间戳(ms):%u,倒计时剩余时间(s):%d", currentTime, CountDownModel::g_CountDownTimes);\r
         }\r
     }\r
 \r
-    uint32_t CountDownModel::get_current_time()\r
+    uint64_t CountDownModel::get_current_time()\r
     {\r
-        uint32_t time;\r
-        if (uapi_get_timestampe_ms(&time) != ERRCODE_SUCC) {\r
+        uint32_t time = 0;\r
+        if (uapi_get_timestampe_ss(&time) != ERRCODE_SUCC) {\r
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get timestamp");\r
             return 0;\r
-        }\r
-        return time;\r
+        } // 秒级时间戳转换成毫秒级时间戳\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "currentTime(ms)转换前:%u",time);\r
+        uint64_t timeMs = static_cast<uint64_t>(time) * 1000; // 秒级时间戳转换成毫秒级时间戳\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "currentTime(ms)转换后:%llu",timeMs);\r
+        return timeMs;\r
     }\r
 \r
     void CountDownModel::countdownstart()\r
@@ -491,9 +495,10 @@ namespace OHOS
         isRunning = true;\r
         isPaused = false;\r
         CountDownModel::totalSeconds = CountDownModel::g_CountDownTimes;\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "totalSeconds:%u",CountDownModel::get_current_time());\r
         CountDownModel::startTime = get_current_time();         //获取开始时间戳\r
-        CountDownModel::endTime = CountDownModel::startTime + static_cast<uint32_t>(g_CountDownTimes) * 1000; //获取结束时间戳(ms)\r
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "startTime(ms):%u,endTime(ms):%u",CountDownModel::startTime,CountDownModel::endTime);\r
+        CountDownModel::endTime = CountDownModel::startTime + static_cast<uint64_t>(g_CountDownTimes) * 1000; //获取结束时间戳(ms)\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "startTime(ms):%llu,endTime(ms):%llu,totalSeconds:%d",CountDownModel::startTime,CountDownModel::endTime,CountDownModel::totalSeconds);\r
 \r
     }\r
     \r
@@ -508,16 +513,16 @@ namespace OHOS
     {\r
         if (isRunning && isPaused) {\r
             isPaused = false;\r
-            uint32_t currentTime = get_current_time();\r
-            uint32_t pauseDuration = currentTime - CountDownModel::pauseTime;\r
+            uint64_t currentTime = get_current_time();\r
+            uint64_t pauseDuration = currentTime - CountDownModel::pauseTime;\r
             CountDownModel::endTime = CountDownModel::endTime + pauseDuration;\r
             if (currentTime >= CountDownModel::endTime) {\r
                 CountDownModel::g_CountDownTimes = 0;\r
             } else {\r
-                uint32_t remainingMs = CountDownModel::endTime - currentTime;\r
+                uint64_t remainingMs = CountDownModel::endTime - currentTime;\r
                 CountDownModel::g_CountDownTimes = static_cast<int32_t>((remainingMs + 999) / 1000); // ceil to seconds\r
             }\r
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "startTime(ms):%u,pauseDuration(ms):%u,endTime(ms):%u",\r
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "startTime(ms):%llu,pauseDuration(ms):%llu,endTime(ms):%llu",\r
                 CountDownModel::startTime, pauseDuration, CountDownModel::endTime);\r
         }\r
     }\r