Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020-2021 Project CHIP Authors
4 : * Copyright (c) 2013-2017 Nest Labs, Inc.
5 : * All rights reserved.
6 : *
7 : * Licensed under the Apache License, Version 2.0 (the "License");
8 : * you may not use this file except in compliance with the License.
9 : * You may obtain a copy of the License at
10 : *
11 : * http://www.apache.org/licenses/LICENSE-2.0
12 : *
13 : * Unless required by applicable law or agreed to in writing, software
14 : * distributed under the License is distributed on an "AS IS" BASIS,
15 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 : * See the License for the specific language governing permissions and
17 : * limitations under the License.
18 : */
19 :
20 : /**
21 : * @file
22 : * Various utility functions for dealing with time and dates.
23 : *
24 : */
25 :
26 : #pragma once
27 :
28 : #include <stdint.h>
29 :
30 : namespace chip {
31 :
32 : enum
33 : {
34 : kYearsPerCentury = 100,
35 : kLeapYearInterval = 4,
36 :
37 : kMonthsPerYear = 12,
38 :
39 : kMaxDaysPerMonth = 31,
40 :
41 : kDaysPerWeek = 7,
42 : kDaysPerStandardYear = 365,
43 : kDaysPerLeapYear = kDaysPerStandardYear + 1,
44 :
45 : kHoursPerDay = 24,
46 : kHoursPerWeek = kDaysPerWeek * kHoursPerDay,
47 :
48 : kMinutesPerHour = 60,
49 : kMinutesPerDay = kHoursPerDay * kMinutesPerHour,
50 :
51 : kSecondsPerMinute = 60,
52 : kSecondsPerHour = kSecondsPerMinute * kMinutesPerHour,
53 : kSecondsPerDay = kSecondsPerHour * kHoursPerDay,
54 : kSecondsPerWeek = kSecondsPerDay * kDaysPerWeek,
55 : kSecondsPerStandardYear = kSecondsPerDay * kDaysPerStandardYear,
56 :
57 : kMillisecondsPerSecond = 1000,
58 :
59 : kMicrosecondsPerSecond = 1000000,
60 : kMicrosecondsPerMillisecond = 1000,
61 :
62 : kNanosecondsPerSecond = 1000000000,
63 : kNanosecondsPerMillisecond = 1000000,
64 : kNanosecondsPerMicrosecond = 1000,
65 : };
66 :
67 : enum
68 : {
69 : kJanuary = 1,
70 : kFebruary = 2,
71 : kMarch = 3,
72 : kApril = 4,
73 : kMay = 5,
74 : kJune = 6,
75 : kJuly = 7,
76 : kAugust = 8,
77 : kSeptember = 9,
78 : kOctober = 10,
79 : kNovember = 11,
80 : kDecember = 12
81 : };
82 :
83 : /* Unix epoch time.
84 : */
85 : enum
86 : {
87 : // First year of the standard unix epoch.
88 : kUnixEpochYear = 1970,
89 :
90 : // Last fully-representable year that can be stored in an unsigned 32-bit seconds-since-epoch value.
91 : kMaxYearInSecondsSinceUnixEpoch32 = 2105,
92 :
93 : // Last fully-representable year that can be stored in an unsigned 32-bit days-since-epoch value.
94 : kMaxYearInDaysSinceUnixEpoch32 = 28276
95 : };
96 :
97 : /* CHIP Epoch time.
98 : */
99 : enum
100 : {
101 : // Base year of the CHIP epoch time.
102 : kChipEpochBaseYear = 2000,
103 :
104 : // Last fully-representable year that can be stored in an unsigned 32-bit CHIP Epoch seconds value.
105 : kChipEpochMaxYear = 2135,
106 :
107 : // Offset, in days, from the Unix Epoch to the CHIP Epoch.
108 : kChipEpochDaysSinceUnixEpoch = 10957,
109 :
110 : // Offset, in non-leap seconds, from the Unix Epoch to the CHIP Epoch.
111 : kChipEpochSecondsSinceUnixEpoch = kChipEpochDaysSinceUnixEpoch * kSecondsPerDay,
112 : };
113 :
114 : // Difference in microseconds between Unix epoch (Jan 1 1970 00:00:00) and CHIP Epoch (Jan 1 2000 00:00:00).
115 : constexpr uint64_t kChipEpochUsSinceUnixEpoch =
116 : static_cast<uint64_t>(kChipEpochSecondsSinceUnixEpoch) * chip::kMicrosecondsPerSecond;
117 :
118 : bool IsLeapYear(uint16_t year);
119 : uint8_t DaysInMonth(uint16_t year, uint8_t month);
120 : uint8_t FirstWeekdayOfYear(uint16_t year);
121 : void OrdinalDateToCalendarDate(uint16_t year, uint16_t dayOfYear, uint8_t & month, uint8_t & dayOfMonth);
122 : void CalendarDateToOrdinalDate(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint16_t & dayOfYear);
123 : bool CalendarDateToDaysSinceUnixEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint32_t & daysSinceEpoch);
124 : bool DaysSinceUnixEpochToCalendarDate(uint32_t daysSinceEpoch, uint16_t & year, uint8_t & month, uint8_t & dayOfMonth);
125 : bool AdjustCalendarDate(uint16_t & year, uint8_t & month, uint8_t & dayOfMonth, int32_t relativeDays);
126 : bool CalendarTimeToSecondsSinceUnixEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint8_t hour, uint8_t minute,
127 : uint8_t second, uint32_t & secondsSinceEpoch);
128 : void SecondsSinceUnixEpochToCalendarTime(uint32_t secondsSinceEpoch, uint16_t & year, uint8_t & month, uint8_t & dayOfMonth,
129 : uint8_t & hour, uint8_t & minute, uint8_t & second);
130 :
131 : /**
132 : * @brief Convert a calendar date and time to the number of seconds since CHIP Epoch (2000-01-01 00:00:00 UTC).
133 : *
134 : * @note This function makes no attempt to verify the correct range of any arguments other than year.
135 : * Therefore callers must make sure the supplied values are valid prior to invocation.
136 : *
137 : * @param year Gregorian calendar year in the range 2000 to 2135.
138 : * @param month Month in standard form (1=January ... 12=December).
139 : * @param dayOfMonth Day-of-month in standard form (1=1st, 2=2nd, etc.).
140 : * @param hour Hour (0-23).
141 : * @param minute Minute (0-59).
142 : * @param second Second (0-59).
143 : * @param chipEpochTime Number of seconds since 2000-01-01 00:00:00 UTC.
144 : *
145 : * @return True if the date/time was converted successfully. False if the given year falls outside the
146 : * representable range.
147 : */
148 : bool CalendarToChipEpochTime(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint8_t hour, uint8_t minute, uint8_t second,
149 : uint32_t & chipEpochTime);
150 :
151 : /**
152 : * @brief Convert the number of seconds since CHIP Epoch (2000-01-01 00:00:00 UTC) to a calendar date and time.
153 : *
154 : * @details Input time values are limited to positive values up to 2^32-1. This limits the
155 : * representable date range to the year 2135.
156 : *
157 : * @param chipEpochTime Number of seconds since 2000-01-01 00:00:00 UTC.
158 : * @param year Gregorian calendar year.
159 : * @param month Month in standard form (1=January ... 12=December).
160 : * @param dayOfMonth Day-of-month in standard form (1=1st, 2=2nd, etc.).
161 : * @param hour Hour (0-23).
162 : * @param minute Minute (0-59).
163 : * @param second Second (0-59).
164 : */
165 : void ChipEpochToCalendarTime(uint32_t chipEpochTime, uint16_t & year, uint8_t & month, uint8_t & dayOfMonth, uint8_t & hour,
166 : uint8_t & minute, uint8_t & second);
167 :
168 : /**
169 : * @brief Convert the number of seconds since Unix Epoch (1970-01-01 00:00:00 GMT TAI) to
170 : * CHIP Epoch (2000-01-01 00:00:00 UTC).
171 : *
172 : * @details Input time values are limited to positive values up to 2^32-1. This limits the
173 : * representable date range to the year 2135.
174 : *
175 : * @param[in] unixEpochTimeSeconds Number of seconds since 1970-01-01 00:00:00 GMT TAI.
176 : * @param[out] outChipEpochTimeSeconds Number of seconds since 2000-01-01 00:00:00 UTC.
177 : *
178 : * @return True if the time was converted successfully. False if the given Unix epoch time
179 : * falls outside the representable range.
180 : */
181 : bool UnixEpochToChipEpochTime(uint32_t unixEpochTimeSeconds, uint32_t & outChipEpochTimeSeconds);
182 :
183 : /**
184 : * @brief Convert the number of microseconds since CHIP Epoch (2000-01-01 00:00:00 UTC) to
185 : * Unix Epoch (1970-01-01 00:00:00 GMT TAI).
186 : *
187 : * @param[in] chipEpochTimeMicros Number of microseconds since 2000-01-01 00:00:00 UTC.
188 : * @param[out] outUnixEpochTimeMicros Number of microseconds since 1970-01-01 00:00:00 GMT TAI.
189 : *
190 : * @return True if the time was converted successfully. False if the given CHIP epoch time
191 : * falls outside the representable range.
192 : */
193 : bool ChipEpochToUnixEpochMicros(uint64_t chipEpochTimeMicros, uint64_t & outUnixEpochTimeMicros);
194 :
195 : /**
196 : * @brief Convert the number of microseconds since Unix Epoch (1970-01-01 00:00:00 GMT TAI) to
197 : * CHIP Epoch (2000-01-01 00:00:00 UTC).
198 : *
199 : * @param[in] unixEpochTimeMicros Number of microseconds since 1970-01-01 00:00:00 GMT TAI.
200 : * @param[out] outChipEpochTimeMicros Number of microseconds since 2000-01-01 00:00:00 UTC.
201 : *
202 : * @return True if the time was converted successfully. False if the given Unix epoch time
203 : * falls outside the representable range.
204 : */
205 : bool UnixEpochToChipEpochMicros(uint64_t unixEpochTimeMicros, uint64_t & outChipEpochTimeMicros);
206 :
207 : /**
208 : * @def SecondsToMilliseconds
209 : *
210 : * @brief
211 : * Convert integer seconds to milliseconds.
212 : *
213 : */
214 2 : inline uint64_t SecondsToMilliseconds(uint32_t seconds)
215 : {
216 2 : return (seconds * kMillisecondsPerSecond);
217 : }
218 :
219 : // For backwards-compatibility of public API.
220 : [[deprecated("Use SecondsToMilliseconds")]] inline uint64_t secondsToMilliseconds(uint32_t seconds)
221 : {
222 : return SecondsToMilliseconds(seconds);
223 : }
224 :
225 : } // namespace chip
|