1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "rtc_base.h"
10 #include "platform_log.h"
11
12 #define HDF_LOG_TAG rtc_base
13
RtcGetMonthDays(const uint8_t isLeapYear,const uint8_t month)14 uint8_t RtcGetMonthDays(const uint8_t isLeapYear, const uint8_t month)
15 {
16 uint8_t days;
17 uint8_t oddMonth;
18
19 if (IS_INVALID_MONTH(month) || (isLeapYear > RTC_TRUE)) {
20 return 0;
21 }
22
23 if (month == RTC_FEBRUARY) {
24 days = RTC_TWO_MONTH_DAY + isLeapYear;
25 } else {
26 oddMonth = (month >= RTC_AUGUST) ? (month - RTC_UNIT_DIFF) : month;
27 days = (oddMonth & RTC_ODD_MONTH_MASK) ? RTC_GREAT_MONTH_DAY : RTC_SMALL_MONTH_DAY;
28 }
29 return days;
30 }
31
RtcIsInvalidDay(const uint8_t day,const uint8_t month,const uint16_t year)32 uint8_t RtcIsInvalidDay(const uint8_t day, const uint8_t month, const uint16_t year)
33 {
34 uint8_t maxDay;
35 maxDay = RtcGetMonthDays(IS_LEAP_YEAR(year), month);
36
37 return ((day == 0) || (day > maxDay)) ? RTC_TRUE : RTC_FALSE;
38 }
39
RtcIsInvalid(const struct RtcTime * time)40 uint8_t RtcIsInvalid(const struct RtcTime *time)
41 {
42 if (time == NULL) {
43 HDF_LOGE("RtcIsInvalid: time is null!");
44 return RTC_FALSE;
45 }
46
47 return (IS_INVALID_YEAR(time->year) || IS_INVALID_MONTH(time->month) ||
48 (RtcIsInvalidDay(time->day, time->month, time->year) == RTC_TRUE) ||
49 IS_INVALID_HOUR(time->hour) || IS_INVALID_MIN(time->minute) ||
50 IS_INVALID_SECOND(time->second) || IS_INVALID_MS(time->millisecond));
51 }
52
RtcGetWeekDay(const struct RtcTime * time)53 uint8_t RtcGetWeekDay(const struct RtcTime *time)
54 {
55 uint32_t days;
56 int8_t month;
57 uint16_t year;
58
59 if ((time == NULL) || IS_INVALID_MONTH(time->month) || IS_INVALID_YEAR(time->year) ||
60 (RtcIsInvalidDay(time->day, time->month, time->year) == RTC_TRUE)) {
61 HDF_LOGE("RtcGetWeekDay: time is invalid!");
62 return RTC_FALSE;
63 }
64
65 days = time->day - RTC_UNIT_DIFF;
66 month = time->month;
67 while (--month >= RTC_JANUARY) {
68 days += RtcGetMonthDays(IS_LEAP_YEAR(time->year), month);
69 }
70
71 year = time->year;
72 while (--year >= RTC_BEGIN_YEAR) {
73 days += RTC_YEAR_DAYS(year);
74 }
75
76 return ((RTC_BEGIN_WEEKDAY + days - RTC_UNIT_DIFF) % RTC_MAX_WEEKDAY + RTC_UNIT_DIFF);
77 }
78
79 #ifndef __KERNEL__
RtcTimeToTimestamp(const struct RtcTime * time)80 uint64_t RtcTimeToTimestamp(const struct RtcTime *time)
81 {
82 uint64_t seconds;
83 uint32_t days;
84 uint16_t year;
85 int8_t month;
86
87 if (time == NULL) {
88 HDF_LOGE("RtcTimeToTimestamp: time is null!");
89 return RTC_FALSE;
90 }
91 PLAT_LOGV("RtcToTimestamp: year-month-day hour:min:second ms %04u-%02u-%02u %02u:%02u:%02u .%03u",
92 time->year, time->month, time->day, time->hour, time->minute, time->second, time->millisecond);
93 if (RtcIsInvalid(time) == RTC_TRUE) {
94 HDF_LOGE("RtcTimeToTimestamp: time invalid");
95 return 0;
96 }
97
98 seconds = ((uint64_t)time->hour * RTC_MAX_MINUTE + time->minute) * RTC_MAX_SECOND + time->second;
99 days = time->day - RTC_UNIT_DIFF;
100 month = time->month;
101 year = time->year;
102
103 for (month--; month >= RTC_JANUARY; month--) {
104 days += RtcGetMonthDays(IS_LEAP_YEAR(time->year), month);
105 }
106
107 for (year--; year >= RTC_BEGIN_YEAR; year--) {
108 days += RTC_YEAR_DAYS(year);
109 }
110
111 seconds += days * RTC_DAY_SECONDS;
112 return seconds;
113 }
114
TimestampToRtcTime(struct RtcTime * time,const uint64_t seconds)115 void TimestampToRtcTime(struct RtcTime *time, const uint64_t seconds)
116 {
117 uint32_t daySeconds = (uint32_t)(seconds % RTC_DAY_SECONDS);
118 uint32_t days = (uint32_t)(seconds / RTC_DAY_SECONDS);
119
120 if (time == NULL) {
121 HDF_LOGE("TimestampToRtcTime: time is null!");
122 return;
123 }
124
125 time->year = RTC_BEGIN_YEAR;
126 while (days >= RTC_YEAR_DAYS(time->year)) {
127 days -= RTC_YEAR_DAYS(time->year);
128 time->year++;
129 }
130
131 time->month = RTC_JANUARY;
132 while (days >= RtcGetMonthDays(IS_LEAP_YEAR(time->year), time->month)) {
133 days -= RtcGetMonthDays(IS_LEAP_YEAR(time->year), time->month);
134 time->month++;
135 }
136
137 time->day = days;
138 time->second = daySeconds % RTC_MAX_SECOND;
139 time->minute = (daySeconds % RTC_HOUR_SECONDS) / RTC_MAX_MINUTE;
140 time->hour = daySeconds / RTC_HOUR_SECONDS;
141
142 time->day += RTC_UNIT_DIFF;
143 time->weekday = RtcGetWeekDay(time);
144 PLAT_LOGV("TimestampToRtc: year-month-day weekday hour:min:second ms %04u-%02u-%02u %u %02u:%02u:%02u .%03u",
145 time->year, time->month, time->day, time->weekday, time->hour, time->minute, time->second, time->millisecond);
146 }
147 #endif
148