123b3eb3cSopenharmony_ci/* 223b3eb3cSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 323b3eb3cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 423b3eb3cSopenharmony_ci * you may not use this file except in compliance with the License. 523b3eb3cSopenharmony_ci * You may obtain a copy of the License at 623b3eb3cSopenharmony_ci * 723b3eb3cSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 823b3eb3cSopenharmony_ci * 923b3eb3cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1023b3eb3cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1123b3eb3cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1223b3eb3cSopenharmony_ci * See the License for the specific language governing permissions and 1323b3eb3cSopenharmony_ci * limitations under the License. 1423b3eb3cSopenharmony_ci */ 1523b3eb3cSopenharmony_ci 1623b3eb3cSopenharmony_ci#include "base/utils/time_util.h" 1723b3eb3cSopenharmony_ci 1823b3eb3cSopenharmony_ci#include <iomanip> 1923b3eb3cSopenharmony_ci#include <sstream> 2023b3eb3cSopenharmony_ci#include <sys/time.h> 2123b3eb3cSopenharmony_ci#include "base/utils/utils.h" 2223b3eb3cSopenharmony_ci 2323b3eb3cSopenharmony_cinamespace OHOS::Ace { 2423b3eb3cSopenharmony_cinamespace { 2523b3eb3cSopenharmony_ci 2623b3eb3cSopenharmony_ciconstexpr int64_t SEC_TO_MICROSEC = 1000000; 2723b3eb3cSopenharmony_ciconstexpr int64_t SEC_TO_NANOSEC = 1000000000; 2823b3eb3cSopenharmony_ciconstexpr int64_t MICROSEC_TO_NANOSEC = 1000; 2923b3eb3cSopenharmony_ciconstexpr int64_t SEC_TO_MILLISEC = 1000; 3023b3eb3cSopenharmony_ciconstexpr int64_t MILLISEC_TO_MICROSEC = 1000; 3123b3eb3cSopenharmony_ciconstexpr int32_t HOURS_WEST_GEOGRAPHICAL_LOWER_LIMIT = -12; 3223b3eb3cSopenharmony_ciconstexpr int32_t HOURS_WEST_LOWER_LIMIT = -14; 3323b3eb3cSopenharmony_ciconstexpr int32_t HOURS_WEST_UPPER_LIMIT = 12; 3423b3eb3cSopenharmony_ciconstexpr int32_t TOTAL_SECONDS_OF_DAY = 24 * 60 * 60; 3523b3eb3cSopenharmony_ciconstexpr int32_t TOTAL_SECONDS_OF_HOUR = 60 * 60; 3623b3eb3cSopenharmony_ciconstexpr int32_t TOTAL_SECONDS_OF_MINUTE = 60; 3723b3eb3cSopenharmony_ciconstexpr int32_t TOTAL_MINUTE_OF_HOUR = 60; 3823b3eb3cSopenharmony_ciconstexpr int32_t TWENTY_FOUR_HOUR_BASE = 24; 3923b3eb3cSopenharmony_ciconstexpr int32_t TWELVE_HOUR_BASE = 12; 4023b3eb3cSopenharmony_ciconstexpr int32_t DAY_TIME_LOWER_LIMIT = 6; 4123b3eb3cSopenharmony_ciconstexpr int32_t DAY_TIME_UPPER_LIMIT = 18; 4223b3eb3cSopenharmony_ciconstexpr int32_t MAX_TIME_STR_LEN = 64; 4323b3eb3cSopenharmony_ci} // namespace 4423b3eb3cSopenharmony_ci 4523b3eb3cSopenharmony_ciint64_t GetMicroTickCount() 4623b3eb3cSopenharmony_ci{ 4723b3eb3cSopenharmony_ci struct timespec ts; 4823b3eb3cSopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &ts); 4923b3eb3cSopenharmony_ci return (ts.tv_sec * SEC_TO_MICROSEC + ts.tv_nsec / MICROSEC_TO_NANOSEC); 5023b3eb3cSopenharmony_ci} 5123b3eb3cSopenharmony_ci 5223b3eb3cSopenharmony_ciint64_t GetSysTimestamp() 5323b3eb3cSopenharmony_ci{ 5423b3eb3cSopenharmony_ci struct timespec ts; 5523b3eb3cSopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &ts); 5623b3eb3cSopenharmony_ci return ts.tv_sec * SEC_TO_NANOSEC + ts.tv_nsec; 5723b3eb3cSopenharmony_ci} 5823b3eb3cSopenharmony_ci 5923b3eb3cSopenharmony_ciint64_t GetCurrentTimestamp() 6023b3eb3cSopenharmony_ci{ 6123b3eb3cSopenharmony_ci struct timeval currentTime; 6223b3eb3cSopenharmony_ci gettimeofday(¤tTime, nullptr); 6323b3eb3cSopenharmony_ci return static_cast<int64_t>(currentTime.tv_sec) * SEC_TO_MILLISEC + currentTime.tv_usec / MILLISEC_TO_MICROSEC; 6423b3eb3cSopenharmony_ci} 6523b3eb3cSopenharmony_ci 6623b3eb3cSopenharmony_ciint64_t GetCurrentTimestampMicroSecond() 6723b3eb3cSopenharmony_ci{ 6823b3eb3cSopenharmony_ci struct timeval currentTime; 6923b3eb3cSopenharmony_ci gettimeofday(¤tTime, nullptr); 7023b3eb3cSopenharmony_ci return static_cast<int64_t>(currentTime.tv_sec) * SEC_TO_MILLISEC * MILLISEC_TO_MICROSEC + currentTime.tv_usec; 7123b3eb3cSopenharmony_ci} 7223b3eb3cSopenharmony_ci 7323b3eb3cSopenharmony_cistd::string ConvertTimestampToStr(int64_t timestamp) 7423b3eb3cSopenharmony_ci{ 7523b3eb3cSopenharmony_ci char timeStr[MAX_TIME_STR_LEN]; 7623b3eb3cSopenharmony_ci // timestamp is in millisecond unit, divide 1000 to second 7723b3eb3cSopenharmony_ci auto t = static_cast<std::time_t>(timestamp / SEC_TO_MILLISEC); 7823b3eb3cSopenharmony_ci auto local = std::localtime(&t); 7923b3eb3cSopenharmony_ci if (!local) { 8023b3eb3cSopenharmony_ci return ""; 8123b3eb3cSopenharmony_ci } 8223b3eb3cSopenharmony_ci std::strftime(timeStr, MAX_TIME_STR_LEN, "%Y-%m-%d %H:%M:%S", local); 8323b3eb3cSopenharmony_ci std::stringstream oss; 8423b3eb3cSopenharmony_ci // milliseconds in timestr should be 3 characters length 8523b3eb3cSopenharmony_ci oss << timeStr << "." << std::setw(3) << std::setfill('0') << (timestamp % SEC_TO_MILLISEC); 8623b3eb3cSopenharmony_ci return oss.str(); 8723b3eb3cSopenharmony_ci} 8823b3eb3cSopenharmony_ci 8923b3eb3cSopenharmony_ciTimeOfNow GetTimeOfNow(int32_t hoursWest) 9023b3eb3cSopenharmony_ci{ 9123b3eb3cSopenharmony_ci struct timeval currentTime; 9223b3eb3cSopenharmony_ci struct timezone timeZone; 9323b3eb3cSopenharmony_ci gettimeofday(¤tTime, &timeZone); 9423b3eb3cSopenharmony_ci 9523b3eb3cSopenharmony_ci TimeOfNow timeOfNow(hoursWest); 9623b3eb3cSopenharmony_ci int32_t minutesWest = timeZone.tz_minuteswest; 9723b3eb3cSopenharmony_ci if (IsHoursWestValid(timeOfNow.hoursWest_)) { 9823b3eb3cSopenharmony_ci minutesWest = Round(TOTAL_MINUTE_OF_HOUR * timeOfNow.hoursWest_); 9923b3eb3cSopenharmony_ci } else { 10023b3eb3cSopenharmony_ci // when [hoursWest] is invalid, set current time zone to [hoursWest]. 10123b3eb3cSopenharmony_ci // default value of hoursWest_ is INT_MAX 10223b3eb3cSopenharmony_ci if (!NearEqual(timeOfNow.hoursWest_, INT_MAX)) { 10323b3eb3cSopenharmony_ci LOGW("hoursWest [%{public}d] is invalid, use current time zone.", timeOfNow.hoursWest_); 10423b3eb3cSopenharmony_ci } 10523b3eb3cSopenharmony_ci timeOfNow.hoursWest_ = timeZone.tz_minuteswest / TOTAL_MINUTE_OF_HOUR; 10623b3eb3cSopenharmony_ci } 10723b3eb3cSopenharmony_ci int secondsOfToday = currentTime.tv_sec % TOTAL_SECONDS_OF_DAY - minutesWest * TOTAL_SECONDS_OF_MINUTE; 10823b3eb3cSopenharmony_ci if (secondsOfToday < 0) { 10923b3eb3cSopenharmony_ci secondsOfToday += TOTAL_SECONDS_OF_DAY; 11023b3eb3cSopenharmony_ci } 11123b3eb3cSopenharmony_ci timeOfNow.minute_ = (secondsOfToday / TOTAL_SECONDS_OF_MINUTE) % TOTAL_MINUTE_OF_HOUR + 11223b3eb3cSopenharmony_ci secondsOfToday % TOTAL_SECONDS_OF_MINUTE / TOTAL_SECONDS_OF_MINUTE; 11323b3eb3cSopenharmony_ci timeOfNow.hour24_ = 11423b3eb3cSopenharmony_ci (secondsOfToday / TOTAL_SECONDS_OF_HOUR) % TWENTY_FOUR_HOUR_BASE + timeOfNow.minute_ / TOTAL_MINUTE_OF_HOUR; 11523b3eb3cSopenharmony_ci timeOfNow.hour12_ = 11623b3eb3cSopenharmony_ci (timeOfNow.hour24_ < TWELVE_HOUR_BASE) ? timeOfNow.hour24_ : (timeOfNow.hour24_ - TWELVE_HOUR_BASE); 11723b3eb3cSopenharmony_ci timeOfNow.second_ = secondsOfToday % TOTAL_SECONDS_OF_MINUTE; 11823b3eb3cSopenharmony_ci timeOfNow.timeUsec_ = currentTime.tv_usec; 11923b3eb3cSopenharmony_ci return timeOfNow; 12023b3eb3cSopenharmony_ci} 12123b3eb3cSopenharmony_ci 12223b3eb3cSopenharmony_cibool IsHoursWestValid(int32_t& hoursWest) 12323b3eb3cSopenharmony_ci{ 12423b3eb3cSopenharmony_ci // valid hoursWest is within [-14, 12] 12523b3eb3cSopenharmony_ci bool isValid = GreatOrEqual(hoursWest, HOURS_WEST_LOWER_LIMIT) && LessOrEqual(hoursWest, HOURS_WEST_UPPER_LIMIT); 12623b3eb3cSopenharmony_ci if (!isValid) { 12723b3eb3cSopenharmony_ci return false; 12823b3eb3cSopenharmony_ci } 12923b3eb3cSopenharmony_ci // Theoretically, the time zone range should be [-12, +12], but some countries and regions that cross the 13023b3eb3cSopenharmony_ci // International Date Line use -13(UTC+13) and -14(UTC+14) to keep the whole country or region at the same date. 13123b3eb3cSopenharmony_ci bool isSpecialTimeZone = LessNotEqual(hoursWest, HOURS_WEST_GEOGRAPHICAL_LOWER_LIMIT); 13223b3eb3cSopenharmony_ci if (isSpecialTimeZone) { 13323b3eb3cSopenharmony_ci hoursWest += TWENTY_FOUR_HOUR_BASE; 13423b3eb3cSopenharmony_ci } 13523b3eb3cSopenharmony_ci return true; 13623b3eb3cSopenharmony_ci} 13723b3eb3cSopenharmony_ci 13823b3eb3cSopenharmony_cibool IsDayTime(const TimeOfNow& timeOfNow) 13923b3eb3cSopenharmony_ci{ 14023b3eb3cSopenharmony_ci return GreatOrEqual(timeOfNow.hour24_, DAY_TIME_LOWER_LIMIT) && 14123b3eb3cSopenharmony_ci LessNotEqual(timeOfNow.hour24_, DAY_TIME_UPPER_LIMIT); 14223b3eb3cSopenharmony_ci} 14323b3eb3cSopenharmony_ci 14423b3eb3cSopenharmony_ciTimeOfZone GetTimeOfZone(int32_t hoursWest) 14523b3eb3cSopenharmony_ci{ 14623b3eb3cSopenharmony_ci struct timeval currentTime; 14723b3eb3cSopenharmony_ci struct timezone timeZone; 14823b3eb3cSopenharmony_ci gettimeofday(¤tTime, &timeZone); 14923b3eb3cSopenharmony_ci 15023b3eb3cSopenharmony_ci TimeOfZone timeOfZone(hoursWest); 15123b3eb3cSopenharmony_ci int32_t minutesWest = timeZone.tz_minuteswest; 15223b3eb3cSopenharmony_ci if (HoursWestIsValid(timeOfZone.hoursWest_)) { 15323b3eb3cSopenharmony_ci minutesWest = Round(TOTAL_MINUTE_OF_HOUR * timeOfZone.hoursWest_); 15423b3eb3cSopenharmony_ci } else { 15523b3eb3cSopenharmony_ci // when [hoursWest] is invalid, set current time zone to [hoursWest]. 15623b3eb3cSopenharmony_ci // default value of hoursWest_ is DEFAULT_HOURS_WEST 15723b3eb3cSopenharmony_ci if (!NearEqual(timeOfZone.hoursWest_, DEFAULT_HOURS_WEST)) { 15823b3eb3cSopenharmony_ci LOGW("hoursWest [%{public}d] is invalid, use current time zone.", timeOfZone.hoursWest_); 15923b3eb3cSopenharmony_ci } 16023b3eb3cSopenharmony_ci timeOfZone.hoursWest_ = minutesWest / TOTAL_MINUTE_OF_HOUR; 16123b3eb3cSopenharmony_ci } 16223b3eb3cSopenharmony_ci int secondsOfToday = currentTime.tv_sec % TOTAL_SECONDS_OF_DAY - minutesWest * TOTAL_SECONDS_OF_MINUTE; 16323b3eb3cSopenharmony_ci if (secondsOfToday < 0) { 16423b3eb3cSopenharmony_ci secondsOfToday += TOTAL_SECONDS_OF_DAY; 16523b3eb3cSopenharmony_ci } 16623b3eb3cSopenharmony_ci timeOfZone.minute_ = (secondsOfToday / TOTAL_SECONDS_OF_MINUTE) % TOTAL_MINUTE_OF_HOUR + 16723b3eb3cSopenharmony_ci secondsOfToday % TOTAL_SECONDS_OF_MINUTE / TOTAL_SECONDS_OF_MINUTE; 16823b3eb3cSopenharmony_ci timeOfZone.hour24_ = 16923b3eb3cSopenharmony_ci (secondsOfToday / TOTAL_SECONDS_OF_HOUR) % TWENTY_FOUR_HOUR_BASE + timeOfZone.minute_ / TOTAL_MINUTE_OF_HOUR; 17023b3eb3cSopenharmony_ci timeOfZone.hour12_ = 17123b3eb3cSopenharmony_ci (timeOfZone.hour24_ < TWELVE_HOUR_BASE) ? timeOfZone.hour24_ : (timeOfZone.hour24_ - TWELVE_HOUR_BASE); 17223b3eb3cSopenharmony_ci timeOfZone.second_ = secondsOfToday % TOTAL_SECONDS_OF_MINUTE; 17323b3eb3cSopenharmony_ci timeOfZone.timeUsec_ = currentTime.tv_usec; 17423b3eb3cSopenharmony_ci return timeOfZone; 17523b3eb3cSopenharmony_ci} 17623b3eb3cSopenharmony_ci 17723b3eb3cSopenharmony_cibool HoursWestIsValid(int32_t& hoursWest) 17823b3eb3cSopenharmony_ci{ 17923b3eb3cSopenharmony_ci // valid hoursWest is within [-14, 12] 18023b3eb3cSopenharmony_ci bool isValid = GreatOrEqual(hoursWest, HOURS_WEST_LOWER_LIMIT) && LessOrEqual(hoursWest, HOURS_WEST_UPPER_LIMIT); 18123b3eb3cSopenharmony_ci if (!isValid) { 18223b3eb3cSopenharmony_ci return false; 18323b3eb3cSopenharmony_ci } 18423b3eb3cSopenharmony_ci // Theoretically, the time zone range should be [-12, +12], but some countries and regions that cross the 18523b3eb3cSopenharmony_ci // International Date Line use -13(UTC+13) and -14(UTC+14) to keep the whole country or region at the same date. 18623b3eb3cSopenharmony_ci bool isSpecialTimeZone = LessNotEqual(hoursWest, HOURS_WEST_GEOGRAPHICAL_LOWER_LIMIT); 18723b3eb3cSopenharmony_ci if (isSpecialTimeZone) { 18823b3eb3cSopenharmony_ci hoursWest += TWENTY_FOUR_HOUR_BASE; 18923b3eb3cSopenharmony_ci } 19023b3eb3cSopenharmony_ci return true; 19123b3eb3cSopenharmony_ci} 19223b3eb3cSopenharmony_ci 19323b3eb3cSopenharmony_cibool IsDayTime(const TimeOfZone& timeOfZone) 19423b3eb3cSopenharmony_ci{ 19523b3eb3cSopenharmony_ci return GreatOrEqual(timeOfZone.hour24_, DAY_TIME_LOWER_LIMIT) && 19623b3eb3cSopenharmony_ci LessNotEqual(timeOfZone.hour24_, DAY_TIME_UPPER_LIMIT); 19723b3eb3cSopenharmony_ci} 19823b3eb3cSopenharmony_ci 19923b3eb3cSopenharmony_ci} // namespace OHOS::Ace 200