如何使用 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)
。)
OffsetDateTime
s 明确表示一个时间点,因此您可以 ToInstant
并将开始和结束时刻与当前时刻进行比较。 Instant
s 具有可比性。
Instant now = SystemClock.Instance.GetCurrentInstant();
Instant startInstant = StartTime.ToInstant();
Instant endInstant = EndTime.ToInstant();
return startInstant < now && now < endInstant;
我需要设置这样一个视图模型的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)
。)
OffsetDateTime
s 明确表示一个时间点,因此您可以 ToInstant
并将开始和结束时刻与当前时刻进行比较。 Instant
s 具有可比性。
Instant now = SystemClock.Instance.GetCurrentInstant();
Instant startInstant = StartTime.ToInstant();
Instant endInstant = EndTime.ToInstant();
return startInstant < now && now < endInstant;