在.NET 6中使用DateOnly和TimeOnly
千呼万唤始出来
在.NET 6(preview 4)
中引入了两个期待已久的类型,将作为核心库的一部分。DateOnly
和TimeOnly
允许开发人员表示DateTime
的日期或时间部分。这两个类型为值类型(struct type),可以在代码中独立处理日期或时间概念时使用,它们定义在System命名控件中,使用它们可以与数据库中允许表示相同类型数据的方式保持一致。具体来说,这些类型与SQL Server数据库中日期和时间类型可以很好的进行匹配。
注意:如果你要使用这两种类型,需要下载并安装.NET 6(preview 4)
和Visual Studio 16.11
(目前处于预览版中)。如果你想测试一下如何使用,可以使用LinqPad
进行测试验证。
在.NET 6
中使用DatetOnly
类型
根据字面意思可以很容易看出它所要表达的意思。当我们需要表示一个没有时间信息的日期类型时,可以使用DateOnly
。例如,我们可以在应用程序中表示某人的出生日期。在这种情况下,我们很少需要使用到DateTime
类型的时间部分了。一个标准的解决方案时将时间设置为:00:00:00.000。但是使用DateOnly
,我们可以更明确的表明我们想要的意图。
我们可以通过年、月、日参数构建一个DateOnly
的实例。
var date = new DateOnly(2021, 5, 31);
这样,我们就创建了一个表示2021年5月31日的日期类型。在内部,DataOnly
结构使用一个整数来跟踪一个有效天数的时间范围:0(映射为0001年1月1日)-3652058(映射为9999年12月31日)。
通常情况下,我们会从一个现有的DateTime
类型的实例开始,希望从它创建一个DateOnly
实例。为了实现这一点,我们可以调用FromDateTime
方法。
var currentDateOnly = DateOnly.FromDateTime(DateTime.Now);
与现有的DateTime
类型一样,我们也可以使用Parse
或TryParse
方法将表示日期的字符串解析为DateOnly
类型,这两个方法可能会抛出异常,或返回指示成功或失败的bool
值。
if (DateOnly.TryParse("28/09/1984", new CultureInfo("en-GB"), DateTimeStyles.None, out var result))
{
Console.WriteLine($"{result.Year}-{result.Month}-{result.Day}");
}
上面的代码尝试从第一个参数(日期的字符串表示)解析日期。由于不同的国家和地区对日期的解释不同,因此日期的解析可能或受到文化的影响。在这个例子中,明确提供CultureInfo
选项,以确保它使用日/月/年的格式从字符串中正确解析。
在成功解析成DateOnly实例的情况下,它将被写入控制台。再一次强调:CultureInfo
选择在这里扮演着重要角色。在本例中,将使用正在运行的线程的当前区域性来确定所使用的格式。根据系统配置,在应用程序线程在en-GB
下运行。因此字符串被正确格式化。在LinqPad
输出结果:
我们还可以向DateOnly实例中调用AddDays
、AddMonths
和AddYears
方法,以创建一个新的日期类型的实例。
var newDateOnly = date.AddDays(1).AddMonths(1).AddYears(1);
在.NET 6
中使用TimeOnly
类型
TimeOnly
结构体用于表示一个与日期无关的一个时间类型。例如,想象创建一个闹钟应用程序,让用户创建一个重复出现的闹钟。在这种情况下,我们要存储一天中报警应该想起的时间,但这个时间和日期是没有关系的。
TimeOnly
类型有几个构造方法重载。我认为大多数开发者会使用的且更常见的方法是允许我们创建一个可以小时分钟,小时分钟秒数、小时分钟秒数毫秒数方法的时间类型。
public TimeOnly(int hour, int minute)
public TimeOnly(int hour, int minute, int second)
public TimeOnly(int hour, int minute, int second, int millisecond)
例如,为了表示上午10:30分,我们可以创建以下TimeOnly
的实例。
var startTime = new TimeOnly(10, 30);
在这里,小时采用24
小时制格式,这样 1 PM
就是13时
。
在内部,TimeOnly
存储了一个long
类型,它表示自定义时间从凌晨后经过的Ticks
(100纳秒一个tick)。例如,凌晨1点时一天中的第一个小时,因此,从凌晨开始就有360亿个Tick(00:00:00.0000000)。虽然我们可以通过提供Ticks
作为参数来构造TimeOnly
。但这个实现细节对于一般使用来说并不是必需的。
public TimeOnly(long ticks);
在定义了开始时间之后,我们可以使用另一个TimeOnly
实例定义一个结束时间为5PM。
var endTime = new TimeOnly(17, 00, 00);
现在就可以对这些TimeOnly
实例进行数学操作,比如计算差。
var diff = endTime - startTime;
该操作返回类型是TimeSpan
,记录了两个TimeOnly
值之间相差的小时数。可以看LinqPad
的输出结果。
我们可以执行的另一个检查时识别特定的TimeOnly
是否在时间窗口内。例如,假设我们想要检查当前时间是否在我们定义的开始时间和结束时间之间。与DateOnly
一样,我们可以使用FromDateTime
静态方法将现有的DateTime
转化为TimeOnly
。
var currentTime = TimeOnly.FromDateTime(DateTime.Now);
var isBetween = currentTime.IsBetween(startTime, endTime);
Console.WriteLine($"Current time {(isBetween ? "is" : "is not")} between start and end");
上面的代码将输出到控制台,以确定当前时间是否在10:30(10:30 AM)
和17:00(5 PM)
之间。LinqPad输出的结果进行了稍微的改变,用来输出当前时间。
方法IsBetween()
可以接受两个参数,正常的时间范围,如我们前面的示例中使用的范围。同样可以接受跨凌晨的时间范围,如22:00-02:00。
var startTime = new TimeOnly(22, 00);
var endTime = new TimeOnly(02, 00);
var now = new TimeOnly(23, 25);
var isBetween = now.IsBetween(startTime, endTime);
Console.WriteLine($"Current time {(isBetween ? "is" : "is not")} between start and end");
// Output = Current time is between start and end
LinqPad
中的最后一行的输出内容。
TimeOnly
还包括用于比较使用循环时钟的时间操作符。
var startTime = new TimeOnly(08, 00);
var endTime = new TimeOnly(09, 00);
Console.WriteLine($"{startTime < endTime}");
// Output = True
这段代码检查上午8点是否早于上午9点,显然是早于9点的。
总结
面向 .NET 6
的新应用程序中,如果您的数据需要独立表示日期或时间,那么 DateOnly
和 TimeOnly
值得考虑。
你喜欢这篇文章吗?觉得它有用吗?如果有,请考虑支持我,关注一下我的公众号
在.NET 6中使用DateOnly和TimeOnly的更多相关文章
- .NET 6: New DateOnly and TimeOnly strcuts
Background and Motivation .NET 目前有用于处理日期和时间的DateTime和DateTimeOffset.但在许多情况下,用户需要处理日期而根本不关心时间部分,也存在需要 ...
- 官宣.NET 6 预览版4
我们很高兴发布 .NET 6 Preview 4.我们现在大约完成了 .NET 6 发布的一半.现在是一个很好的时机,可以再次查看.NET6的完整范围.许多功能都接近最终形式,而其他功能将很快推出,因 ...
- 20 个 .NET 6 新增的 API
DateOnly & TimeOnly .NET 6 引入了两种期待已久的类型 - DateOnly 和 TimeOnly, 它们分别代表DateTime的日期和时间部分. DateOnly ...
- .NET 6 史上最全攻略
欢迎使用.NET 6.今天的版本是.NET 团队和社区一年多努力的结果.C# 10 和F# 6 提供了语言改进,使您的代码更简单.更好.性能大幅提升,我们已经看到微软降低了托管云服务的成本..NET ...
- .NET性能优化-使用结构体替代类
前言 我们知道在C#和Java明显的一个区别就是C#可以自定义值类型,也就是今天的主角struct,我们有了更加方便的class为什么微软还加入了struct呢?这其实就是今天要谈到的一个优化性能的T ...
- Python开源框架
info:更多Django信息url:https://www.oschina.net/p/djangodetail: Django 是 Python 编程语言驱动的一个开源模型-视图-控制器(MVC) ...
- Safari中的new Date()格式化坑
今天在测试的时候发现,在Chrome中的如下代码: new Date("2014-03-09"); 在Safari中报错invalid date.经过查阅资料找到类似的问答: st ...
- Sharepoint中WebPart開發時註意的問題
1. 怎麼樣在WebPart中使用Sharepoint控件? 要在webpart中使用sharepoint控件必須先引用Microsoft.SharePoint.WebControls命名空間,如你現 ...
- Spring中基于XML的声明式事务控制配置步骤
1.配置事务管理器 2.配置事务的通知 此时,我们就需要导入事务的约束 tx名称空间和约束,同时也需要aop的 使用tx:advice标签配置事务通知 属性: id:给事务通知起一个唯一标识 tran ...
随机推荐
- Go之Zap日志库集成Gin
简介 在许多Go语言项目中,我们需要一个好的日志记录器能够提供下面这些功能: 1 . 能够将事件记录到文件中,而不是应用程序控制台; 2 . 日志切割-能够根据文件大小.时间或间隔等来切割日志文件; ...
- 数据结构之栈(JavaScript描述)
栈数据结构 栈是一种遵从后进先出原则的有序集合.新添加或待删除的元素都保存在栈的同一端,称为栈顶,另一端就叫栈底.在栈内,锌元素都靠近栈顶,救援都接近栈底 类似栈的例子 栈也被用在编程语言你的 ...
- Web操作摄像头、高拍仪、指纹仪等设备的功能扩展方案
摘要:信息系统开发中难免会有要操作摄像头.高拍仪.指纹仪等硬件外设,异或诸如获取机器签名.硬件授权保护(加密锁)检测等情况.受限于Web本身运行机制,就不得不使用Active.浏览器插件进行能力扩展了 ...
- Kafka2.8安装
1.概述 最近Kafka官网发布了2.8版本,在该版本中引入了KRaft模式.鉴于新版本和新特性的引入,相关使用资料较少,那边本篇博客笔者将为大家介绍Kafka2.8的安装和使用. 2.内容 2.1 ...
- volatile修饰全局变量,可以保证并发安全吗?
今天被人问到volatile能不能保证并发安全? 呵,这能难倒我? 上代码: //电脑太好,100线程起步~public class ThreadTest { private static volat ...
- Java并发-同步容器篇
作者:汤圆 个人博客:javalover.cc 前言 官人们好啊,我是汤圆,今天给大家带来的是<Java并发-同步容器篇>,希望有所帮助,谢谢 文章如果有问题,欢迎大家批评指正,在此谢过啦 ...
- vue 回顾
①.组件的注册 全局注册: // 注册 Vue.component('my-component', { template: '<div>A custom component!</di ...
- animation几个比较好玩的属性(alternate,及animation-fill-mode)
<!DOCTYPE html> <html> <head> <style> div { width:100px; height:100px; backg ...
- POJ 1716 区间最小点个数
题意: 给你n个区间,每个区间最少取两个元素,问你所有区间最少取几个元素(可以满足每个区间最少两个元素). 思路: 这个题目感觉挺巧妙的,之前在杭电上做过这个题目,这个题目可以用查 ...
- SpringBoot项目启动后自动打开浏览器
编写一个类,注册为Spring的Bean,然后实现CommandLineRunner接口,重写run()方法即可 @Component public class OpenBrowser impleme ...