From 67350b17dc9650942657d2fd960e429f5049cb14 Mon Sep 17 00:00:00 2001 From: CrazyBloo Date: Wed, 4 Sep 2024 21:11:38 -0400 Subject: [PATCH 1/5] fix ConvertUtcToLocalTime,RtcConvertLocalTimeToUtc --- src/core/libraries/rtc/rtc.cpp | 41 ++++++++++------------------------ src/core/libraries/rtc/rtc.h | 3 ++- 2 files changed, 14 insertions(+), 30 deletions(-) diff --git a/src/core/libraries/rtc/rtc.cpp b/src/core/libraries/rtc/rtc.cpp index e29a1cd74..1fe2fb2bc 100644 --- a/src/core/libraries/rtc/rtc.cpp +++ b/src/core/libraries/rtc/rtc.cpp @@ -80,7 +80,7 @@ int PS4_SYSV_ABI sceRtcConvertLocalTimeToUtc(OrbisRtcTick* pTickLocal, OrbisRtcT if (convertValue >= 0) { convertValue = sceRtcTickAddMinutes( - pTickUtc, pTickLocal, -((timezone.tz_dsttime + timezone.tz_minuteswest) / 60)); + pTickUtc, pTickLocal, -(((timezone.tz_dsttime * 60) - timezone.tz_minuteswest))); } return convertValue; @@ -95,29 +95,13 @@ int PS4_SYSV_ABI sceRtcConvertUtcToLocalTime(OrbisRtcTick* pTickUtc, OrbisRtcTic time_t seconds; Kernel::OrbisTimesec timezone; - int convertValue = Kernel::sceKernelConvertUtcToLocaltime( - (pTickUtc->tick + 0xff23400100d44000U) / 1000000, &seconds, &timezone, 0); + Kernel::OrbisKernelTimezone timeZone; + int returnValue = Kernel::sceKernelGettimezone(&timeZone); - if (convertValue >= 0) { - auto newTime = ((timezone.dst_sec + timezone.west_sec) / 60) * 60000000; + sceRtcTickAddMinutes(pTickLocal, pTickUtc, + -(timeZone.tz_minuteswest - (timeZone.tz_dsttime * 60))); - if (pTickLocal == nullptr) - return ORBIS_RTC_ERROR_INVALID_POINTER; - - if (newTime < 0) { - if (pTickUtc->tick < -newTime) { - return ORBIS_RTC_ERROR_INVALID_VALUE; - } - } else { - if ((pTickUtc->tick + newTime) < pTickUtc->tick) { - return ORBIS_RTC_ERROR_INVALID_VALUE; - } - } - pTickLocal->tick = pTickUtc->tick + newTime; - convertValue = 0; - } - - return convertValue; + return 0; } int PS4_SYSV_ABI sceRtcEnd() { @@ -471,14 +455,13 @@ int PS4_SYSV_ABI sceRtcSetDosTime(OrbisRtcDateTime* pTime, u32 dosTime) { pTime->microsecond = 0; pTime->second = (dosTime << 1) & 0x3e; pTime->minute = (dosTime >> 5) & 0x3f; - pTime->hour = ((dosTime & 0xf800) >> 0xb); + pTime->hour = (dosTime & 0xf800) >> 0xb; - int days = (dosTime >> 0x10); + int16_t days = dosTime >> 0x10; pTime->day = days & 0x1f; - pTime->month = (days >> 5) & 0xf; - pTime->year = (days >> 9) + 0x7bc; - + pTime->month = (days >> 5) & 0x0f; + pTime->year = (days >> 9) + 1980; return SCE_OK; } @@ -559,13 +542,13 @@ int PS4_SYSV_ABI sceRtcSetTime_t(OrbisRtcDateTime* pTime, time_t llTime) { return SCE_OK; } -int PS4_SYSV_ABI sceRtcSetWin32FileTime(OrbisRtcDateTime* pTime, uint64_t ulWin32Time) { +int PS4_SYSV_ABI sceRtcSetWin32FileTime(OrbisRtcDateTime* pTime, int64_t ulWin32Time) { LOG_TRACE(Lib_Rtc, "called"); if (pTime == nullptr) return ORBIS_RTC_ERROR_INVALID_POINTER; - u64 convertedTime = (ulWin32Time / 10) + 0xb36168b6a58000; + u64 convertedTime = (ulWin32Time / 10) + WIN32_FILETIME_EPOCH_TICKS; OrbisRtcTick convertedTick; convertedTick.tick = convertedTime; diff --git a/src/core/libraries/rtc/rtc.h b/src/core/libraries/rtc/rtc.h index 776fa3653..d71998635 100644 --- a/src/core/libraries/rtc/rtc.h +++ b/src/core/libraries/rtc/rtc.h @@ -20,6 +20,7 @@ constexpr int ORBIS_RTC_DAYOFWEEK_FRIDAY = 5; constexpr int ORBIS_RTC_DAYOFWEEK_SATURDAY = 6; constexpr int64_t UNIX_EPOCH_TICKS = 0xdcbffeff2bc000; +constexpr int64_t WIN32_FILETIME_EPOCH_TICKS = 0xb36168b6a58000; struct OrbisRtcTick { uint64_t tick; @@ -74,7 +75,7 @@ int PS4_SYSV_ABI sceRtcSetCurrentTick(); int PS4_SYSV_ABI sceRtcSetDosTime(OrbisRtcDateTime* pTime, u32 dosTime); int PS4_SYSV_ABI sceRtcSetTick(OrbisRtcDateTime* pTime, OrbisRtcTick* pTick); int PS4_SYSV_ABI sceRtcSetTime_t(OrbisRtcDateTime* pTime, time_t llTime); -int PS4_SYSV_ABI sceRtcSetWin32FileTime(OrbisRtcDateTime* pTime, uint64_t ulWin32Time); +int PS4_SYSV_ABI sceRtcSetWin32FileTime(OrbisRtcDateTime* pTime, int64_t ulWin32Time); int PS4_SYSV_ABI sceRtcTickAddDays(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd); int PS4_SYSV_ABI sceRtcTickAddHours(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd); int PS4_SYSV_ABI sceRtcTickAddMicroseconds(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, From b5437974f2ff39c51bb36c15d70598e4ea9c8050 Mon Sep 17 00:00:00 2001 From: CrazyBloo Date: Thu, 5 Sep 2024 03:32:52 -0400 Subject: [PATCH 2/5] format rfc2822, format rfc3339 --- src/core/libraries/rtc/rtc.cpp | 280 +++++++++++++++++++++++++++++++-- 1 file changed, 265 insertions(+), 15 deletions(-) diff --git a/src/core/libraries/rtc/rtc.cpp b/src/core/libraries/rtc/rtc.cpp index 1fe2fb2bc..035811967 100644 --- a/src/core/libraries/rtc/rtc.cpp +++ b/src/core/libraries/rtc/rtc.cpp @@ -92,9 +92,6 @@ int PS4_SYSV_ABI sceRtcConvertUtcToLocalTime(OrbisRtcTick* pTickUtc, OrbisRtcTic if (pTickUtc == nullptr) return ORBIS_RTC_ERROR_INVALID_POINTER; - time_t seconds; - Kernel::OrbisTimesec timezone; - Kernel::OrbisKernelTimezone timeZone; int returnValue = Kernel::sceKernelGettimezone(&timeZone); @@ -110,36 +107,289 @@ int PS4_SYSV_ABI sceRtcEnd() { int PS4_SYSV_ABI sceRtcFormatRFC2822(char* pszDateTime, const OrbisRtcTick* pTickUtc, int iTimeZoneMinutes) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_TRACE(Lib_Rtc, "called"); + + if (pszDateTime == nullptr) + return ORBIS_RTC_ERROR_INVALID_POINTER; + + OrbisRtcTick formatTick; + + if (pTickUtc == nullptr) { + sceRtcGetCurrentTick(&formatTick); + } else { + formatTick.tick = pTickUtc->tick; + } + + sceRtcTickAddMinutes(&formatTick, &formatTick, iTimeZoneMinutes); + + OrbisRtcDateTime formatTime; + sceRtcSetTick(&formatTime, &formatTick); + + int validTime = sceRtcCheckValid(&formatTime); + + std::string formattedString; + + if (validTime >= 0) { + int weekDay = sceRtcGetDayOfWeek(formatTime.year, formatTime.month, formatTime.day); + switch (weekDay) { + case 0: + formattedString = "Sun, "; + break; + case 1: + formattedString = "Mon, "; + break; + case 2: + formattedString = "Tue, "; + break; + case 3: + formattedString = "Wed, "; + break; + case 4: + formattedString = "Thu, "; + break; + case 5: + formattedString = "Fri, "; + break; + case 6: + formattedString = "Sat, "; + break; + } + + if (formatTime.day < 10) { + formattedString += "0" + std::to_string(formatTime.day) + " "; + } else { + formattedString += std::to_string(formatTime.day) + " "; + } + + switch (formatTime.month) { + case 1: + formattedString += "Jan "; + break; + case 2: + formattedString += "Feb "; + break; + case 3: + formattedString += "Mar "; + break; + case 4: + formattedString += "Apr "; + break; + case 5: + formattedString += "May "; + break; + case 6: + formattedString += "Jun "; + break; + case 7: + formattedString += "Jul "; + break; + case 8: + formattedString += "Aug "; + break; + case 9: + formattedString += "Sep "; + break; + case 10: + formattedString += "Oct "; + break; + case 11: + formattedString += "Nov "; + break; + case 12: + formattedString += "Dec "; + break; + } + + formattedString += std::to_string(formatTime.year) + " "; + + if (formatTime.hour < 10) { + formattedString += "0" + std::to_string(formatTime.hour) + ":"; + } else { + formattedString += std::to_string(formatTime.hour) + ":"; + } + + if (formatTime.minute < 10) { + formattedString += "0" + std::to_string(formatTime.minute) + ":"; + } else { + formattedString += std::to_string(formatTime.minute) + ":"; + } + + if (formatTime.second < 10) { + formattedString += "0" + std::to_string(formatTime.second) + " "; + } else { + formattedString += std::to_string(formatTime.second) + " "; + } + + if (iTimeZoneMinutes == 0) { + formattedString += "+0000"; + } else { + int timeZoneHours = iTimeZoneMinutes / 60; + int timeZoneRemainder = iTimeZoneMinutes % 60; + + // negative timezone + if (timeZoneHours < 0) { + formattedString += "-"; + timeZoneHours *= -1; + } else { + // positive timezone + formattedString += "+"; + } + + if (timeZoneHours < 10) { + formattedString += "0" + std::to_string(timeZoneHours); + } else { + formattedString += std::to_string(timeZoneHours); + } + + if (timeZoneRemainder == 0) { + formattedString += "00"; + } else { + if (timeZoneRemainder < 0) + timeZoneRemainder *= -1; + formattedString += std::to_string(timeZoneRemainder); + } + } + + for (int i = 0; i < formattedString.size() + 1; ++i) { + pszDateTime[i] = formattedString.c_str()[i]; + } + } + + return SCE_OK; } int PS4_SYSV_ABI sceRtcFormatRFC2822LocalTime(char* pszDateTime, const OrbisRtcTick* pTickUtc) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_TRACE(Lib_Rtc, "called"); + + Kernel::OrbisKernelTimezone timeZone; + Kernel::sceKernelGettimezone(&timeZone); + + return sceRtcFormatRFC2822(pszDateTime, pTickUtc, + -(timeZone.tz_minuteswest - (timeZone.tz_dsttime * 60))); } int PS4_SYSV_ABI sceRtcFormatRFC3339(char* pszDateTime, const OrbisRtcTick* pTickUtc, int iTimeZoneMinutes) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_TRACE(Lib_Rtc, "called"); + return sceRtcFormatRFC3339Precise(pszDateTime, pTickUtc, iTimeZoneMinutes); } int PS4_SYSV_ABI sceRtcFormatRFC3339LocalTime(char* pszDateTime, const OrbisRtcTick* pTickUtc) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_TRACE(Lib_Rtc, "called"); + + Kernel::OrbisKernelTimezone timeZone; + Kernel::sceKernelGettimezone(&timeZone); + + return sceRtcFormatRFC3339(pszDateTime, pTickUtc, + -(timeZone.tz_minuteswest - (timeZone.tz_dsttime * 60))); } int PS4_SYSV_ABI sceRtcFormatRFC3339Precise(char* pszDateTime, const OrbisRtcTick* pTickUtc, int iTimeZoneMinutes) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_TRACE(Lib_Rtc, "called"); + + if (pszDateTime == nullptr) + return ORBIS_RTC_ERROR_INVALID_POINTER; + + OrbisRtcTick formatTick; + + if (pTickUtc == nullptr) { + sceRtcGetCurrentTick(&formatTick); + } else { + formatTick.tick = pTickUtc->tick; + } + + sceRtcTickAddMinutes(&formatTick, &formatTick, iTimeZoneMinutes); + + OrbisRtcDateTime formatTime; + + sceRtcSetTick(&formatTime, &formatTick); + + std::string formattedString; + formattedString = std::to_string(formatTime.year) + "-"; + + if (formatTime.month < 10) { + formattedString += "0" + std::to_string(formatTime.month) + "-"; + } else { + formattedString += std::to_string(formatTime.month) + "-"; + } + + if (formatTime.day < 10) { + formattedString += "0" + std::to_string(formatTime.day) + "T"; + } else { + formattedString += std::to_string(formatTime.day) + "T"; + } + + if (formatTime.hour < 10) { + formattedString += "0" + std::to_string(formatTime.hour) + ":"; + } else { + formattedString += std::to_string(formatTime.hour) + ":"; + } + + if (formatTime.minute < 10) { + formattedString += "0" + std::to_string(formatTime.minute) + ":"; + } else { + formattedString += std::to_string(formatTime.minute) + ":"; + } + + if (formatTime.second < 10) { + formattedString += "0" + std::to_string(formatTime.second); + } else { + formattedString += std::to_string(formatTime.second); + } + + if (formatTime.microsecond != 0) { + formattedString += "." + std::to_string(formatTime.microsecond / 1000).substr(0, 2); + } + + if (iTimeZoneMinutes == 0) { + formattedString += "z"; + } else { + int timeZoneHours = iTimeZoneMinutes / 60; + int timeZoneRemainder = iTimeZoneMinutes % 60; + + // negative timezone + if (timeZoneHours < 0) { + formattedString += "-"; + timeZoneHours *= -1; + } else { + // positive timezone + formattedString += "+"; + } + + if (timeZoneHours < 10) { + formattedString += "0" + std::to_string(timeZoneHours); + } else { + formattedString += std::to_string(timeZoneHours); + } + + if (timeZoneRemainder == 0) { + formattedString += ":00"; + } else { + if (timeZoneRemainder < 0) + timeZoneRemainder *= -1; + formattedString += ":" + std::to_string(timeZoneRemainder); + } + } + + + + for (int i = 0; i < formattedString.size() + 1; ++i) { + pszDateTime[i] = formattedString.c_str()[i]; + } + + return SCE_OK; } int PS4_SYSV_ABI sceRtcFormatRFC3339PreciseLocalTime(char* pszDateTime, const OrbisRtcTick* pTickUtc) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_TRACE(Lib_Rtc, "called"); + + Kernel::OrbisKernelTimezone timeZone; + Kernel::sceKernelGettimezone(&timeZone); + + return sceRtcFormatRFC3339Precise(pszDateTime, pTickUtc, + -(timeZone.tz_minuteswest - (timeZone.tz_dsttime * 60))); } int PS4_SYSV_ABI sceRtcGetCurrentAdNetworkTick(OrbisRtcTick* pTick) { From 44e310e27e04e28a9e7a82ed276176f0ef1a2a2f Mon Sep 17 00:00:00 2001 From: CrazyBloo Date: Thu, 5 Sep 2024 03:39:47 -0400 Subject: [PATCH 3/5] format --- src/core/libraries/rtc/rtc.cpp | 82 +++++++++++++++++----------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/src/core/libraries/rtc/rtc.cpp b/src/core/libraries/rtc/rtc.cpp index 035811967..b5448f4aa 100644 --- a/src/core/libraries/rtc/rtc.cpp +++ b/src/core/libraries/rtc/rtc.cpp @@ -132,26 +132,26 @@ int PS4_SYSV_ABI sceRtcFormatRFC2822(char* pszDateTime, const OrbisRtcTick* pTic if (validTime >= 0) { int weekDay = sceRtcGetDayOfWeek(formatTime.year, formatTime.month, formatTime.day); switch (weekDay) { - case 0: - formattedString = "Sun, "; + case 0: + formattedString = "Sun, "; break; - case 1: - formattedString = "Mon, "; + case 1: + formattedString = "Mon, "; break; - case 2: - formattedString = "Tue, "; + case 2: + formattedString = "Tue, "; break; - case 3: - formattedString = "Wed, "; + case 3: + formattedString = "Wed, "; break; - case 4: - formattedString = "Thu, "; + case 4: + formattedString = "Thu, "; break; - case 5: - formattedString = "Fri, "; + case 5: + formattedString = "Fri, "; break; - case 6: - formattedString = "Sat, "; + case 6: + formattedString = "Sat, "; break; } @@ -162,46 +162,46 @@ int PS4_SYSV_ABI sceRtcFormatRFC2822(char* pszDateTime, const OrbisRtcTick* pTic } switch (formatTime.month) { - case 1: - formattedString += "Jan "; + case 1: + formattedString += "Jan "; break; - case 2: - formattedString += "Feb "; + case 2: + formattedString += "Feb "; break; - case 3: - formattedString += "Mar "; + case 3: + formattedString += "Mar "; break; - case 4: - formattedString += "Apr "; + case 4: + formattedString += "Apr "; break; - case 5: - formattedString += "May "; + case 5: + formattedString += "May "; break; - case 6: - formattedString += "Jun "; + case 6: + formattedString += "Jun "; break; - case 7: - formattedString += "Jul "; + case 7: + formattedString += "Jul "; break; - case 8: - formattedString += "Aug "; + case 8: + formattedString += "Aug "; break; - case 9: - formattedString += "Sep "; + case 9: + formattedString += "Sep "; break; - case 10: - formattedString += "Oct "; + case 10: + formattedString += "Oct "; break; - case 11: - formattedString += "Nov "; + case 11: + formattedString += "Nov "; break; - case 12: - formattedString += "Dec "; + case 12: + formattedString += "Dec "; break; } formattedString += std::to_string(formatTime.year) + " "; - + if (formatTime.hour < 10) { formattedString += "0" + std::to_string(formatTime.hour) + ":"; } else { @@ -319,7 +319,7 @@ int PS4_SYSV_ABI sceRtcFormatRFC3339Precise(char* pszDateTime, const OrbisRtcTic } else { formattedString += std::to_string(formatTime.day) + "T"; } - + if (formatTime.hour < 10) { formattedString += "0" + std::to_string(formatTime.hour) + ":"; } else { @@ -372,8 +372,6 @@ int PS4_SYSV_ABI sceRtcFormatRFC3339Precise(char* pszDateTime, const OrbisRtcTic } } - - for (int i = 0; i < formattedString.size() + 1; ++i) { pszDateTime[i] = formattedString.c_str()[i]; } From a83bf77a25129e30f0eb2327c5d339bab53ddcc3 Mon Sep 17 00:00:00 2001 From: CrazyBloo Date: Thu, 5 Sep 2024 05:19:24 -0400 Subject: [PATCH 4/5] GetDosTime, GetTime_t, GetWin32FileTime +various formatting improvements --- src/core/libraries/rtc/rtc.cpp | 92 ++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 22 deletions(-) diff --git a/src/core/libraries/rtc/rtc.cpp b/src/core/libraries/rtc/rtc.cpp index b5448f4aa..5f702c21c 100644 --- a/src/core/libraries/rtc/rtc.cpp +++ b/src/core/libraries/rtc/rtc.cpp @@ -76,7 +76,7 @@ int PS4_SYSV_ABI sceRtcConvertLocalTimeToUtc(OrbisRtcTick* pTickLocal, OrbisRtcT Kernel::OrbisKernelTimezone timezone; int convertValue = Kernel::sceKernelConvertLocaltimeToUtc( - (pTickLocal->tick + 0xff23400100d44000U) / 1000000, 0xffffffff, &seconds, &timezone, 0); + (pTickLocal->tick - UNIX_EPOCH_TICKS) / 1000000, 0xffffffff, &seconds, &timezone, 0); if (convertValue >= 0) { convertValue = sceRtcTickAddMinutes( @@ -151,7 +151,7 @@ int PS4_SYSV_ABI sceRtcFormatRFC2822(char* pszDateTime, const OrbisRtcTick* pTic formattedString = "Fri, "; break; case 6: - formattedString = "Sat, "; + formattedString = "Sat, "; break; } @@ -226,12 +226,10 @@ int PS4_SYSV_ABI sceRtcFormatRFC2822(char* pszDateTime, const OrbisRtcTick* pTic int timeZoneHours = iTimeZoneMinutes / 60; int timeZoneRemainder = iTimeZoneMinutes % 60; - // negative timezone if (timeZoneHours < 0) { formattedString += "-"; timeZoneHours *= -1; } else { - // positive timezone formattedString += "+"; } @@ -348,12 +346,10 @@ int PS4_SYSV_ABI sceRtcFormatRFC3339Precise(char* pszDateTime, const OrbisRtcTic int timeZoneHours = iTimeZoneMinutes / 60; int timeZoneRemainder = iTimeZoneMinutes % 60; - // negative timezone if (timeZoneHours < 0) { formattedString += "-"; timeZoneHours *= -1; } else { - // positive timezone formattedString += "+"; } @@ -399,7 +395,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentAdNetworkTick(OrbisRtcTick* pTick) { Kernel::OrbisKernelTimespec clocktime; int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); - if (returnValue == 0) { + if (returnValue == SCE_OK) { pTick->tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + UNIX_EPOCH_TICKS; } else { return ORBIS_RTC_ERROR_NOT_INITIALIZED; @@ -417,7 +413,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentClock(OrbisRtcDateTime* pTime, int timeZone) { Kernel::OrbisKernelTimespec clocktime; int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); - if (returnValue == 0) { + if (returnValue == SCE_OK) { OrbisRtcTick clockTick; clockTick.tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + UNIX_EPOCH_TICKS; @@ -468,7 +464,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentDebugNetworkTick(OrbisRtcTick* pTick) { Kernel::OrbisKernelTimespec clocktime; int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); - if (returnValue == 0) { + if (returnValue == SCE_OK) { pTick->tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + UNIX_EPOCH_TICKS; } else { return ORBIS_RTC_ERROR_NOT_INITIALIZED; @@ -486,7 +482,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentNetworkTick(OrbisRtcTick* pTick) { Kernel::OrbisKernelTimespec clocktime; int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); - if (returnValue == 0) { + if (returnValue == SCE_OK) { pTick->tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + UNIX_EPOCH_TICKS; } else { return ORBIS_RTC_ERROR_NOT_INITIALIZED; @@ -504,7 +500,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentRawNetworkTick(OrbisRtcTick* pTick) { Kernel::OrbisKernelTimespec clocktime; int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); - if (returnValue == 0) { + if (returnValue == SCE_OK) { pTick->tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + UNIX_EPOCH_TICKS; } else { return ORBIS_RTC_ERROR_NOT_INITIALIZED; @@ -588,8 +584,24 @@ int PS4_SYSV_ABI sceRtcGetDaysInMonth(int year, int month) { } int PS4_SYSV_ABI sceRtcGetDosTime(OrbisRtcDateTime* pTime, unsigned int* dosTime) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_TRACE(Lib_Rtc, "called"); + + if (pTime == nullptr || dosTime == nullptr) + return ORBIS_RTC_ERROR_INVALID_POINTER; + + int isValid = sceRtcCheckValid(pTime); + if (isValid != SCE_OK) { + return isValid; + } + + *dosTime |= (pTime->second / 2) & 0x1F; + *dosTime |= (pTime->minute & 0x3F) << 5; + *dosTime |= (pTime->hour & 0x1F) << 11; + *dosTime |= (pTime->day & 0x1F) << 16; + *dosTime |= (pTime->month & 0x0F) << 21; + *dosTime |= ((pTime->year - 1980) & 0x7F) << 25; + + return SCE_OK; } int PS4_SYSV_ABI sceRtcGetTick(OrbisRtcDateTime* pTime, OrbisRtcTick* pTick) { @@ -634,13 +646,49 @@ unsigned int PS4_SYSV_ABI sceRtcGetTickResolution() { } int PS4_SYSV_ABI sceRtcGetTime_t(OrbisRtcDateTime* pTime, time_t* llTime) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_TRACE(Lib_Rtc, "called"); + + if (pTime == nullptr || llTime == nullptr) + return ORBIS_RTC_ERROR_INVALID_POINTER; + + int isValid = sceRtcCheckValid(pTime); + if (isValid != SCE_OK) { + return isValid; + } + + OrbisRtcTick timeTick; + sceRtcGetTick(pTime, &timeTick); + + if (timeTick.tick < UNIX_EPOCH_TICKS) { + *llTime = 0; + } else { + *llTime = (timeTick.tick - UNIX_EPOCH_TICKS) / 1000000; + } + + return SCE_OK; } int PS4_SYSV_ABI sceRtcGetWin32FileTime(OrbisRtcDateTime* pTime, uint64_t* ulWin32Time) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_TRACE(Lib_Rtc, "called"); + + if (pTime == nullptr || ulWin32Time == nullptr) + return ORBIS_RTC_ERROR_INVALID_POINTER; + + int isValid = sceRtcCheckValid(pTime); + if (isValid != SCE_OK) { + return isValid; + } + + OrbisRtcTick timeTick; + sceRtcGetTick(pTime, &timeTick); + + if (timeTick.tick < WIN32_FILETIME_EPOCH_TICKS) { + *ulWin32Time = 0; + } else { + *ulWin32Time = (timeTick.tick - WIN32_FILETIME_EPOCH_TICKS) * 10; + } + + return SCE_OK; } int PS4_SYSV_ABI sceRtcInit() { @@ -894,8 +942,8 @@ int PS4_SYSV_ABI sceRtcTickAddMonths(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, time.day = lastDay; } - u64 timeIsValid = sceRtcCheckValid(&time); - if (timeIsValid == 0) { + int timeIsValid = sceRtcCheckValid(&time); + if (timeIsValid == SCE_OK) { sceRtcGetTick(&time, pTick1); } else { return timeIsValid; @@ -932,7 +980,7 @@ int PS4_SYSV_ABI sceRtcTickAddWeeks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, if (pTick1 == nullptr || pTick2 == nullptr) return ORBIS_RTC_ERROR_INVALID_POINTER; - pTick1->tick = (lAdd * 0x8cd0e3a000) + pTick2->tick; + pTick1->tick = (lAdd * 604800000000) + pTick2->tick; return SCE_OK; } @@ -954,8 +1002,8 @@ int PS4_SYSV_ABI sceRtcTickAddYears(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, time.year += lAdd; - u64 timeIsValid = sceRtcCheckValid(&time); - if (timeIsValid == 0) { + int timeIsValid = sceRtcCheckValid(&time); + if (timeIsValid == SCE_OK) { sceRtcGetTick(&time, pTick1); } else { return timeIsValid; From 00f9b6d8115b698e6bc955c7ef9ffcbd1acebd0e Mon Sep 17 00:00:00 2001 From: CrazyBloo Date: Thu, 5 Sep 2024 07:08:19 -0400 Subject: [PATCH 5/5] sceRtcParseRFC3339, sceRtcParseDateTime --- src/core/libraries/rtc/rtc.cpp | 149 ++++++++++++++++++++++++++++----- src/core/libraries/rtc/rtc.h | 8 +- 2 files changed, 134 insertions(+), 23 deletions(-) diff --git a/src/core/libraries/rtc/rtc.cpp b/src/core/libraries/rtc/rtc.cpp index 5f702c21c..7a46a1e31 100644 --- a/src/core/libraries/rtc/rtc.cpp +++ b/src/core/libraries/rtc/rtc.cpp @@ -338,10 +338,12 @@ int PS4_SYSV_ABI sceRtcFormatRFC3339Precise(char* pszDateTime, const OrbisRtcTic if (formatTime.microsecond != 0) { formattedString += "." + std::to_string(formatTime.microsecond / 1000).substr(0, 2); + } else { + formattedString += ".00"; } if (iTimeZoneMinutes == 0) { - formattedString += "z"; + formattedString += "Z"; } else { int timeZoneHours = iTimeZoneMinutes / 60; int timeZoneRemainder = iTimeZoneMinutes % 60; @@ -421,9 +423,6 @@ int PS4_SYSV_ABI sceRtcGetCurrentClock(OrbisRtcDateTime* pTime, int timeZone) { sceRtcSetTick(pTime, &clockTick); } - LOG_INFO(Lib_Rtc, "Got Current Clock {}/{}/{} @ {}:{}", pTime->year, pTime->month, pTime->day, - pTime->hour, pTime->minute); - return returnValue; } @@ -450,8 +449,6 @@ int PS4_SYSV_ABI sceRtcGetCurrentClockLocalTime(OrbisRtcDateTime* pTime) { } } - LOG_INFO(Lib_Rtc, "Got Local Time {}/{}/{} @ {}:{}", pTime->year, pTime->month, pTime->day, - pTime->hour, pTime->minute); return returnValue; } @@ -559,8 +556,6 @@ int PS4_SYSV_ABI sceRtcGetDayOfWeek(int year, int month, int day) { std::chrono::day(day)}; std::chrono::weekday chrono_weekday{chrono_time}; - LOG_INFO(Lib_Rtc, "Got Day Of Week : {}", chrono_weekday.c_encoding()); - return chrono_weekday.c_encoding(); } @@ -578,8 +573,6 @@ int PS4_SYSV_ABI sceRtcGetDaysInMonth(int year, int month) { int lastDay = static_cast(unsigned( std::chrono::year_month_day_last{chronoYear / chronoMonth / std::chrono::last}.day())); - LOG_INFO(Lib_Rtc, "Got Days In Month : {}", lastDay); - return lastDay; } @@ -600,7 +593,7 @@ int PS4_SYSV_ABI sceRtcGetDosTime(OrbisRtcDateTime* pTime, unsigned int* dosTime *dosTime |= (pTime->day & 0x1F) << 16; *dosTime |= (pTime->month & 0x0F) << 21; *dosTime |= ((pTime->year - 1980) & 0x7F) << 25; - + return SCE_OK; } @@ -707,14 +700,132 @@ int PS4_SYSV_ABI sceRtcIsLeapYear(int yearInt) { return (ymdl.day() == 29d); } +int GetMonthFromString(std::string monthStr) { + if (monthStr == "Jan") + return 1; + + if (monthStr == "Feb") + return 2; + + if (monthStr == "Mar") + return 3; + + if (monthStr == "Apr") + return 4; + + if (monthStr == "May") + return 5; + + if (monthStr == "Jun") + return 6; + + if (monthStr == "Jul") + return 7; + + if (monthStr == "Aug") + return 8; + + if (monthStr == "Sep") + return 9; + + if (monthStr == "Oct") + return 10; + + if (monthStr == "Nov") + return 11; + + if (monthStr == "Dec") + return 12; + + return 1; +} + int PS4_SYSV_ABI sceRtcParseDateTime(OrbisRtcTick* pTickUtc, const char* pszDateTime) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_TRACE(Lib_Rtc, "called"); + + if (pTickUtc == nullptr || pszDateTime == nullptr) + return ORBIS_RTC_ERROR_INVALID_POINTER; + + std::string dateTimeString = std::string(pszDateTime); + + char formatKey = dateTimeString[22]; + OrbisRtcDateTime dateTime; + + if (formatKey == 'Z' || formatKey == '-' || formatKey == '+') { + // RFC3339 + sceRtcParseRFC3339(pTickUtc, pszDateTime); + } else if (formatKey == ':') { + // RFC2822 + dateTime.day = std::stoi(dateTimeString.substr(5, 2)); + dateTime.month = GetMonthFromString(dateTimeString.substr(8, 3)); + dateTime.year = std::stoi(dateTimeString.substr(12, 4)); + dateTime.hour = std::stoi(dateTimeString.substr(17, 2)); + dateTime.minute = std::stoi(dateTimeString.substr(20, 2)); + dateTime.second = std::stoi(dateTimeString.substr(23, 2)); + dateTime.microsecond = 0; + + sceRtcGetTick(&dateTime, pTickUtc); + + if (dateTimeString[26] == '+') { + int timeZoneOffset = std::stoi(dateTimeString.substr(27, 2)) * 60; + timeZoneOffset += std::stoi(dateTimeString.substr(29, 2)); + sceRtcTickAddMinutes(pTickUtc, pTickUtc, timeZoneOffset); + } else if (dateTimeString[26] == '-') { + int timeZoneOffset = std::stoi(dateTimeString.substr(27, 2)) * 60; + timeZoneOffset += std::stoi(dateTimeString.substr(29, 2)); + timeZoneOffset *= -1; + sceRtcTickAddMinutes(pTickUtc, pTickUtc, timeZoneOffset); + } + + } else { + // asctime + dateTime.month = GetMonthFromString(dateTimeString.substr(4, 3)); + dateTime.day = std::stoi(dateTimeString.substr(8, 2)); + dateTime.hour = std::stoi(dateTimeString.substr(11, 2)); + dateTime.minute = std::stoi(dateTimeString.substr(14, 2)); + dateTime.second = std::stoi(dateTimeString.substr(17, 2)); + dateTime.year = std::stoi(dateTimeString.substr(20, 4)); + dateTime.microsecond = 0; + + sceRtcGetTick(&dateTime, pTickUtc); + } + + return SCE_OK; } int PS4_SYSV_ABI sceRtcParseRFC3339(OrbisRtcTick* pTickUtc, const char* pszDateTime) { - LOG_ERROR(Lib_Rtc, "(STUBBED) called"); - return ORBIS_OK; + LOG_TRACE(Lib_Rtc, "called"); + + if (pTickUtc == nullptr || pszDateTime == nullptr) + return ORBIS_RTC_ERROR_INVALID_POINTER; + + std::string dateTimeString = std::string(pszDateTime); + + OrbisRtcDateTime dateTime; + dateTime.year = std::stoi(dateTimeString.substr(0, 4)); + dateTime.month = std::stoi(dateTimeString.substr(5, 2)); + dateTime.day = std::stoi(dateTimeString.substr(8, 2)); + dateTime.hour = std::stoi(dateTimeString.substr(11, 2)); + dateTime.minute = std::stoi(dateTimeString.substr(14, 2)); + dateTime.second = std::stoi(dateTimeString.substr(17, 2)); + dateTime.microsecond = std::stoi(dateTimeString.substr(20, 2)); + + sceRtcGetTick(&dateTime, pTickUtc); + + if (dateTimeString[22] != 'Z') { + if (dateTimeString[22] == '-') { + int timeZoneOffset = std::stoi(dateTimeString.substr(23, 2)) * 60; + timeZoneOffset += std::stoi(dateTimeString.substr(26, 2)); + timeZoneOffset *= -1; + sceRtcTickAddMinutes(pTickUtc, pTickUtc, timeZoneOffset); + } else if (dateTimeString[22] == '+') { + int timeZoneOffset = std::stoi(dateTimeString.substr(23, 2)) * 60; + timeZoneOffset += std::stoi(dateTimeString.substr(26, 2)); + sceRtcTickAddMinutes(pTickUtc, pTickUtc, timeZoneOffset); + } + } + + return SCE_OK; } int PS4_SYSV_ABI sceRtcSetConf() { @@ -722,22 +833,22 @@ int PS4_SYSV_ABI sceRtcSetConf() { return ORBIS_OK; } -int PS4_SYSV_ABI sceRtcSetCurrentAdNetworkTick() { +int PS4_SYSV_ABI sceRtcSetCurrentAdNetworkTick(OrbisRtcTick* pTick) { LOG_ERROR(Lib_Rtc, "(STUBBED) called"); return ORBIS_OK; } -int PS4_SYSV_ABI sceRtcSetCurrentDebugNetworkTick() { +int PS4_SYSV_ABI sceRtcSetCurrentDebugNetworkTick(OrbisRtcTick* pTick) { LOG_ERROR(Lib_Rtc, "(STUBBED) called"); return ORBIS_OK; } -int PS4_SYSV_ABI sceRtcSetCurrentNetworkTick() { +int PS4_SYSV_ABI sceRtcSetCurrentNetworkTick(OrbisRtcTick* pTick) { LOG_ERROR(Lib_Rtc, "(STUBBED) called"); return ORBIS_OK; } -int PS4_SYSV_ABI sceRtcSetCurrentTick() { +int PS4_SYSV_ABI sceRtcSetCurrentTick(OrbisRtcTick* pTick) { LOG_ERROR(Lib_Rtc, "(STUBBED) called"); return ORBIS_OK; } diff --git a/src/core/libraries/rtc/rtc.h b/src/core/libraries/rtc/rtc.h index d71998635..c41040863 100644 --- a/src/core/libraries/rtc/rtc.h +++ b/src/core/libraries/rtc/rtc.h @@ -68,10 +68,10 @@ int PS4_SYSV_ABI sceRtcIsLeapYear(int yearInt); int PS4_SYSV_ABI sceRtcParseDateTime(OrbisRtcTick* pTickUtc, const char* pszDateTime); int PS4_SYSV_ABI sceRtcParseRFC3339(OrbisRtcTick* pTickUtc, const char* pszDateTime); int PS4_SYSV_ABI sceRtcSetConf(); -int PS4_SYSV_ABI sceRtcSetCurrentAdNetworkTick(); -int PS4_SYSV_ABI sceRtcSetCurrentDebugNetworkTick(); -int PS4_SYSV_ABI sceRtcSetCurrentNetworkTick(); -int PS4_SYSV_ABI sceRtcSetCurrentTick(); +int PS4_SYSV_ABI sceRtcSetCurrentAdNetworkTick(OrbisRtcTick* pTick); +int PS4_SYSV_ABI sceRtcSetCurrentDebugNetworkTick(OrbisRtcTick* pTick); +int PS4_SYSV_ABI sceRtcSetCurrentNetworkTick(OrbisRtcTick* pTick); +int PS4_SYSV_ABI sceRtcSetCurrentTick(OrbisRtcTick* pTick); int PS4_SYSV_ABI sceRtcSetDosTime(OrbisRtcDateTime* pTime, u32 dosTime); int PS4_SYSV_ABI sceRtcSetTick(OrbisRtcDateTime* pTime, OrbisRtcTick* pTick); int PS4_SYSV_ABI sceRtcSetTime_t(OrbisRtcDateTime* pTime, time_t llTime);