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