- Merge from trunk up to r45543
[reactos.git] / boot / armllb / hw / time.c
1 /*
2 * PROJECT: ReactOS Boot Loader
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: boot/armllb/hw/time.c
5 * PURPOSE: LLB Time Routines
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 #include "precomp.h"
10
11 #define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
12
13 UCHAR LlbDaysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
14 TIMEINFO LlbTime;
15
16 BOOLEAN
17 NTAPI
18 LlbIsLeapYear(IN ULONG Year)
19 {
20 /* Every 4, 100, or 400 years */
21 return (!(Year % 4) && (Year % 100)) || !(Year % 400);
22 }
23
24 ULONG
25 NTAPI
26 LlbDayOfMonth(IN ULONG Month,
27 IN ULONG Year)
28 {
29 /* Check how many days a month has, accounting for leap yearS */
30 return LlbDaysInMonth[Month] + (LlbIsLeapYear(Year) && Month == 1);
31 }
32
33 VOID
34 NTAPI
35 LlbConvertRtcTime(IN ULONG RtcTime,
36 OUT TIMEINFO* TimeInfo)
37 {
38 ULONG Month, Year, Days, DaysLeft;
39
40 /* Count the days, keep the minutes */
41 Days = RtcTime / 86400;
42 RtcTime -= Days * 86400;
43
44 /* Get the year, based on days since 1970 */
45 Year = 1970 + Days / 365;
46
47 /* Account for leap years which changed the number of days/year */
48 Days -= (Year - 1970) * 365 + LEAPS_THRU_END_OF(Year - 1) - LEAPS_THRU_END_OF(1970 - 1);
49 if (Days < 0)
50 {
51 /* We hit a leap year, so fixup the math */
52 Year--;
53 Days += 365 + LlbIsLeapYear(Year);
54 }
55
56 /* Count months */
57 for (Month = 0; Month < 11; Month++)
58 {
59 /* How many days in this month? */
60 DaysLeft = Days - LlbDayOfMonth(Month, Year);
61 if (DaysLeft < 0) break;
62
63 /* How many days left total? */
64 Days = DaysLeft;
65 }
66
67 /* Write the structure */
68 TimeInfo->Year = Year;
69 TimeInfo->Day = Days + 1;
70 TimeInfo->Month = Month + 1;
71 TimeInfo->Hour = RtcTime / 3600;
72 RtcTime -= TimeInfo->Hour * 3600;
73 TimeInfo->Minute = RtcTime / 60;
74 TimeInfo->Second = RtcTime - TimeInfo->Minute * 60;
75 }
76
77 TIMEINFO*
78 NTAPI
79 LlbGetTime(VOID)
80 {
81 ULONG RtcTime;
82
83 /* Read RTC time */
84 RtcTime = LlbHwRtcRead();
85
86 /* Convert it */
87 LlbConvertRtcTime(RtcTime, &LlbTime);
88 return &LlbTime;
89 }
90
91 /* EOF */