在System命名空间中有 下面几个表示日期时间的类型:都是不可变的、结构体(Struct)。
类型 | 说明 |
DateTime | 常用的日期时间类型,默认使用的是本地时间(本地时区) |
DateTimeOffset | 支持时区偏移量的的 DateTime,适合跨时区的场景。 |
TimeSpan | 表示一段时间的时间长度(间隔),或一天内的时间(类似时钟,无日期) |
DateOnly 、 TimeOnly | .NET 6 引入的只表示日期、时间,结构更简单轻量,适合特点场景 |
TimeZoneInfo | 时区,可表示世界上的任何时区 |
📢Ticks: 上面几个时间对象中都有一个
Ticks
值,其值为从公元0001/01/01开始的计数周期。1 Tick (一个周期)为100纳秒(ns),0.1微秒(us),千万分之一秒,可以看做是C#中的最小时间单位。
Console.WriteLine(DateTime.Now.Ticks); //638504277997063647 Console.WriteLine(DateTimeOffset.Now.Ticks); //638504277997063874 Console.WriteLine(TimeSpan.FromSeconds(1).Ticks); //10000000
3.1、什么是UTC、GMT?
UTC(Coordinated Universal Time)世界标准时间(协调时间时间),简单理解就是 0时区的时间,是国际通用时间。它与0度经线的平太阳时相差不超过1秒,接近格林尼治标准时间(GMT)。
格林尼治标准时间(Greenwich Mean Time,GMT)是指位于伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。 理论上来说,格林尼治标准时间的正午是指当太阳横穿格林尼治子午线时的时间。
📢 由于地球在它的椭圆轨道里的运动速度不均匀,因此GMT是不稳定的。而UTC时间是由原子钟提供的,更为精确可靠,基本上已经取代GMT标准了。
我们日常使用的DateTime.Now
获取的时间其实是带了本地时区的(TimeZone),北京时区(+8小时),就是相比UTC时间,多了8个小时的偏差(时差)。DateTime 的Kind属性为DateTimeKind枚举,指定了时区类型:
- Unspecified:不确定的,大部分场景会被认为是
Local
的。 - Utc:UTC标准时区,偏移量为0。
- Local(默认值):本地时区的时间,偏移量根据本地时区计算,如北京时间的偏移量为
+8小时
。
public enum DateTimeKind { Unspecified, Utc, Local }
3.2、DateTime
🔸静态成员 | 说明 |
Now、UtcNow | 当前本地时间、当前UTC时间,还有一个Today 只有日期部分的值 |
MinValue、MaxValue | 最小、最大值 |
UnixEpoch | Unix 0点的时间,值就是 1970 年 1 月 1 日的 00:00:00.0000000 UTC |
Parse、ParseExact | 解析字符串转换为DateTime值,转换失败会抛出异常 |
TryParse、TryParseExact | 作用同上,安全版本的,Exact版本的方法可配置时间字符格式 |
🔸实例成员 | 说明 |
Date | 只有日期部分的DateTime值 |
Kind | DateTimeKind 类型,默认Local,构造函数中可以指定 |
Ticks | 计时周期总数,单位为100ns(纳秒) |
Year、Month、Day... | 当前时间的年、月、日、星期等等 |
🔸方法 | |
Add*** | 添加值后返回一个新的 DateTime,可以为负数 |
ToString(String) | 转换为字符串,指定日期时间格式,详细格式参考《String字符串全面了解》 |
ToUniversalTime() | 转换为UTC时间 |
3.3、DateTimeOffset
DateTimeOffset 和 DataTime 很像,使用、构造方式、API都差不多。主要的区别就是多了时区(偏移Offset),构造函数中可以用 TimeSpan 指定偏移量。DateTimeOffset 内部有两个比较重要的字段:
- 用一个短整型
short _offsetMinutes
来存储时区偏移量(基于UTC),单位为分钟。 - 用一个DateTime 存储始终为UTC的日期时间。
🔸静态成员 | 说明 |
UtcTicks | (UTC) 日期和时间的计时周期数 |
Offset | 时区偏移量,如北京时间:DateTimeOffset.Now.Offset //08:00:00 |
UtcDateTime | 返回本地UTC的DateTime |
LocalDateTime | 返回本地时区的DateTime |
DateTime | 返回Kind类型为Unspecified的DateTime,忽略了时区的DateTime值 |
用一个示例来理解DataTime、DataTimeOffset的区别: 比如你在一个跨国(跨时区)团队,你要发布一个通知:
- “本周五下午5点前提交周报”,不同时区都是周五下午5点前提交报告,虽然他们不是同一时刻,此时可用
DateTime
。- “明天下午5点开视频会”,此时则需要大家都在同一时刻上线远程会议,可能有些地方的是白天,有些则在黑夜,此时可用DateTimeOffset。