Skip to content

Add DateTimeOffset support to ITimeSystem #1039

Description

@vbreuss

Problem

ITimeSystem.DateTime (IDateTime) only abstracts System.DateTime — it exposes Now, UtcNow, Today, MinValue, MaxValue, UnixEpoch. There is no seam for System.DateTimeOffset.

DateTimeOffset.Now / DateTimeOffset.UtcNow is a primary "current time" source in modern code (it is the recommended type for timestamps), so code that reads them directly cannot be made deterministic through this library today. The only workaround is new DateTimeOffset(timeSystem.DateTime.UtcNow), which does not reproduce the local-offset semantics of DateTimeOffset.Now.

Proposed API

Add an IDateTimeOffset abstraction and expose it on ITimeSystem:

namespace Testably.Abstractions.TimeSystem;

public interface IDateTimeOffset : ITimeSystemEntity
{
    DateTimeOffset MaxValue { get; }
    DateTimeOffset MinValue { get; }
    DateTimeOffset UnixEpoch { get; }
    DateTimeOffset Now { get; }
    DateTimeOffset UtcNow { get; }
}

public interface ITimeSystem
{
    IDateTime DateTime { get; }
    IDateTimeOffset DateTimeOffset { get; } // new
    // ...existing members
}

Notes / design

  • The mock must be driven by the same ITimeProvider clock that backs IDateTime, so SetTo / AdvanceBy / auto-advance move both consistently. Now should apply the local offset the same way DateTimeMock.Now uses ToLocalTime().
  • MinValue / MaxValue / UnixEpoch should track the corresponding overridable values already present on ITimeProvider (they are DateTime there; convert to DateTimeOffset).
  • Adding a member to the public ITimeSystem interface is a binary-breaking change for anyone who implements it directly (real + mock ship with the package, but third-party implementers would break). Consider whether this warrants a major version bump, or a default-interface-member on TFMs that support it.
  • The On notification handler (INotificationHandler for the time system) may want a matching DateTimeOffsetRead callback for parity with DateTimeRead.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions