1 /*
2 * Copyright (C) 2023 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, length).compare("Z") != 0) {
56 int mins = std::stoi(iso8601Str.substr(length - 2, 2));
57 int hours = std::stoi(iso8601Str.substr(length - 4, 2));
58 char symbol = iso8601Str.at(length - 5);
59 long seconds = (hours * 60 + mins) * 60;
60 diffTime = symbol == '+' ? seconds : -seconds;
61 }
62
63 // convert time to localtime
64 long timezone = 0;
65 std::tm *timeWithOffsetPtr = localtime(&tt);
66 if (timeWithOffsetPtr == nullptr) {
67 return "";
68 }
69 std::tm timeWithOffset = *timeWithOffsetPtr;
70 if (timeWithOffset.tm_gmtoff != 0) {
71 timezone = timeWithOffset.tm_gmtoff;
72 }
73 auto localTime =
74 std::chrono::system_clock::from_time_t(std::mktime(&tm)) + std::chrono::seconds(timezone - diffTime);
75 std::time_t localTimeT = std::chrono::system_clock::to_time_t(localTime);
76 std::tm *localTmPtr = std::localtime(&localTimeT);
77 if (localTmPtr == nullptr) {
78 return "";
79 }
80 std::tm localTm = *localTmPtr;
81 std::ostringstream oss;
82 oss << std::put_time(&localTm, "%Y-%m-%d %H:%M:%S");
83 return oss.str();
84 }
85
FormatDataTimeByString(const std::string &dataTime)86 std::string TimeFormatUtils::FormatDataTimeByString(const std::string &dataTime)
87 {
88 if (dataTime.compare("") == 0) {
89 return dataTime;
90 }
91 std::string::size_type position = dataTime.find(" ");
92 std::string data = "";
93 std::string time = "";
94 if (position == dataTime.npos) {
95 data = dataTime;
96 if (data.find("-") == data.npos) {
97 data += "-01-01";
98 } else if (data.find_first_of("-") == data.find_last_of("-")) {
99 data += "-01";
100 }
101 time += " 00:00:00";
102 } else {
103 data = dataTime.substr(0, position);
104 time = dataTime.substr(position);
105 if (data.find("-") == data.npos) {
106 data += "-01-01";
107 } else if (data.find_first_of("-") == data.find_last_of("-")) {
108 data += "-01";
109 }
110 if (time.find(":") == data.npos) {
111 time += ":00:00";
112 } else if (time.find_first_of(":") == time.find_last_of(":")) {
113 time += ":00";
114 } else {
115 time = time.substr(0, time.find("."));
116 }
117 }
118 MEDIA_LOGD("FormatDataTimeByString is: %{public}s%{public}s", data.c_str(), time.c_str());
119 return data + time;
120 }
121
ConvertTimestampToDatetime(const std::string ×tamp)122 std::string TimeFormatUtils::ConvertTimestampToDatetime(const std::string ×tamp)
123 {
124 if (timestamp.empty()) {
125 MEDIA_LOGE("datetime is empty, format failed");
126 return "";
127 }
128
129 time_t ts = stoi(timestamp);
130 tm *pTime;
131 char date[maxDateTimeSize];
132 char time[maxDateTimeSize];
133 pTime = localtime(&ts);
134 if (pTime == nullptr) {
135 return "";
136 }
137 size_t sizeDateStr = strftime(date, maxDateTimeSize, "%Y-%m-%d", pTime);
138 size_t sizeTimeStr = strftime(time, maxDateTimeSize, "%H:%M:%S", pTime);
139 if (sizeDateStr != standardDateStrSize || sizeTimeStr != standardTimeStrSize) {
140 MEDIA_LOGE("datetime is invalid, format failed");
141 return "";
142 }
143
144 return std::string(date) + " " + std::string(time);
145 }
146 } // namespace Media
147 } // namespace OHOS