Table of Contents

Persistence and schedule-zone conversions — System Clock, production

This scenario projects a persisted UTC DateTimeOffset into the clock’s LocalScheduleTimeZone, yielding BCL DateOnly, TimeOnly, and wall DateTime via DateOnly.ToDateTime(TimeOnly).

For the conceptual background, see Persistence and time conversions.

ServiceCollection services = [];
services.AddPrimeClock();

using ServiceProvider serviceProvider = services.BuildServiceProvider();
IPrimeClock primeClock = serviceProvider.GetRequiredService<IPrimeClock>();
IPrimeTime time = primeClock;

DateTimeOffset persistedUtc = new(2025, 7, 4, 15, 30, 0, TimeSpan.Zero);

DateTimeOffset inScheduleZone = time.ToScheduleDateTimeOffset(persistedUtc);
ScenarioConsole.WriteLine($"Schedule DateTimeOffset: {inScheduleZone:O}");
ScenarioConsole.WriteLine($"Schedule DateOnly: {time.ToScheduleDateOnly(persistedUtc)}");
ScenarioConsole.WriteLine($"Schedule TimeOnly: {time.ToScheduleTimeOnly(persistedUtc)}");

DateOnly scheduleDate = time.ToScheduleDateOnly(persistedUtc);
TimeOnly scheduleTimeOfDay = time.ToScheduleTimeOnly(persistedUtc);
DateTime wallUnspecified = scheduleDate.ToDateTime(scheduleTimeOfDay);
ScenarioConsole.WriteLine($"DateOnly+TimeOnly wall (unspecified kind): {wallUnspecified:O}");

return Task.CompletedTask;

What to notice

  • ToScheduleDateTimeOffset, ToScheduleDateOnly, and ToScheduleTimeOnly align with TimeZoneInfo.ConvertTime for the clock’s schedule zone.
  • Recombining DateOnly + TimeOnly gives an unspecified-kind DateTime representing the wall calendar and clock in that zone (not a UTC instant by itself).