.NET 6: New DateOnly and TimeOnly strcuts
Background and Motivation
.NET 目前有用于处理日期和时间的DateTime
和DateTimeOffset
。但在许多情况下,用户需要处理日期而根本不关心时间部分,也存在需要处理时间而不关心日期部分的场景。当用户试图通过使用DateTime
和DateTimeOffset
来解决这个问题,需要截断他们不需要的部分,并且希望确保剩下的值不受影响。这很容易出错,因为DateTime
和DateTimeOffset
也携带一些与时区相关的内容。
这就是为什么 .NET 6 推出了DateOnly
和TimeOnly
的原因。
Intro
官方介绍:
DateOnly
只关心DateTime
的日期部分TimeOnly
只关心DateTime
的时间部分。DateOnly
适用于生日、周年纪念日和工作日等场景。TimeOnly
适用于定期会议、闹钟和每周营业时间等场景。- 补充了现有的日期/时间类型(
DateTime
,DateTimeOffset
,TimeSpan
,TimeZoneInfo
)。 - 定义在
System
命名空间中,与现有的相关类型一样,由CoreLib中提供。
关于命名,没有直接使用
Date
和Time
作为新API的名称,应该是因为避免混淆,因为一个DateTime.Date
已经返回了一个DateTime
类型的值。既然日期类型只能选择DateOnly
了,那么时间类型也自然是TimeOnly
啦。
DateOnly
// Without DateOnly
var d1 = DateTime.Parse("2021-11-14");
var d2 = DateTime.Parse("2021-11-14");
var isSameDate = d1.Date == d2.Date;
Assert.IsTrue(isSameDate);
// Use DateOnly
var d1 = DateOnly.Parse("2021-11-14");
var d2 = DateOnly.Parse("2021-11-14");
var isSameDate = d1 == d2;
Assert.IsTrue(isSameDate);
DateOnly
使用很简单,一般使用DateOnly.FromDateTime
和DateOnly.(Try)Parse
生成一个DateOnly
对象。需要注意的是DateOnly.Parse
的传参只能是日期部分的字符串,像2021-11-14 12:34:56
这样的参数是会报错的。
TimeOnly
// Without TimeOnly
var workDateTime = DateTimeOffset.Parse("09:00");
var outOfWorkDateTime = DateTimeOffset.Parse("18:00");
var workingDateTime = DateTimeOffset.Parse("10:00");
var workTime = workDateTime.TimeOfDay;
var outOfWorkTime = outOfWorkDateTime.TimeOfDay;
var workingTime = workingDateTime.TimeOfDay;
var noLate = workingTime > workTime && workingTime < outOfWorkTime;
Assert.IsTrue(noLate);
// Use TimeOnly
var workTime = TimeOnly.Parse("09:00");
var outOfWorkTime = TimeOnly.Parse("18:00");
var workingTime = TimeOnly.Parse("10:00");
var noLate = workingTime.IsBetween(workTime, outOfWorkTime);
Assert.IsTrue(noLate);
TimeOnly
使用方式与DateOnly
类似,不过它有个特别的TimeOnly.IsBetween
方法。
Supports both "normal"
ranges such as 10:00-12:00, and ranges that span midnight such as 23:00-01:00.
Attentions
- 目前
DateOnly
和TimeOnly
不被System.Text.Json
和Newtonsoft.Json
等库支持。
References
- https://devblogs.microsoft.com/dotnet/announcing-net-6/#new-dateonly-and-timeonly-structs
- https://github.com/dotnet/runtime/issues/49036
- https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/DateOnly.cs
- https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/TimeOnly.cs