2 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file MDev_GpsRollOver.cpp
20 #include "MDev_GpsRollOver.h"
22 #define TIM_ROLOVR_CALCORCNT_DAYS (1024 * 7) /*1024 weeks * 7 days */
24 #define TMT_OK (1) /* Definition indicating normal status */
25 #define TMT_NG (0) /* Definitions indicating abnormal status */
26 #define TMT_TRUE (1) /* Definitions indicating the status for which the condition is true */
27 #define TMT_FALSE (0) /* Definitions indicating a status in which the condition is false */
29 #define TIM_ROLOVR_LEAPYEARDAYS (366) /*Number of days in the leap year */
30 #define TIM_ROLOVR_NOTLEAPYEARDAYS (365) /*Year days in non-leap years */
32 static const WORD kMonth[2][12] = {
33 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, /* Number of days per month(For non-leap year) */
34 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} /* Number of days per month(For leap years) */
36 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
37 * FUNCTION : ChkLeapYear
38 * Function : Leap year determination processing
39 * Feature Overview : Determine whether it is a leap year
40 * Input : u_int16 year
42 * Return value : u_int32
44 TMT_FALSE Non-leap year
45 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
46 static u_int32 ChkLeapYear(u_int16 year) {
49 /* Leap year determination processing (select subscripts in the [LEAP YEAR] table) *The processing that matches the time correction processing after time difference value addition/subtraction is used. */
50 leap_year = TMT_FALSE;
51 if ((year % 4) == 0) {
54 if ((year % 100) == 0) {
55 leap_year = TMT_FALSE;
58 if ((year % 400) == 0) {
66 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
67 * FUNCTION : RollOverFormerLaterDays
68 * Function : Calculation of the number of days before and after
69 * Feature Overview : The number of days from the beginning of the month to the previous day of the specified date,
70 and calculates the number of days after a given date, up to the end of the month
71 * Input : TG_TIM_ROLOVR_YMD* base_ymd Reference date
72 * Output : u_int32* former_days Number of days before (number of days before the specified date from the beginning of the month)
73 u_int32* later_days Number of days after(Number of days following the specified date until the end of the month)
75 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
76 static void RollOverFormerLaterDays(TG_TIM_ROLOVR_YMD* base_ymd, u_int32* former_days, u_int32* later_days) {
79 leap_year = ChkLeapYear(base_ymd->year);
81 *former_days = base_ymd->day - 1;
83 *later_days = kMonth[leap_year][base_ymd->month - 1] - base_ymd->day;
87 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
88 * FUNCTION : RollOverCalDaysWithinBY
89 * Function : Calculation of the difference in the number of days in the base year
90 * Feature Overview : Calculate the difference in the number of days between the base date and the conversion target date.
91 [Restriction]If the base date > conversion target date, the number of days difference is 0.
92 * Input : TG_TIM_ROLOVR_YMD* base_ymd Reference date
93 TG_TIM_ROLOVR_YMD* conv_ymd Conversion Date
95 * Return value : u_int32 Difference in the number of days(positive only)
96 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
97 static u_int32 RollOverCalDaysWithinBY(TG_TIM_ROLOVR_YMD* base_ymd, TG_TIM_ROLOVR_YMD* conv_ymd) {
98 int32 leap_year; /* Subscripts in the [LEAP YEAR] table */
99 u_int32 days; /* Day Difference Calculation Result */
100 u_int32 l_days; /* Number of days after the reference month */
101 u_int32 f_days; /* Number of days before the conversion target month */
102 u_int32 dmy_days; /* Dummy days(For storing unnecessary number of days in this function) */
103 u_int32 m_days; /* Sum of the number of days in the month between the base month and the month to be converted */
104 int32 cnt; /* A counter that sums the number of days in a month between the base month and the month to be converted */
105 u_int16 diff_month; /* Difference between the conversion target month and the base month */
106 u_int16 chk_month; /* Number of days of month to be acquired */
110 if (base_ymd->month == conv_ymd->month) {
111 if (base_ymd->day <= conv_ymd->day) {
112 days = conv_ymd->day - base_ymd->day;
114 days = 0; /* Set the difference to 0(Negative difference in number of days is not calculated.) */
116 } else if (base_ymd->month < conv_ymd->month) {
117 RollOverFormerLaterDays(base_ymd, &dmy_days, &l_days);
120 diff_month = conv_ymd->month - base_ymd->month;
122 leap_year = ChkLeapYear(base_ymd->year);
124 /* Calculate the sum of the number of days in the month between the base month and the conversion target month B */
125 chk_month = base_ymd->month + 1;
126 for (cnt = 0; cnt < (diff_month - 1); cnt++) {
127 m_days += kMonth[leap_year][chk_month - 1];
131 RollOverFormerLaterDays(conv_ymd, &f_days, &dmy_days);
133 days = l_days + m_days + f_days + 1; /* Calculate the difference in number of days as A+B+C+1 */
136 days = 0; /* Set the difference to 0(Negative difference in number of days is not calculated.) */
143 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
144 * FUNCTION : RollOverGetAYearDays
145 * Function : Process of obtaining the number of days per year
146 * Feature Overview : Get the number of days in a given year
147 * Input : u_int16 base_year Year
149 * Return value : u_int32 Number of days
150 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
151 static u_int32 RollOverGetAYearDays(u_int16 base_year) {
152 int32 leap_year; /* Subscripts in the [LEAP YEAR] table */
155 leap_year = ChkLeapYear(base_year); /* Leap year determination processing */
157 if (leap_year == TMT_TRUE) {
158 days = TIM_ROLOVR_LEAPYEARDAYS;
160 days = TIM_ROLOVR_NOTLEAPYEARDAYS;
166 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
167 * FUNCTION : RollOverConvYMDWithoutBY
168 * Function : Date conversion processing outside the base year, month, and day
169 * Feature Overview : Calculate the date shifted by the specified number of days from the specified date.
170 *If less than (1024 weeks x 7 days) is specified as the number of days difference, the calculation result is
171 returns the specified date(No correction)
172 * Input : TG_TIM_ROLOVR_YMD* base_ymd Reference date
173 u_int32 days Difference in the number of days
174 u_int32 days_by Number of days after + number of days after month
175 * Output : TG_TIM_ROLOVR_YMD* conv_ymd Date of the conversion result
176 * Return value : None
177 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
178 static void RollOverConvYMDWithoutBY(TG_TIM_ROLOVR_YMD* base_ymd, u_int32 days,
179 u_int32 days_by, TG_TIM_ROLOVR_YMD* conv_ymd) {
180 int32 leap_year; /* Subscripts in the [LEAP YEAR] table */
181 u_int32 rest_days; /* Remaining number of days */
182 u_int16 cal_year; /* For year calculation */
183 u_int16 cal_month; /* For monthly calculation */
184 u_int32 cal_days; /* To calculate the number of days */
186 rest_days = days - days_by; /* Remaining number of days is different from the number of initialization days.-(Number of days after + Number of days after month) */
187 cal_year = base_ymd->year + 1; /* The year is set to the year following the year of the initialization reference date. */ /* Ignore -> MISRA-C++:2008 Rule 5-0-5 */
189 cal_days = RollOverGetAYearDays(cal_year); /* Process of obtaining the number of days per year */
191 while (rest_days > cal_days) {
192 rest_days -= cal_days; /* Remaining Days = Remaining Days-Updated as Days of Year */
194 cal_year++; /* Increment Year */
196 cal_days = RollOverGetAYearDays(cal_year); /* Process of obtaining the number of days per year */
199 /* Year Finalization */
200 conv_ymd->year = cal_year; /* Year Calculated */
202 cal_month = 1; /* Initialize Month January */
204 leap_year = ChkLeapYear(conv_ymd->year); /* Leap year determination processing */
206 cal_days = kMonth[leap_year][cal_month - 1]; /* Acquisition processing of the number of days/month */ /* Ignore -> MISRA-C++:2008 Rule 5-0-5 */
208 while (rest_days > cal_days) {
209 rest_days -= cal_days; /* Remaining Days = Remaining Days-Updated as Days of Month */
211 cal_month++; /* Increment month */
213 cal_days = kMonth[leap_year][cal_month - 1]; /* Acquisition processing of the number of days/month */ /* Ignore -> MISRA-C++:2008 Rule 5-0-5 */
217 conv_ymd->month = cal_month; /* Month Calculated */
220 conv_ymd->day = (u_int16)rest_days; /* Day calculated Remaining number of days */
225 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
226 * FUNCTION : RollOverConvYMD
227 * Function : Date conversion processing
228 * Feature Overview : Calculate the date shifted by the specified number of days from the specified date.
229 *If the base date is shifted by the number of days but the year is the same as the base date, the result returns the base date
230 * Input : TG_TIM_ROLOVR_YMD* base_ymd Reference date
231 u_int32 days Difference in the number of days
232 * Output : TG_TIM_ROLOVR_YMD* conv_ymd Date of the conversion result
233 * Return value : None
234 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
235 static void RollOverConvYMD(TG_TIM_ROLOVR_YMD* base_ymd, u_int32 days, TG_TIM_ROLOVR_YMD* conv_ymd) {
236 u_int32 days_by; /* Number of days after + number of days after month(=difference in number of days from the base date to the end of the year) */
237 TG_TIM_ROLOVR_YMD tmp_ymd;
240 /* (number of days after + number of days after)Set calculation date( 12/31 ) */
241 tmp_ymd.year = base_ymd->year;
245 days_by = RollOverCalDaysWithinBY(base_ymd, &tmp_ymd); /* Calculation of the difference in the number of days in the base year */
247 if (days_by >= days) {
248 memcpy(conv_ymd, base_ymd, sizeof(TG_TIM_ROLOVR_YMD)); /* Returns the base date regardless of the number of days difference */
251 RollOverConvYMDWithoutBY(base_ymd, days, days_by, conv_ymd);
259 * Conversion to a time that takes the GPS week correction counter into account
261 * Converting the GPS Week Correction Counter to a Considered Time
263 * @param[in] TG_TIM_ROLOVR_YMD* base_ymd Reference date
264 * @param[in] u_int8 gpsweekcorcnt GPS weekly correction counter
265 * @param[out] TG_TIM_ROLOVR_YMD* conv_ymd Correction Date
269 void GPSRollOverConvTime(TG_TIM_ROLOVR_YMD* base_ymd, TG_TIM_ROLOVR_YMD* conv_ymd, u_int8 gpsweekcorcnt) {
270 u_int32 days; /* Difference in the number of days */
272 days = TIM_ROLOVR_CALCORCNT_DAYS * gpsweekcorcnt; /* (1024 weeks x 7 days) x GPS week correction counter to calculate the difference in the number of days */
274 RollOverConvYMD(base_ymd, days, conv_ymd); /* Date conversion processing */