Table of Contents

Persistence and schedule-zone conversions — PrimeTime (NodaTime), testing

These tests use PrimeTestClock with a fixed DateTimeZone so schedule-zone projections stay deterministic. They also assert NodaDurationBclConversion clamping for delays beyond TimeSpan range.

For the conceptual background, see Persistence and time conversions.

/// <summary>
/// Verifies a fixed <see cref="Instant"/> projects into the virtual clock zone the same way as
/// an in-memory <see cref="ZonedDateTime"/> conversion.
/// </summary>
[Fact]
public void PersistedInstant_ToScheduleZone_MatchesInZoneProjection ()
{
    DateTimeZone zone = DateTimeZoneProviders.Tzdb["America/New_York"];
    Instant persisted = Instant.FromUtc(2025, 7, 4, 15, 30, 0);
    IPrimeTestClock clock = new PrimeTestClock(persisted, zone);
    IPrimeTime time = clock;

    LocalDate expectedDate = persisted.InZone(zone).Date;
    time.ToScheduleLocalDate(persisted).Should().Be(expectedDate);

    LocalTime wallTime = time.ToScheduleLocalTime(persisted);
    LocalTimeOfDay stored = PrimeTimeOfDayConversion.ToLocalTimeOfDay(wallTime);
    PrimeTimeOfDayConversion.ToLocalTime(stored).Should().Be(wallTime);
}

/// <summary>
/// Verifies <see cref="NodaDurationBclConversion.ToTimeSpanForDelay"/> clamps durations beyond
/// BCL <see cref="TimeSpan"/> range to <see cref="TimeSpan.MaxValue"/>.
/// </summary>
[Fact]
public void LargeDuration_ToTimeSpanForDelay_ClampsToMaxValue ()
{
    Duration beyondBclRange = Duration.FromTimeSpan(TimeSpan.MaxValue) + Duration.FromSeconds(1);
    NodaDurationBclConversion.ToTimeSpanForDelay(beyondBclRange).Should().Be(TimeSpan.MaxValue);
}

What to notice

  • ToScheduleLocalDate matches Instant.InZone(zone).Date for the same zone the test clock uses.
  • LocalTimeOfDay preserves wall LocalTime when round-tripping through PrimeTimeOfDayConversion.
  • Delay TimeSpan conversion clamps to TimeSpan.MaxValue for durations larger than BCL can represent.