• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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