1 /* 2 * Copyright (C) 2023-2025 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 "time_format_utils.h" 17 18 #include <chrono> 19 #include <ctime> 20 #include <iomanip> 21 #include <iostream> 22 #include <regex> 23 #include <sstream> 24 #include <string> 25 26 #include "media_log.h" 27 28 namespace { 29 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_PLAYER, "TimeFormatUtils"}; 30 } 31 32 namespace OHOS { 33 namespace Media { FormatDateTimeByTimeZone(const std::string & iso8601Str)34 std::string TimeFormatUtils::FormatDateTimeByTimeZone(const std::string &iso8601Str) 35 { 36 std::regex pattern(R"((\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(.\d{1,6})?(((\+|-)\d{4})|Z)?)"); 37 std::smatch match; 38 if (!std::regex_match(iso8601Str, match, pattern)) { 39 return iso8601Str; // not standard ISO8601 type string 40 } 41 42 std::istringstream iss(iso8601Str); 43 std::tm tm; 44 if (!(iss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S"))) { 45 return iso8601Str; // cant prase time 46 } 47 48 // time zone 49 time_t tt = mktime(&tm); 50 if (tt == -1) { 51 return iso8601Str; 52 } 53 uint32_t length = iso8601Str.length(); 54 long diffTime = 0; 55 if (iso8601Str.substr(length - 1, 1).compare("Z") != 0) { 56 char symbol = iso8601Str.at(length - 5); 57 if (symbol != '+' && symbol != '-') { 58 std::ostringstream oss; 59 oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S"); 60 return oss.str(); 61 } 62 int mins = std::stoi(iso8601Str.substr(length - 2, 2)); 63 int hours = std::stoi(iso8601Str.substr(length - 4, 2)); 64 long seconds = (hours * 60 + mins) * 60; 65 diffTime = symbol == '+' ? seconds : -seconds; 66 } 67 68 // convert time to localtime 69 long timezone = 0; 70 std::tm *timeWithOffsetPtr = localtime(&tt); 71 if (timeWithOffsetPtr == nullptr) { 72 return ""; 73 } 74 std::tm timeWithOffset = *timeWithOffsetPtr; 75 if (timeWithOffset.tm_gmtoff != 0) { 76 timezone = timeWithOffset.tm_gmtoff; 77 } 78 auto localTime = 79 std::chrono::system_clock::from_time_t(std::mktime(&tm)) + std::chrono::seconds(timezone - diffTime); 80 std::time_t localTimeT = std::chrono::system_clock::to_time_t(localTime); 81 std::tm *localTmPtr = std::localtime(&localTimeT); 82 if (localTmPtr == nullptr) { 83 return ""; 84 } 85 std::tm localTm = *localTmPtr; 86 std::ostringstream oss; 87 oss << std::put_time(&localTm, "%Y-%m-%d %H:%M:%S"); 88 return oss.str(); 89 } 90 FormatDataTimeByString(const std::string & dataTime)91 std::string TimeFormatUtils::FormatDataTimeByString(const std::string &dataTime) 92 { 93 if (dataTime.compare("") == 0) { 94 return dataTime; 95 } 96 std::string::size_type position = dataTime.find(" "); 97 std::string data = ""; 98 std::string time = ""; 99 if (position == dataTime.npos) { 100 data = dataTime; 101 if (data.find("-") == data.npos) { 102 data += "-01-01"; 103 } else if (data.find_first_of("-") == data.find_last_of("-")) { 104 data += "-01"; 105 } 106 time += " 00:00:00"; 107 } else { 108 data = dataTime.substr(0, position); 109 time = dataTime.substr(position); 110 if (data.find("-") == data.npos) { 111 data += "-01-01"; 112 } else if (data.find_first_of("-") == data.find_last_of("-")) { 113 data += "-01"; 114 } 115 if (time.find(":") == data.npos) { 116 time += ":00:00"; 117 } else if (time.find_first_of(":") == time.find_last_of(":")) { 118 time += ":00"; 119 } else { 120 time = time.substr(0, time.find(".")); 121 } 122 } 123 MEDIA_LOGD("FormatDataTimeByString is: %{public}s%{public}s", data.c_str(), time.c_str()); 124 return data + time; 125 } 126 ConvertTimestampToDatetime(const std::string & timestamp)127 std::string TimeFormatUtils::ConvertTimestampToDatetime(const std::string ×tamp) 128 { 129 if (timestamp.empty()) { 130 MEDIA_LOGE("datetime is empty, format failed"); 131 return ""; 132 } 133 134 time_t ts = stoi(timestamp); 135 tm *pTime; 136 char date[maxDateTimeSize]; 137 char time[maxDateTimeSize]; 138 pTime = localtime(&ts); 139 if (pTime == nullptr) { 140 return ""; 141 } 142 size_t sizeDateStr = strftime(date, maxDateTimeSize, "%Y-%m-%d", pTime); 143 size_t sizeTimeStr = strftime(time, maxDateTimeSize, "%H:%M:%S", pTime); 144 if (sizeDateStr != standardDateStrSize || sizeTimeStr != standardTimeStrSize) { 145 MEDIA_LOGE("datetime is invalid, format failed"); 146 return ""; 147 } 148 149 return std::string(date) + " " + std::string(time); 150 } 151 } // namespace Media 152 } // namespace OHOS