diff --git a/src/core/core.cpp b/src/core/core.cpp
index 81e8cc338a..fde2ccc096 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -40,6 +40,7 @@
 #include "core/hle/service/lm/manager.h"
 #include "core/hle/service/service.h"
 #include "core/hle/service/sm/sm.h"
+#include "core/hle/service/time/time_manager.h"
 #include "core/loader/loader.h"
 #include "core/memory.h"
 #include "core/memory/cheat_engine.h"
@@ -121,7 +122,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
 struct System::Impl {
     explicit Impl(System& system)
         : kernel{system}, fs_controller{system}, memory{system},
-          cpu_manager{system}, reporter{system}, applet_manager{system} {}
+          cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {}
 
     ResultStatus Run() {
         status = ResultStatus::Success;
@@ -189,6 +190,9 @@ struct System::Impl {
             return ResultStatus::ErrorVideoCore;
         }
 
+        // Initialize time manager, which must happen after kernel is created
+        time_manager.Initialize();
+
         is_powered_on = true;
         exit_lock = false;
 
@@ -387,6 +391,7 @@ struct System::Impl {
     /// Service State
     Service::Glue::ARPManager arp_manager;
     Service::LM::Manager lm_manager{reporter};
+    Service::Time::TimeManager time_manager;
 
     /// Service manager
     std::shared_ptr<Service::SM::ServiceManager> service_manager;
@@ -717,6 +722,14 @@ const Service::LM::Manager& System::GetLogManager() const {
     return impl->lm_manager;
 }
 
+Service::Time::TimeManager& System::GetTimeManager() {
+    return impl->time_manager;
+}
+
+const Service::Time::TimeManager& System::GetTimeManager() const {
+    return impl->time_manager;
+}
+
 void System::SetExitLock(bool locked) {
     impl->exit_lock = locked;
 }
diff --git a/src/core/core.h b/src/core/core.h
index 27efe30bb4..6db896bae0 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -69,6 +69,10 @@ namespace SM {
 class ServiceManager;
 } // namespace SM
 
+namespace Time {
+class TimeManager;
+} // namespace Time
+
 } // namespace Service
 
 namespace Tegra {
@@ -361,6 +365,10 @@ public:
 
     const Service::LM::Manager& GetLogManager() const;
 
+    Service::Time::TimeManager& GetTimeManager();
+
+    const Service::Time::TimeManager& GetTimeManager() const;
+
     void SetExitLock(bool locked);
 
     bool GetExitLock() const;
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index ee4fa4b485..7d0474e0b9 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -10,6 +10,7 @@
 #include "core/hle/ipc_helpers.h"
 #include "core/hle/kernel/client_port.h"
 #include "core/hle/kernel/client_session.h"
+#include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/scheduler.h"
 #include "core/hle/service/time/interface.h"
 #include "core/hle/service/time/time.h"
@@ -125,7 +126,7 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal(
     Kernel::Thread* thread, Clock::SystemClockContext user_context,
     Clock::SystemClockContext network_context, u8 type, Clock::ClockSnapshot& clock_snapshot) {
 
-    auto& time_manager{module->GetTimeManager()};
+    auto& time_manager{system.GetTimeManager()};
 
     clock_snapshot.is_automatic_correction_enabled =
         time_manager.GetStandardUserSystemClockCore().IsAutomaticCorrectionEnabled();
@@ -182,7 +183,7 @@ void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ct
     LOG_DEBUG(Service_Time, "called");
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardUserSystemClockCore(),
+    rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardUserSystemClockCore(),
                                       system);
 }
 
@@ -190,7 +191,7 @@ void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext&
     LOG_DEBUG(Service_Time, "called");
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardNetworkSystemClockCore(),
+    rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardNetworkSystemClockCore(),
                                       system);
 }
 
