如何使用 NodaTime 检查 "now" 是否位于两个 OffsetDateTime 对象之间?

How can I check whether "now" is in between two OffsetDateTime objects with NodaTime?

我需要设置这样一个视图模型的IsCurrent字段:

public class SessionVm {
    public OffsetDateTime StartTime { get; set; }
    public OffsetDateTime EndTime { get; set; }
    public string TimezoneId { get; set; }
    public bool IsCurrent {get;}
}

我以为我可以为IsCurrent字段写这样一个getter:

public bool IsCurrent
{
    get
    {
        var currentTimeWithOffset = new OffsetDateTime(LocalDateTime.FromDateTime(DateTime.UtcNow), StartTime.Offset);
        return StartTime < currentTimeWithOffset && currentTimeWithOffset < EndTime;
    }
}

但是,OffsetDateTime 似乎没有实现 IComparable。然后我发现 LocalDateTime 可以并尝试了这个:

public bool IsCurrent
{
    get
    {
        var currentLocalDateTime = SystemClock.Instance.InUtc().GetCurrentLocalDateTime();
        var currentOffsetDateTime = new OffsetDateTime(currentLocalDateTime, StartTime.Offset);
        var currentLocalDateTimeExpectedWithOffsetAdded = currentOffsetDateTime.LocalDateTime;

        var startLocalDateTime = StartTime.LocalDateTime;
        var endLocalDateTime = StartTime.LocalDateTime;
        return startLocalDateTime < currentLocalDateTimeExpectedWithOffsetAdded && currentLocalDateTimeExpectedWithOffsetAdded < endLocalDateTime;
    }
}

然而,currentLocalDateTimeExpectedWithOffsetAdded并不能真正代表我所需要的。来自 OffsetDateTime class 文档 LocalDateTime 字段上方:

/// <summary>
/// Returns the local date and time represented within this offset date and time.
/// </summary>
/// <value>The local date and time represented within this offset date and time.</value>
public LocalDateTime LocalDateTime => new LocalDateTime(Date, TimeOfDay);

显然,我误解了这句话,并认为它会给我带偏移量的日期时间。
你能帮我弄清楚如何获得添加偏移量的 UTC 日期时间对象吗?或者也许有更好的方法来实现 IsCurrent 字段? 提前谢谢你:)

首先,我强烈建议完全删除 DateTime.UtcNow 的使用。相反,请使用 NodaTime 的 IClock 接口。像任何其他依赖项一样注入它,使用 SystemClock.Instance 作为生产实现。对于测试,您可以使用 NodaTime.Testing 包提供的 FakeClock

获得时钟后,调用 IClock.GetCurrentInstant() 找出当前时刻。如果你真的非常非常想使用DateTime.UtcNow,你可以调用Instant.FromDateTimeUtc(DateTime.UtcNow)。但请注意,这是一种更难测试且更少 NodaTime-idiomatic 的方法。

我会将您当前的 OffsetDateTime 值转换为瞬间值,然后您可以执行比较:

public bool IsCurrent
{
    get
    {
        var startInstant = StartTime.ToInstant();
        var endInstant = EndTime.ToInstant();
        var now = clock.GetCurrentInstant();
        return startInstant <= now && now < endInstant;
    }
}

(或者,从两个瞬间创建一个 Interval,并使用 Interval.Contains(Instant)。)

OffsetDateTimes 明确表示一个时间点,因此您可以 ToInstant 并将开始和结束时刻与当前时刻进行比较。 Instants 具有可比性。

Instant now = SystemClock.Instance.GetCurrentInstant();
Instant startInstant = StartTime.ToInstant();
Instant endInstant = EndTime.ToInstant();
return startInstant < now && now < endInstant;