1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "utils_datetime.h" 17 18#include <time.h> 19 20#ifdef __cplusplus 21extern "C" { 22#endif 23 24#define SEC_TO_NANOSEC 1000000000 25#define SEC_TO_MICROSEC 1000000 26#define SEC_TO_MILLISEC 1000 27#define MILLISEC_TO_NANOSEC 1000000 28#define MILLISEC_TO_USEC 1000 29#define MICROSEC_TO_NANOSEC 1000 30#define GET_TIME_RETRY_TIMES 5 31 32uint64_t GetMillisecondSinceBoot(void) 33{ 34 struct timespec ts; 35 uint64_t result = 0; 36 uint32_t retryTimes = 0; 37 while (retryTimes < GET_TIME_RETRY_TIMES) { 38 clock_gettime(CLOCK_BOOTTIME, &ts); 39 result = (uint64_t)(ts.tv_sec * SEC_TO_MILLISEC + ts.tv_nsec / MILLISEC_TO_NANOSEC); 40 if (result != 0) { 41 break; 42 } 43 retryTimes++; 44 } 45 return result; 46} 47 48uint64_t GetMillisecondSince1970(void) 49{ 50 struct timespec ts; 51 clock_gettime(CLOCK_REALTIME, &ts); 52 return ts.tv_sec * SEC_TO_MILLISEC + ts.tv_nsec / MILLISEC_TO_NANOSEC; 53} 54 55bool GetDateTimeByMillisecondSince1970(uint64_t input, DateTime *datetime) 56{ 57 if (datetime == NULL) { 58 return false; 59 } 60 struct tm tm; 61 time_t time = (time_t)(input / SEC_TO_MILLISEC); 62 localtime_r(&time, &tm); 63 64 datetime->year = (uint16_t)(tm.tm_year + 1900); // need add 1900 65 datetime->mon = (uint16_t)(tm.tm_mon + 1); 66 datetime->day = (uint16_t)tm.tm_mday; 67 datetime->hour = (uint16_t)tm.tm_hour; 68 datetime->min = (uint16_t)tm.tm_min; 69 datetime->sec = (uint16_t)tm.tm_sec; 70 datetime->msec = (uint16_t)(input % SEC_TO_MILLISEC); 71 return true; 72} 73 74bool GetDateTimeByMillisecondSinceBoot(uint64_t input, DateTime *datetime) 75{ 76 if (datetime == NULL) { 77 return false; 78 } 79 static uint64_t compensate = 0; 80 if (compensate == 0) { 81 compensate = GetMillisecondSince1970() - GetMillisecondSinceBoot(); 82 } 83 84 return GetDateTimeByMillisecondSince1970(input + compensate, datetime); 85} 86#ifdef __cplusplus 87} 88#endif