@@ -198,29 +199,28 @@ void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) {
     LOG_DEBUG(Service_Time, "called");
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushIpcInterface<ISteadyClock>(module->GetTimeManager().GetStandardSteadyClockCore(),
-                                      system);
+    rb.PushIpcInterface<ISteadyClock>(system.GetTimeManager().GetStandardSteadyClockCore(), system);
 }
 
 void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) {
     LOG_DEBUG(Service_Time, "called");
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushIpcInterface<ITimeZoneService>(module->GetTimeManager().GetTimeZoneContentManager());
+    rb.PushIpcInterface<ITimeZoneService>(system.GetTimeManager().GetTimeZoneContentManager());
 }
 
 void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) {
     LOG_DEBUG(Service_Time, "called");
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardLocalSystemClockCore(),
+    rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardLocalSystemClockCore(),
                                       system);
 }
 
 void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient(
     Kernel::HLERequestContext& ctx) {
     LOG_DEBUG(Service_Time, "called");
-    auto& clock_core{module->GetTimeManager().GetStandardNetworkSystemClockCore()};
+    auto& clock_core{system.GetTimeManager().GetStandardNetworkSystemClockCore()};
     IPC::ResponseBuilder rb{ctx, 3};
     rb.Push(RESULT_SUCCESS);
     rb.Push<u32>(clock_core.IsStandardNetworkSystemClockAccuracySufficient(system));
@@ -229,7 +229,7 @@ void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient(
 void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx) {
     LOG_DEBUG(Service_Time, "called");
 
-    auto& steady_clock_core{module->GetTimeManager().GetStandardSteadyClockCore()};
+    auto& steady_clock_core{system.GetTimeManager().GetStandardSteadyClockCore()};
     if (!steady_clock_core.IsInitialized()) {
         IPC::ResponseBuilder rb{ctx, 2};
         rb.Push(ERROR_UNINITIALIZED_CLOCK);
@@ -262,8 +262,8 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
 
     Clock::SystemClockContext user_context{};
     if (const ResultCode result{
-            module->GetTimeManager().GetStandardUserSystemClockCore().GetClockContext(
-                system, user_context)};
+            system.GetTimeManager().GetStandardUserSystemClockCore().GetClockContext(system,
+                                                                                     user_context)};
         result.IsError()) {
         IPC::ResponseBuilder rb{ctx, 2};
         rb.Push(result);
@@ -271,7 +271,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
     }
     Clock::SystemClockContext network_context{};
     if (const ResultCode result{
-            module->GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext(
+            system.GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext(
                 system, network_context)};
         result.IsError()) {
         IPC::ResponseBuilder rb{ctx, 2};
@@ -372,7 +372,7 @@ void Module::Interface::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& c
     LOG_DEBUG(Service_Time, "called");
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushCopyObjects(module->GetTimeManager().GetSharedMemory().GetSharedMemoryHolder());
+    rb.PushCopyObjects(SharedFrom(&system.Kernel().GetTimeSharedMem()));
 }
 
 Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name)
@@ -381,7 +381,7 @@ Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& syste
 Module::Interface::~Interface() = default;
 
 void InstallInterfaces(Core::System& system) {
-    auto module{std::make_shared<Module>(system)};
+    auto module{std::make_shared<Module>()};
     std::make_shared<Time>(module, system, "time:a")->InstallAsService(system.ServiceManager());
     std::make_shared<Time>(module, system, "time:s")->InstallAsService(system.ServiceManager());
     std::make_shared<Time>(module, system, "time:u")->InstallAsService(system.ServiceManager());
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h
index 41f3002e9c..49f4aac0a6 100644
--- a/src/core/hle/service/time/time.h
+++ b/src/core/hle/service/time/time.h
@@ -16,7 +16,7 @@ namespace Service::Time {
 
 class Module final {
 public:
-    Module(Core::System& system) : time_manager{system} {}
+    Module() = default;
 
     class Interface : public ServiceFramework<Interface> {
     public:
@@ -46,13 +46,6 @@ public:
         std::shared_ptr<Module> module;
         Core::System& system;
     };
-
-    TimeManager& GetTimeManager() {
-        return time_manager;
-    }
-
-private:
-    TimeManager time_manager;
 };
 
 /// Registers all Time services with the specified service manager.
diff --git a/src/core/hle/service/time/time_manager.cpp b/src/core/hle/service/time/time_manager.cpp
index b4dfe45e5e..858623e2bd 100644
--- a/src/core/hle/service/time/time_manager.cpp
+++ b/src/core/hle/service/time/time_manager.cpp
@@ -22,7 +22,277 @@ static std::chrono::seconds GetSecondsSinceEpoch() {
            Settings::values.custom_rtc_differential;
 }
 
-static s64 GetExternalTimeZoneOffset() {
+static s64 GetExternalRtcValue() {
+    return GetSecondsSinceEpoch().count() + TimeManager::GetExternalTimeZoneOffset();
+}
+
+struct TimeManager::Impl final {
+    explicit Impl(Core::System& system)
+        : shared_memory{system}, standard_local_system_clock_core{standard_steady_clock_core},
+          standard_network_system_clock_core{standard_steady_clock_core},
+          standard_user_system_clock_core{standard_local_system_clock_core,
+                                          standard_network_system_clock_core, system},
+          ephemeral_network_system_clock_core{tick_based_steady_clock_core},
+          local_system_clock_context_writer{
+              std::make_shared<Clock::LocalSystemClockContextWriter>(shared_memory)},
+          network_system_clock_context_writer{
+              std::make_shared<Clock::NetworkSystemClockContextWriter>(shared_memory)},
+          ephemeral_network_system_clock_context_writer{
+              std::make_shared<Clock::EphemeralNetworkSystemClockContextWriter>()},
+          time_zone_content_manager{system} {
+
+        const auto system_time{Clock::TimeSpanType::FromSeconds(GetExternalRtcValue())};
+        SetupStandardSteadyClock(system, Common::UUID::Generate(), system_time, {}, {});
+        SetupStandardLocalSystemClock(system, {}, system_time.ToSeconds());
+        SetupStandardNetworkSystemClock({}, standard_network_clock_accuracy);
+        SetupStandardUserSystemClock(system, {}, Clock::SteadyClockTimePoint::GetRandom());
+        SetupEphemeralNetworkSystemClock();
+    }
+
+    ~Impl() = default;
+
+    Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() {
+        return standard_steady_clock_core;
+    }
+
+    const Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() const {
+        return standard_steady_clock_core;
+    }
+
+    Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() {
+        return standard_local_system_clock_core;
+    }
+
+    const Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() const {
+        return standard_local_system_clock_core;
+    }
+
+    Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() {
+        return standard_network_system_clock_core;
+    }
+
+    const Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() const {
+        return standard_network_system_clock_core;
+    }
+
+    Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() {
+        return standard_user_system_clock_core;
+    }
+
+    const Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() const {
+        return standard_user_system_clock_core;
+    }
+
+    TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() {
+        return time_zone_content_manager;
+    }
+
+    const TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() const {
+        return time_zone_content_manager;
+    }
+
+    SharedMemory& GetSharedMemory() {
+        return shared_memory;
+    }
+
+    const SharedMemory& GetSharedMemory() const {
+        return shared_memory;
+    }
+
+    void SetupTimeZoneManager(std::string location_name,
+                              Clock::SteadyClockTimePoint time_zone_updated_time_point,
+                              std::size_t total_location_name_count, u128 time_zone_rule_version,
+                              FileSys::VirtualFile& vfs_file) {
+        if (time_zone_content_manager.GetTimeZoneManager().SetDeviceLocationNameWithTimeZoneRule(
+                location_name, vfs_file) != RESULT_SUCCESS) {
+            UNREACHABLE();
+            return;
+        }
+
+        time_zone_content_manager.GetTimeZoneManager().SetUpdatedTime(time_zone_updated_time_point);
+        time_zone_content_manager.GetTimeZoneManager().SetTotalLocationNameCount(
+            total_location_name_count);
+        time_zone_content_manager.GetTimeZoneManager().SetTimeZoneRuleVersion(
+            time_zone_rule_version);
+        time_zone_content_manager.GetTimeZoneManager().MarkAsInitialized();
+    }
+
+    static s64 GetExternalTimeZoneOffset() {
+        // With "auto" timezone setting, we use the external system's timezone offset
+        if (Settings::GetTimeZoneString() == "auto") {
+            return Common::TimeZone::GetCurrentOffsetSeconds().count();
+        }
+        return 0;
+    }
+
+    void SetupStandardSteadyClock(Core::System& system, Common::UUID clock_source_id,
+                                  Clock::TimeSpanType setup_value,
+                                  Clock::TimeSpanType internal_offset, bool is_rtc_reset_detected) {
+        standard_steady_clock_core.SetClockSourceId(clock_source_id);
+        standard_steady_clock_core.SetSetupValue(setup_value);
+        standard_steady_clock_core.SetInternalOffset(internal_offset);
+        standard_steady_clock_core.MarkAsInitialized();
+
+        const auto current_time_point{standard_steady_clock_core.GetCurrentRawTimePoint(system)};
+        shared_memory.SetupStandardSteadyClock(system, clock_source_id, current_time_point);
+    }
+
+    void SetupStandardLocalSystemClock(Core::System& system,
+                                       Clock::SystemClockContext clock_context, s64 posix_time) {
+        standard_local_system_clock_core.SetUpdateCallbackInstance(
+            local_system_clock_context_writer);
+
+        const auto current_time_point{
+            standard_local_system_clock_core.GetSteadyClockCore().GetCurrentTimePoint(system)};
+        if (current_time_point.clock_source_id == clock_context.steady_time_point.clock_source_id) {
+            standard_local_system_clock_core.SetSystemClockContext(clock_context);
+        } else {
+            if (standard_local_system_clock_core.SetCurrentTime(system, posix_time) !=
+                RESULT_SUCCESS) {
+                UNREACHABLE();
+                return;
+            }
+        }
+
+        standard_local_system_clock_core.MarkAsInitialized();
+    }
+
+    void SetupStandardNetworkSystemClock(Clock::SystemClockContext clock_context,
+                                         Clock::TimeSpanType sufficient_accuracy) {
+        standard_network_system_clock_core.SetUpdateCallbackInstance(
+            network_system_clock_context_writer);
+
+        if (standard_network_system_clock_core.SetSystemClockContext(clock_context) !=
+            RESULT_SUCCESS) {
+            UNREACHABLE();
+            return;
+        }
+
+        standard_network_system_clock_core.SetStandardNetworkClockSufficientAccuracy(
+            sufficient_accuracy);
+        standard_network_system_clock_core.MarkAsInitialized();
+    }
+
+    void SetupStandardUserSystemClock(Core::System& system, bool is_automatic_correction_enabled,
+                                      Clock::SteadyClockTimePoint steady_clock_time_point) {
+        if (standard_user_system_clock_core.SetAutomaticCorrectionEnabled(
+                system, is_automatic_correction_enabled) != RESULT_SUCCESS) {
+            UNREACHABLE();
+            return;
+        }
+
+        standard_user_system_clock_core.SetAutomaticCorrectionUpdatedTime(steady_clock_time_point);
+        standard_user_system_clock_core.MarkAsInitialized();
+        shared_memory.SetAutomaticCorrectionEnabled(is_automatic_correction_enabled);
+    }
+
+    void SetupEphemeralNetworkSystemClock() {
+        ephemeral_network_system_clock_core.SetUpdateCallbackInstance(
+            ephemeral_network_system_clock_context_writer);
+        ephemeral_network_system_clock_core.MarkAsInitialized();
+    }
+
+    void UpdateLocalSystemClockTime(Core::System& system, s64 posix_time) {
+        const auto timespan{Service::Time::Clock::TimeSpanType::FromSeconds(posix_time)};
+        if (GetStandardLocalSystemClockCore()
+                .SetCurrentTime(system, timespan.ToSeconds())
+                .IsError()) {
+            UNREACHABLE();
+            return;
+        }
+    }
+
+    SharedMemory shared_memory;
+
+    Clock::StandardSteadyClockCore standard_steady_clock_core;
+    Clock::TickBasedSteadyClockCore tick_based_steady_clock_core;
+    Clock::StandardLocalSystemClockCore standard_local_system_clock_core;
+    Clock::StandardNetworkSystemClockCore standard_network_system_clock_core;
+    Clock::StandardUserSystemClockCore standard_user_system_clock_core;
+    Clock::EphemeralNetworkSystemClockCore ephemeral_network_system_clock_core;
+
+    std::shared_ptr<Clock::LocalSystemClockContextWriter> local_system_clock_context_writer;
+    std::shared_ptr<Clock::NetworkSystemClockContextWriter> network_system_clock_context_writer;
+    std::shared_ptr<Clock::EphemeralNetworkSystemClockContextWriter>
+        ephemeral_network_system_clock_context_writer;
+
+    TimeZone::TimeZoneContentManager time_zone_content_manager;
+};
+
+TimeManager::TimeManager(Core::System& system) : system{system} {}
+
+TimeManager::~TimeManager() = default;
+
+void TimeManager::Initialize() {
+    impl = std::make_unique<Impl>(system);
+
+    // Time zones can only be initialized after impl is valid
+    impl->time_zone_content_manager.Initialize(*this);
+}
+
+Clock::StandardSteadyClockCore& TimeManager::GetStandardSteadyClockCore() {
+    return impl->standard_steady_clock_core;
+}
+
+const Clock::StandardSteadyClockCore& TimeManager::GetStandardSteadyClockCore() const {
+    return impl->standard_steady_clock_core;
+}
+
+Clock::StandardLocalSystemClockCore& TimeManager::GetStandardLocalSystemClockCore() {
+    return impl->standard_local_system_clock_core;
+}
+
+const Clock::StandardLocalSystemClockCore& TimeManager::GetStandardLocalSystemClockCore() const {
+    return impl->standard_local_system_clock_core;
+}
+
+Clock::StandardNetworkSystemClockCore& TimeManager::GetStandardNetworkSystemClockCore() {
+    return impl->standard_network_system_clock_core;
+}
+
+const Clock::StandardNetworkSystemClockCore& TimeManager::GetStandardNetworkSystemClockCore()
+    const {
+    return impl->standard_network_system_clock_core;
+}
+
+Clock::StandardUserSystemClockCore& TimeManager::GetStandardUserSystemClockCore() {
+    return impl->standard_user_system_clock_core;
+}
+
+const Clock::StandardUserSystemClockCore& TimeManager::GetStandardUserSystemClockCore() const {
+    return impl->standard_user_system_clock_core;
+}
+
+TimeZone::TimeZoneContentManager& TimeManager::GetTimeZoneContentManager() {
+    return impl->time_zone_content_manager;
+}
+
+const TimeZone::TimeZoneContentManager& TimeManager::GetTimeZoneContentManager() const {
+    return impl->time_zone_content_manager;
+}
+
+SharedMemory& TimeManager::GetSharedMemory() {
+    return impl->shared_memory;
+}
+
+const SharedMemory& TimeManager::GetSharedMemory() const {
+    return impl->shared_memory;
+}
+
+void TimeManager::UpdateLocalSystemClockTime(s64 posix_time) {
+    impl->UpdateLocalSystemClockTime(system, posix_time);
+}
+
+void TimeManager::SetupTimeZoneManager(std::string location_name,
+                                       Clock::SteadyClockTimePoint time_zone_updated_time_point,
+                                       std::size_t total_location_name_count,
+                                       u128 time_zone_rule_version,
+                                       FileSys::VirtualFile& vfs_file) {
+    impl->SetupTimeZoneManager(location_name, time_zone_updated_time_point,
+                               total_location_name_count, time_zone_rule_version, vfs_file);
+}
+
+/*static*/ s64 TimeManager::GetExternalTimeZoneOffset() {
     // With "auto" timezone setting, we use the external system's timezone offset
     if (Settings::GetTimeZoneString() == "auto") {
         return Common::TimeZone::GetCurrentOffsetSeconds().count();
@@ -30,117 +300,4 @@ static s64 GetExternalTimeZoneOffset() {
     return 0;
 }
 
-static s64 GetExternalRtcValue() {
-    return GetSecondsSinceEpoch().count() + GetExternalTimeZoneOffset();
-}
-
-TimeManager::TimeManager(Core::System& system)
-    : shared_memory{system}, standard_local_system_clock_core{standard_steady_clock_core},
-      standard_network_system_clock_core{standard_steady_clock_core},
-      standard_user_system_clock_core{standard_local_system_clock_core,
-                                      standard_network_system_clock_core, system},
-      ephemeral_network_system_clock_core{tick_based_steady_clock_core},
-      local_system_clock_context_writer{
-          std::make_shared<Clock::LocalSystemClockContextWriter>(shared_memory)},
-      network_system_clock_context_writer{
-          std::make_shared<Clock::NetworkSystemClockContextWriter>(shared_memory)},
-      ephemeral_network_system_clock_context_writer{
-          std::make_shared<Clock::EphemeralNetworkSystemClockContextWriter>()},
-      time_zone_content_manager{*this, system} {
-
-    const auto system_time{Clock::TimeSpanType::FromSeconds(GetExternalRtcValue())};
-    SetupStandardSteadyClock(system, Common::UUID::Generate(), system_time, {}, {});
-    SetupStandardLocalSystemClock(system, {}, system_time.ToSeconds());
-    SetupStandardNetworkSystemClock({}, standard_network_clock_accuracy);
-    SetupStandardUserSystemClock(system, {}, Clock::SteadyClockTimePoint::GetRandom());
-    SetupEphemeralNetworkSystemClock();
-}
-
-TimeManager::~TimeManager() = default;
-
-void TimeManager::SetupTimeZoneManager(std::string location_name,
-                                       Clock::SteadyClockTimePoint time_zone_updated_time_point,
-                                       std::size_t total_location_name_count,
-                                       u128 time_zone_rule_version,
-                                       FileSys::VirtualFile& vfs_file) {
-    if (time_zone_content_manager.GetTimeZoneManager().SetDeviceLocationNameWithTimeZoneRule(
-            location_name, vfs_file) != RESULT_SUCCESS) {
-        UNREACHABLE();
-        return;
-    }
-
-    time_zone_content_manager.GetTimeZoneManager().SetUpdatedTime(time_zone_updated_time_point);
-    time_zone_content_manager.GetTimeZoneManager().SetTotalLocationNameCount(
-        total_location_name_count);
-    time_zone_content_manager.GetTimeZoneManager().SetTimeZoneRuleVersion(time_zone_rule_version);
-    time_zone_content_manager.GetTimeZoneManager().MarkAsInitialized();
-}
-
-void TimeManager::SetupStandardSteadyClock(Core::System& system, Common::UUID clock_source_id,
-                                           Clock::TimeSpanType setup_value,
-                                           Clock::TimeSpanType internal_offset,
-                                           bool is_rtc_reset_detected) {
-    standard_steady_clock_core.SetClockSourceId(clock_source_id);
-    standard_steady_clock_core.SetSetupValue(setup_value);
-    standard_steady_clock_core.SetInternalOffset(internal_offset);
-    standard_steady_clock_core.MarkAsInitialized();
-
-    const auto current_time_point{standard_steady_clock_core.GetCurrentRawTimePoint(system)};
-    shared_memory.SetupStandardSteadyClock(system, clock_source_id, current_time_point);
-}
-
-void TimeManager::SetupStandardLocalSystemClock(Core::System& system,
-                                                Clock::SystemClockContext clock_context,
-                                                s64 posix_time) {
-    standard_local_system_clock_core.SetUpdateCallbackInstance(local_system_clock_context_writer);
-
-    const auto current_time_point{
-        standard_local_system_clock_core.GetSteadyClockCore().GetCurrentTimePoint(system)};
-    if (current_time_point.clock_source_id == clock_context.steady_time_point.clock_source_id) {
-        standard_local_system_clock_core.SetSystemClockContext(clock_context);
-    } else {
-        if (standard_local_system_clock_core.SetCurrentTime(system, posix_time) != RESULT_SUCCESS) {
-            UNREACHABLE();
-            return;
-        }
-    }
-
-    standard_local_system_clock_core.MarkAsInitialized();
-}
-
-void TimeManager::SetupStandardNetworkSystemClock(Clock::SystemClockContext clock_context,
-                                                  Clock::TimeSpanType sufficient_accuracy) {
-    standard_network_system_clock_core.SetUpdateCallbackInstance(
-        network_system_clock_context_writer);
-
-    if (standard_network_system_clock_core.SetSystemClockContext(clock_context) != RESULT_SUCCESS) {
-        UNREACHABLE();
-        return;
-    }
-
-    standard_network_system_clock_core.SetStandardNetworkClockSufficientAccuracy(
-        sufficient_accuracy);
-    standard_network_system_clock_core.MarkAsInitialized();
-}
-
-void TimeManager::SetupStandardUserSystemClock(
-    Core::System& system, bool is_automatic_correction_enabled,
-    Clock::SteadyClockTimePoint steady_clock_time_point) {
-    if (standard_user_system_clock_core.SetAutomaticCorrectionEnabled(
-            system, is_automatic_correction_enabled) != RESULT_SUCCESS) {
-        UNREACHABLE();
-        return;
-    }
-
-    standard_user_system_clock_core.SetAutomaticCorrectionUpdatedTime(steady_clock_time_point);
-    standard_user_system_clock_core.MarkAsInitialized();
-    shared_memory.SetAutomaticCorrectionEnabled(is_automatic_correction_enabled);
-}
-
-void TimeManager::SetupEphemeralNetworkSystemClock() {
-    ephemeral_network_system_clock_core.SetUpdateCallbackInstance(
-        ephemeral_network_system_clock_context_writer);
-    ephemeral_network_system_clock_core.MarkAsInitialized();
-}
-
 } // namespace Service::Time
diff --git a/src/core/hle/service/time/time_manager.h b/src/core/hle/service/time/time_manager.h
index 8e65f0d221..993c7c2886 100644
--- a/src/core/hle/service/time/time_manager.h
+++ b/src/core/hle/service/time/time_manager.h
@@ -5,6 +5,7 @@
 #pragma once
 
 #include "common/common_types.h"
+#include "common/time_zone.h"
 #include "core/file_sys/vfs_types.h"
 #include "core/hle/service/time/clock_types.h"
 #include "core/hle/service/time/ephemeral_network_system_clock_core.h"
@@ -32,86 +33,46 @@ public:
     explicit TimeManager(Core::System& system);
     ~TimeManager();
 
-    Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() {
-        return standard_steady_clock_core;
-    }
+    void Initialize();
 
-    const Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() const {
-        return standard_steady_clock_core;
-    }
+    Clock::StandardSteadyClockCore& GetStandardSteadyClockCore();
 
-    Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() {
-        return standard_local_system_clock_core;
-    }
+    const Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() const;
 
-    const Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() const {
-        return standard_local_system_clock_core;
-    }
+    Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore();
 
-    Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() {
-        return standard_network_system_clock_core;
-    }
+    const Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() const;
 
-    const Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() const {
-        return standard_network_system_clock_core;
-    }
+    Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore();
 
-    Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() {
-        return standard_user_system_clock_core;
-    }
+    const Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() const;
 
-    const Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() const {
-        return standard_user_system_clock_core;
-    }
+    Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore();
 
-    TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() {
-        return time_zone_content_manager;
-    }
+    const Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() const;
 
-    const TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() const {
-        return time_zone_content_manager;
-    }
+    TimeZone::TimeZoneContentManager& GetTimeZoneContentManager();
 
-    SharedMemory& GetSharedMemory() {
-        return shared_memory;
-    }
+    const TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() const;
 
-    const SharedMemory& GetSharedMemory() const {
-        return shared_memory;
-    }
+    void UpdateLocalSystemClockTime(s64 posix_time);
+
+    SharedMemory& GetSharedMemory();
+
+    const SharedMemory& GetSharedMemory() const;
 
     void SetupTimeZoneManager(std::string location_name,
                               Clock::SteadyClockTimePoint time_zone_updated_time_point,
                               std::size_t total_location_name_count, u128 time_zone_rule_version,
                               FileSys::VirtualFile& vfs_file);
 
+    static s64 GetExternalTimeZoneOffset();
+
 private:
-    void SetupStandardSteadyClock(Core::System& system, Common::UUID clock_source_id,
-                                  Clock::TimeSpanType setup_value,
-                                  Clock::TimeSpanType internal_offset, bool is_rtc_reset_detected);
-    void SetupStandardLocalSystemClock(Core::System& system,
-                                       Clock::SystemClockContext clock_context, s64 posix_time);
-    void SetupStandardNetworkSystemClock(Clock::SystemClockContext clock_context,
-                                         Clock::TimeSpanType sufficient_accuracy);
-    void SetupStandardUserSystemClock(Core::System& system, bool is_automatic_correction_enabled,
-                                      Clock::SteadyClockTimePoint steady_clock_time_point);
-    void SetupEphemeralNetworkSystemClock();
+    Core::System& system;
 
-    SharedMemory shared_memory;
-
-    Clock::StandardSteadyClockCore standard_steady_clock_core;
-    Clock::TickBasedSteadyClockCore tick_based_steady_clock_core;
-    Clock::StandardLocalSystemClockCore standard_local_system_clock_core;
-    Clock::StandardNetworkSystemClockCore standard_network_system_clock_core;
-    Clock::StandardUserSystemClockCore standard_user_system_clock_core;
-    Clock::EphemeralNetworkSystemClockCore ephemeral_network_system_clock_core;
-
-    std::shared_ptr<Clock::LocalSystemClockContextWriter> local_system_clock_context_writer;
-    std::shared_ptr<Clock::NetworkSystemClockContextWriter> network_system_clock_context_writer;
-    std::shared_ptr<Clock::EphemeralNetworkSystemClockContextWriter>
-        ephemeral_network_system_clock_context_writer;
-
-    TimeZone::TimeZoneContentManager time_zone_content_manager;
+    struct Impl;
+    std::unique_ptr<Impl> impl;
 };
 
 } // namespace Service::Time
diff --git a/src/core/hle/service/time/time_zone_content_manager.cpp b/src/core/hle/service/time/time_zone_content_manager.cpp
index 320672add6..4177d0a414 100644
--- a/src/core/hle/service/time/time_zone_content_manager.cpp
+++ b/src/core/hle/service/time/time_zone_content_manager.cpp
@@ -68,9 +68,10 @@ static std::vector<std::string> BuildLocationNameCache(Core::System& system) {
     return location_name_cache;
 }
 
-TimeZoneContentManager::TimeZoneContentManager(TimeManager& time_manager, Core::System& system)
-    : system{system}, location_name_cache{BuildLocationNameCache(system)} {
+TimeZoneContentManager::TimeZoneContentManager(Core::System& system)
+    : system{system}, location_name_cache{BuildLocationNameCache(system)} {}
 
+void TimeZoneContentManager::Initialize(TimeManager& time_manager) {
     std::string location_name;
     const auto timezone_setting = Settings::GetTimeZoneString();
     if (timezone_setting == "auto" || timezone_setting == "default") {
diff --git a/src/core/hle/service/time/time_zone_content_manager.h b/src/core/hle/service/time/time_zone_content_manager.h
index 4f302c3b98..02bbbadaca 100644
--- a/src/core/hle/service/time/time_zone_content_manager.h
+++ b/src/core/hle/service/time/time_zone_content_manager.h
@@ -21,7 +21,9 @@ namespace Service::Time::TimeZone {
 
 class TimeZoneContentManager final {
 public:
-    TimeZoneContentManager(TimeManager& time_manager, Core::System& system);
+    TimeZoneContentManager(Core::System& system);
+
+    void Initialize(TimeManager& time_manager);
 
     TimeZoneManager& GetTimeZoneManager() {
         return time_zone_manager;
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index 9ad43ed8ff..5e8e201dc8 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -12,6 +12,7 @@
 #include "common/assert.h"
 #include "common/file_util.h"
 #include "core/core.h"
+#include "core/hle/service/time/time.h"
 #include "core/settings.h"
 #include "ui_configure_system.h"
 #include "yuzu/configuration/configuration_shared.h"
@@ -104,6 +105,22 @@ void ConfigureSystem::SetConfiguration() {
 void ConfigureSystem::ReadSystemSettings() {}
 
 void ConfigureSystem::ApplyConfiguration() {
+    // Allow setting custom RTC even if system is powered on, to allow in-game time to be fast
+    // forwared
+    if (Settings::values.custom_rtc.UsingGlobal()) {
+        if (ui->custom_rtc_checkbox->isChecked()) {
+            Settings::values.custom_rtc.SetValue(
+                std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
+            if (Core::System::GetInstance().IsPoweredOn()) {
+                const s64 posix_time{Settings::values.custom_rtc.GetValue()->count() +
+                                     Service::Time::TimeManager::GetExternalTimeZoneOffset()};
+                Core::System::GetInstance().GetTimeManager().UpdateLocalSystemClockTime(posix_time);
+            }
+        } else {
+            Settings::values.custom_rtc.SetValue(std::nullopt);
+        }
+    }
+
     if (!enabled) {
         return;
     }
@@ -131,15 +148,6 @@ void ConfigureSystem::ApplyConfiguration() {
                 Settings::values.rng_seed.SetValue(std::nullopt);
             }
         }
-
-        if (Settings::values.custom_rtc.UsingGlobal()) {
-            if (ui->custom_rtc_checkbox->isChecked()) {
-                Settings::values.custom_rtc.SetValue(
-                    std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
-            } else {
-                Settings::values.custom_rtc.SetValue(std::nullopt);
-            }
-        }
     } else {
         ConfigurationShared::ApplyPerGameSetting(&Settings::values.language_index,
                                                  ui->combo_language);