summaryrefslogtreecommitdiff
path: root/arm9/lib/src
diff options
context:
space:
mode:
authorPikalaxALT <pikalaxalt@gmail.com>2020-08-22 20:50:56 -0400
committerPikalaxALT <pikalaxalt@gmail.com>2020-08-22 20:50:56 -0400
commit0f0b82b4dcdc39a8503b39bfb9125cab0ce6cdb4 (patch)
tree3fcaac545569d479e2c4afe3d1b761b6b25dcf5c /arm9/lib/src
parent96499a6120d0d0eb9382685253f69bd9123ddb18 (diff)
RTC_convert.c
Diffstat (limited to 'arm9/lib/src')
-rw-r--r--arm9/lib/src/RTC_convert.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/arm9/lib/src/RTC_convert.c b/arm9/lib/src/RTC_convert.c
new file mode 100644
index 00000000..af5574dc
--- /dev/null
+++ b/arm9/lib/src/RTC_convert.c
@@ -0,0 +1,164 @@
+#include "global.h"
+#include "RTC_api.h"
+#include "RTC_convert.h"
+
+static s32 sDayOfYear[12] = {
+ 0, // Jan
+ 31, // Feb
+ 59, // Mar
+ 90, // Apr
+ 120, // May
+ 151, // Jun
+ 181, // Jul
+ 212, // Aug
+ 243, // Sep
+ 273, // Oct
+ 304, // Nov
+ 334, // Dec
+};
+
+static inline BOOL RTCi_IsLeapYear(u32 year)
+{
+ return !((year & 0x03));
+}
+
+s32 RTC_ConvertDateToDay(const RTCDate * date)
+{
+ if (date->year >= 100
+ || date->month < 1
+ || date->month > 12
+ || date->day < 1
+ || date->day > 31
+ || date->week >= RTC_WEEK_MAX
+ || date->month < 1 // can't be
+ || date->month > 12 // too sure
+ )
+ return -1;
+ s32 dayNum = (s32)(date->day - 1);
+ dayNum += sDayOfYear[date->month - 1];
+ if (date->month >= 3 && RTCi_IsLeapYear(date->year))
+ dayNum++;
+ dayNum += date->year * 365;
+ dayNum += (date->year + 3) / 4;
+ return dayNum;
+}
+
+s32 RTCi_ConvertTimeToSecond(const RTCTime * time)
+{
+ return (time->hour * 60 + time->minute) * 60 + time->second;
+}
+
+s64 RTC_ConvertDateTimeToSecond(const RTCDate * date, const RTCTime * time)
+{
+ s32 day = RTC_ConvertDateToDay(date);
+ if (day == -1)
+ return -1;
+ s32 second = RTCi_ConvertTimeToSecond(time);
+ if (second == -1)
+ return -1;
+ return ((s64)day) * (60 * 60 * 24) + second;
+}
+
+void RTC_ConvertDayToDate(RTCDate * date, s32 day)
+{
+ u32 year;
+ s32 month;
+
+ if (day < 0)
+ {
+ day = 0;
+ }
+ if (day > 36524) // max number of days that can be recorded
+ {
+ day = 36524;
+ }
+ date->week = (RTCWeek)((day + 6) % 7);
+ for (year = 0; year < 99; year++)
+ {
+ s32 prev = day;
+ day -= (RTCi_IsLeapYear(year)) ? 366 : 365;
+ if (day < 0)
+ {
+ day = prev;
+ break;
+ }
+ }
+ if (day > 365)
+ {
+ day = 365;
+ }
+ date->year = year;
+ if (RTCi_IsLeapYear(year))
+ {
+ if (day < 31 + 29)
+ {
+ if (day < 31)
+ {
+ month = 1;
+ }
+ else
+ {
+ month = 2;
+ day -= 31;
+ }
+ date->month = (u32)month;
+ date->day = (u32)(day + 1);
+ return;
+ }
+ else
+ {
+ day--;
+ }
+ }
+ for (month = 11; month >= 0; month--)
+ {
+ if (day >= sDayOfYear[month])
+ {
+ date->month = (u32)(month + 1);
+ date->day = (u32)(day - sDayOfYear[month] + 1);
+ return;
+ }
+ }
+ // Internal Error.
+}
+
+void RTCi_ConvertSecondToTime(RTCTime * time, s32 sec)
+{
+ if (sec < 0)
+ sec = 0;
+ if (sec > 86399)
+ sec = 86399;
+ time->second = (u32)(sec % 60);
+ sec /= 60;
+ time->minute = (u32)(sec % 60);
+ sec /= 60;
+ time->hour = (u32)sec;
+}
+
+void RTC_ConvertSecondToDateTime(RTCDate * date, RTCTime * time, s64 sec)
+{
+ if (sec < 0)
+ sec = 0;
+ else if (sec > 3155759999)
+ sec = 3155759999;
+ RTCi_ConvertSecondToTime(time, (s32)(sec % 86400));
+ RTC_ConvertDayToDate(date, (s32)(sec / 86400));
+}
+
+RTCWeek RTC_GetDayOfWeek(RTCDate * date)
+{
+ int cent;
+ int year = (int)(2000 + date->year);
+ int month = (int)date->month;
+ int day = (int)date->day;
+
+ month -= 2;
+ if (month < 1)
+ {
+ month += 12;
+ --year;
+ }
+ cent = year / 100;
+ year %= 100;
+ return (RTCWeek)(((26 * month - 2) / 10 + day + year + year / 4 + cent / 4 + 5 * cent) % 7);
+}