diff --git a/core/libs/prx/libkernel/Time/Time.cpp b/core/libs/prx/libkernel/Time/Time.cpp index da55e9f2002..e029cb67d9d 100644 --- a/core/libs/prx/libkernel/Time/Time.cpp +++ b/core/libs/prx/libkernel/Time/Time.cpp @@ -564,10 +564,10 @@ int APS5_VABI sceKernelClockGettime(KernelClockid clock_id, KernelTimespec* tp) return clock_gettime_nid_postfix(static_cast(clock_id), tp); } -int APS5_VABI sceKernelConvertLocaltimeToUtc(int64_t local_time, int64_t reserved, int64_t* utc_time, KernelTimezone* timezone, int32_t* dst_seconds) { +int APS5_VABI sceKernelConvertLocaltimeToUtc(int64_t local_time, int64_t reserved, int64_t* utc_time, KernelTimesec* timezone, int32_t* dst_seconds) { (void)reserved; if (utc_time != nullptr) *utc_time = local_time; - if (timezone != nullptr) *timezone = {0, 0}; + if (timezone != nullptr) *timezone = {local_time, 0u, 0u}; if (dst_seconds != nullptr) *dst_seconds = 0; return 0; } diff --git a/core/libs/tests/GuestFreebsdClocks.cpp b/core/libs/tests/GuestFreebsdClocks.cpp index 75a69daa613..25be2c623ee 100644 --- a/core/libs/tests/GuestFreebsdClocks.cpp +++ b/core/libs/tests/GuestFreebsdClocks.cpp @@ -1,4 +1,5 @@ #include "SceTypes.hpp" +#include #include #include @@ -10,6 +11,8 @@ int APS5_VABI sceKernelClockGetres(KernelClockid clockId, KernelTimespec* tp); int APS5_VABI sceKernelUsleep_nid_postfix(KernelUseconds microseconds); int APS5_VABI gettimeofday_nid_postfix(KernelTimeval* tv, KernelTimezone* tz); std::int64_t APS5_VABI _Xtime_get_ticks_nid_postfix(); +int APS5_VABI sceKernelConvertLocaltimeToUtc(std::int64_t, std::int64_t, std::int64_t*, KernelTimesec*, std::int32_t*); +int APS5_VABI sceKernelConvertUtcToLocaltime(std::int64_t, std::int64_t*, KernelTimesec*, std::uint64_t*); } static constexpr int SCE_OK = 0; @@ -137,7 +140,35 @@ static void XtimeTicksAreGettimeofdayMicroseconds() { } } +static void CalendarConversionsInitializeTheirState() { + constexpr std::uint64_t sentinel = 0xa5a5a5a5a5a5a5a5ull; + struct GuardedState { + std::uint64_t before; + KernelTimesec state; + std::uint64_t after; + }; + for (const auto seconds : std::array{-86400, 0, 1767225600, 2147483648}) { + GuardedState local{sentinel, {-1, 0xa5a5a5a5u, 0xa5a5a5a5u}, sentinel}; + std::int64_t utc = -1; + std::int32_t dst = -1; + Require(sceKernelConvertLocaltimeToUtc(seconds, 0, &utc, &local.state, &dst) == SCE_OK); + Require(utc == seconds && dst == 0); + Require(local.state.t == seconds && local.state.west_sec == 0 && local.state.dst_sec == 0); + Require(local.before == sentinel && local.after == sentinel); + GuardedState universal{sentinel, {-1, 0xa5a5a5a5u, 0xa5a5a5a5u}, sentinel}; + std::int64_t converted = -1; + std::uint64_t universalDst = sentinel; + Require(sceKernelConvertUtcToLocaltime(utc, &converted, &universal.state, &universalDst) == SCE_OK); + Require(converted == seconds && universalDst == 0); + Require(universal.state.t == seconds && universal.state.west_sec == 0 && universal.state.dst_sec == 0); + Require(universal.before == sentinel && universal.after == sentinel); + } + Require(sceKernelConvertLocaltimeToUtc(0, 0, nullptr, nullptr, nullptr) == SCE_OK); + Require(sceKernelConvertUtcToLocaltime(0, nullptr, nullptr, nullptr) == SCE_OK); +} + int main() { + CalendarConversionsInitializeTheirState(); SecondClockReportsWholeSeconds(); KernelTimespec time{-1, -1};