DateTime和DateTimeOffset是同胞兄弟吗?
小编在日常开发中,用得最多的时间类型就是DateTime,直到一次偶然的邂逅,让小编遇见了DateTimeOffset。当时小编也是一脸迷茫,因为在小编的C#编程字典里就没出现过DateTimeOffset的字样,实属惭愧。于是心中立马产生疑惑:DateTimeOffset是用来干嘛的?它和DateTime之间又是什么关系?带着种种疑问和不解,小编今天就带你一起一窥究竟!
开场前,先了解下GMT、UTC、TimeZone这三个时间概念
GMT:Greenwich Mean Time,格林威治平时(也称格林威治时间)。它规定太阳每天经过位于英国伦敦郊区的皇家格林威治天文台的时间为中午12点。1972年之前,格林威治时间(GMT)一直是世界时间的标准。1972年之后,GMT 不再是一个时间标准了,取而代之的是UTC。
UTC:Coodinated Universal Time,协调世界时,又称世界统一时间、世界标准时间、国际协调时间。UTC 是现在全球通用的时间标准,全球各地都同意将各自的时间进行同步协调。
TimeZone: 时间区域,简称时区。按照规定从格林威治本初子午线起,经度每向东或者向西间隔15°,就划分一个时区,在这个区域内,大家使用同样的标准时间。全球共分为24个标准时区,相邻时区的时间相差一个小时。
举个例子:北京位于东八区,和伦敦时间(UTC时间)相差+8个小时。当小编每天早上8点出门上班的时候 ,大洋彼岸的英国人民正处于睡梦中,因为那儿正值午夜零点,这就是我们常说的时差。顺带提一句,虽然我国地域辽阔横跨5个时区,但统一采用北京时间作为标准时间,目的就是为了方便时间管理。
首先登场的是:DateTime
DateTime表示的是一个日期和时间值。这里我们先思考一个问题:假设有个陌生人电话告诉你现在时间是某月某日某时某分,但你又不知道对方在哪里,那么这个时间对你来说是不清晰的,它可能是当地时间(东京时间、悉尼时间...),也有可能是UTC时间。因此DateTime有个只读属性Kind,它是一个DateTimeKind枚举,用来表示时间类型。定义如下:
1 public enum DateTimeKind
2 {
3 // 未指明是UTC时间,还是当地时间
4 Unspecified = 0,
5 // 表示UTC时间
6 Utc = 1,
7 // 表示本地时间
8 Local = 2
9 }
通过DateTime构造函数,可以看出Kind属性值是由构造函数传入的。下面来看DateTime的几种常见用法:
1 DateTime dt1 = new DateTime(2023, 7, 27, 8, 40, 25);
2 Console.WriteLine($"DateTime:{dt1}, 时间类型:{dt1.Kind}, 转本地时间:{dt1.ToLocalTime()},转UTC时间:{dt1.ToUniversalTime()}");
3
4 DateTime dt2 = DateTime.Now;
5 Console.WriteLine($"DateTime:{dt2}, 时间类型:{dt2.Kind}, 转本地时间:{dt2.ToLocalTime()},转UTC时间:{dt2.ToUniversalTime()}");
6
7 DateTime dt3 = DateTime.UtcNow;
8 Console.WriteLine($"DateTime:{dt3}, 时间类型:{dt3.Kind}, 转本地时间:{dt3.ToLocalTime()},转UTC时间:{dt3.ToUniversalTime()}");
9
10 DateTime dt4 = new DateTime(2023, 7, 27, 8, 40, 25, DateTimeKind.Local);
11 Console.WriteLine($"DateTime:{dt4}, 时间类型:{dt4.Kind}, 转本地时间:{dt4.ToLocalTime()},转UTC时间:{dt4.ToUniversalTime()}");
12
13 DateTime dt5 = new DateTime(2023, 7, 27, 8, 40, 25, DateTimeKind.Utc);
14 Console.WriteLine($"DateTime:{dt5}, 时间类型:{dt5.Kind}, 转本地时间:{dt5.ToLocalTime()},转UTC时间:{dt5.ToUniversalTime()}");
输出结果:
DateTime: 2023 / 7 / 27 8:40:25, 时间类型: Unspecified, 转本地时间: 2023 / 7 / 27 16:40:25,转UTC时间: 2023 / 7 / 27 0:40:25
DateTime: 2023 / 7 / 27 14:04:00, 时间类型: Local, 转本地时间: 2023 / 7 / 27 14:04:00,转UTC时间: 2023 / 7 / 27 6:04:00
DateTime: 2023 / 7 / 27 6:04:00, 时间类型: Utc, 转本地时间: 2023 / 7 / 27 14:04:00,转UTC时间: 2023 / 7 / 27 6:04:00
DateTime: 2023 / 7 / 27 8:40:25, 时间类型: Local, 转本地时间: 2023 / 7 / 27 8:40:25,转UTC时间: 2023 / 7 / 27 0:40:25
DateTime: 2023 / 7 / 27 8:40:25, 时间类型: Utc, 转本地时间: 2023 / 7 / 27 16:40:25,转UTC时间: 2023 / 7 / 27 8:40:25
由此可见,DateTime是通过Kind属性来区分是本地时间还是UTC时间,同时本地时间和UTC时间之间可以相互转换,转换条件就是根据你电脑当前所设置的时区。不足之处就是DateTime提供了非常有限的时区信息,如果不看Kind属性,你无法判断它是来自本地时间还是UTC时间,因此在跨时区系统间的数据移植性较差(除非是指定是UTC时间)。
接着出场的就是:DateTimeOffset
DateTimeOffset表示一个时间点,通常以相对于协调世界时 (UTC) 的日期和时间来表示。它既包含了DateTime属性,又包含了一个TimeSpan类型的Offset属性(表示相对于UTC时间的偏移量).
通过DateTimeOffset构造函数,可以看出Offset属性值是由构造函数传入的。下面来看DateTimeOffset的几种常见用法:
1 DateTimeOffset dto1 = new DateTimeOffset(2023, 7, 27, 8, 40, 25, TimeSpan.Zero);
2 Console.WriteLine($"DateTimeOffset:{dto1}, 时间偏移:{dto1.Offset}, 转本地时间:{dto1.ToLocalTime()},转UTC时间:{dto1.ToUniversalTime()}");
3
4 DateTimeOffset dto2 = DateTimeOffset.Now;
5 Console.WriteLine($"DateTimeOffset:{dto2}, 时间偏移:{dto2.Offset}, 转本地时间:{dto2.ToLocalTime()},转UTC时间:{dto2.ToUniversalTime()}");
6
7 DateTimeOffset dto3 = DateTimeOffset.UtcNow;
8 Console.WriteLine($"DateTimeOffset:{dto3}, 时间偏移:{dto3.Offset}, 转本地时间:{dto3.ToLocalTime()},转UTC时间:{dto3.ToUniversalTime()}");
9
10 DateTimeOffset dto4 = new DateTimeOffset(2023, 7, 27, 8, 40, 25, new TimeSpan(8, 0, 0));
11 Console.WriteLine($"DateTimeOffset:{dto4}, 时间偏移:{dto4.Offset}, 转本地时间:{dto4.ToLocalTime()},转UTC时间:{dto4.ToUniversalTime()}");
12
13 DateTimeOffset dto5 = new DateTimeOffset(new DateTime(2023, 7, 27, 8, 40, 25), new TimeSpan(-8, 0, 0));
14 Console.WriteLine($"DateTimeOffset:{dto5}, 时间偏移:{dto5.Offset}, 转本地时间:{dto5.ToLocalTime()},转UTC时间:{dto5.ToUniversalTime()}");
输出结果:
DateTimeOffset:2023/7/27 8:40:25 +00:00, 偏移量:00:00:00, 转本地时间:2023/7/27 16:40:25 +08:00,转UTC时间:2023/7/27 8:40:25 +00:00
DateTimeOffset:2023/7/27 15:46:14 +08:00, 偏移量:08:00:00, 转本地时间:2023/7/27 15:46:14 +08:00,转UTC时间:2023/7/27 7:46:14 +00:00
DateTimeOffset:2023/7/27 7:46:14 +00:00, 偏移量:00:00:00, 转本地时间:2023/7/27 15:46:14 +08:00,转UTC时间:2023/7/27 7:46:14 +00:00
DateTimeOffset:2023/7/27 8:40:25 +08:00, 偏移量:08:00:00, 转本地时间:2023/7/27 8:40:25 +08:00,转UTC时间:2023/7/27 0:40:25 +00:00
DateTimeOffset:2023/7/27 8:40:25 -08:00, 偏移量:-08:00:00, 转本地时间:2023/7/28 0:40:25 +08:00,转UTC时间:2023/7/27 16:40:25 +00:00
可以看出,DateTimeOffset除了包含日期和时间之外,还包含相对于UTC时间的偏移量,因此不再需要Kind属性,就能区分出是UTC时间(如:dto1和dto3)还是本地时间(如:dto2、dto4和dto5),同时还能反馈时间所在的时区(如:dto2和dto4是东八区,dto5是西八区)。
最后得出结论:
DateTimeOffset和DateTime之间的确存在血缘关系,DateTimeOffset相当于是DateTime的一个包装,它除了具有DateTime的所有功能之外,还包含时区信息。如果你的系统不需要考虑时区问题或者只用UTC时间,那么DateTime就够用了。如果你的系统是全球化的,客户来自不同时区的不同国家,那么服务端就需要用DateTimeOffset来保存时间,这样客户端很容易将带有时区的时间字符串(如:"2023/7/27 8:40:25 +08:00")转成本地时间来显示。总而言之,小编认为DateTimeOffset功能比DateTime更强大、也更加灵活。微软官方建议用DateTimeOffset作为应用开发的默认时间类型。
参考资料:
彻底弄懂GMT、UTC、时区和夏令时 - 知乎 (zhihu.com)
c#:细说时区、DateTime和DateTimeOffset在国际化中的应用 - 知乎 (zhihu.com)
谈谈你最熟悉的System.DateTime[上篇] - Artech - 博客园 (cnblogs.com)
Compare types related to date and time | Microsoft Learn
DateTime和DateTimeOffset是同胞兄弟吗?的更多相关文章
- DateTime , DateTime2 ,DateTimeOffset 之间的小区别
闲来无事列了个表比对一下这3兄弟之间还是有一点差距的╮(╯_╰)╭ DateTime DateTime2 DateTimeOffset 日期范围 1753-01-01到 9999-12-31 00 ...
- C#中 DateTime , DateTime2 ,DateTimeOffset 之间的小区别 (转载)
闲来无事列了个表比对一下这3兄弟之间还是有一点差距的╮(╯_╰)╭ DateTime DateTime2 DateTimeOffset 日期范围 1753-01-01到 9999-12-31 00 ...
- DateTime还是DateTimeOffset?Now还是UtcNow?
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:新年第一篇文章,就来谈谈关于时间的简单技术问题:该用DateTime还是DateTim ...
- 第二节:比较DateTime和DateTimeOffset两种时间类型并介绍Quartz.Net中用到的几类时间形式(定点、四舍五入、倍数、递增)
一. 时间的类型 1. 背景 这里为什么要介绍时间类型呢,明明是定时调度篇,原因是在定时任务中,任务什么时间开始执行,什么时间结束执行,要用到各种各样的时间模式,虽然这不能算是一个复杂的问题,但在正式 ...
- 重学c#系列——datetime 和 datetimeoffset[二十一]
前言 简单介绍一下datetime和 datetimeoffset. 正文 了解一个国家的文化,就要了解一个国家的历史. 要了解datetimeoffset,那么很有必要了解一下datetime. 表 ...
- DateTime和DateTimeOffset的区别
1,DateTime 表示时间上的一刻,通常以日期和当天时间来表示. 2, DateTimeOffset 表示一个时间点,通常以相对于协调世界时(UTC)的日期和时间来表示. 3,下面是微软官方给出的 ...
- .NETFramework:DateTimeOffset
ylbtech-.NETFramework:DateTimeOffset 表示一个时间点,通常相对于协调世界时(UTC)的日期和时间来表示. 1.程序集 mscorlib, Version=4.0.0 ...
- 如何使用 System.Text.Json 序列化 DateTimeOffset 为 Unix 时间戳
在 .NET 中,日期和时间通常使用 DateTime 或 DateTimeOffset 来表示.这两种数据类型都可以表示日期和时间,但它们之间有一些明显的区别.DateTime 是不带时区信息的,而 ...
- 初试ASP.NET Web API/MVC API(附Demo)
写在前面 HTTP RESTful 创建Web API 调用Web API 运行截图及Demo下载 ASP.NET Web API是一个框架,可以很容易构建达成了广泛的HTTP服务客户端,包括浏览 ...
- ASP.NET Web API(MVC API)
ASP.NET Web API是一个框架,可以很容易构建达成了广泛的HTTP服务客户端,包括浏览器和移动设备.是构建RESTful应用程序的理想平台的.NET框架. 上面是微软对Web API给出 ...
随机推荐
- python的format方法中文字符输出问题
format方法的介绍 前言 提示:本文仅介绍format方法的使用和中文的输出向左右和居中输出问题 一.format方法的使用 format方法一般可以解决中文居中输出问题,假如我们设定宽度,当中文 ...
- python的docker环境配置
docker环境配置 Docker基本操作指令, 下载安装参考 https://duoke360.com/tutorial/docker/install-docker docker + flask + ...
- 2023-05-09:石子游戏中,爱丽丝和鲍勃轮流进行自己的回合,爱丽丝先开始 。 有 n 块石子排成一排。 每个玩家的回合中,可以从行中 移除 最左边的石头或最右边的石头, 并获得与该行中剩余石头值
2023-05-09:石子游戏中,爱丽丝和鲍勃轮流进行自己的回合,爱丽丝先开始 . 有 n 块石子排成一排. 每个玩家的回合中,可以从行中 移除 最左边的石头或最右边的石头, 并获得与该行中剩余石头值 ...
- 2020-11-18:java中,到底多大的对象会被直接扔到老年代?
福哥答案2020-11-18: HotSpot 虚拟机提供了-XX:PretenureSizeThreshold 参数,指定大于该设置值的对象直接在老年代分配,这样做的目的就是避免在 Eden 区及两 ...
- 2021-02-27:假设一个固定大小为W的窗口,依次划过arr,返回每一次滑出状况的最大值。例如,arr = [4,3,5,4,3,3,6,7], W = 3。返回:[5,5,5,4,6,7]。
2021-02-27:假设一个固定大小为W的窗口,依次划过arr,返回每一次滑出状况的最大值.例如,arr = [4,3,5,4,3,3,6,7], W = 3.返回:[5,5,5,4,6,7]. 福 ...
- 2022-04-17:给定一个数组arr,其中的值有可能正、负、0, 给定一个正数k。 返回累加和>=k的所有子数组中,最短的子数组长度。 来自字节跳动。力扣862。
2022-04-17:给定一个数组arr,其中的值有可能正.负.0, 给定一个正数k. 返回累加和>=k的所有子数组中,最短的子数组长度. 来自字节跳动.力扣862. 答案2022-04-17: ...
- 2023-05-17:一个正整数如果能被 a 或 b 整除,那么它是神奇的。 给定三个整数 n , a , b ,返回第 n 个神奇的数字。 因为答案可能很大,所以返回答案 对 10^9 + 7 取模
2023-05-17:一个正整数如果能被 a 或 b 整除,那么它是神奇的. 给定三个整数 n , a , b ,返回第 n 个神奇的数字. 因为答案可能很大,所以返回答案 对 10^9 + 7 取模 ...
- 在Winform中一分钟入门使用好看性能还好的Blazor Hybrid
在Winform中一分钟入门使用好看性能还好的Blazor Hybrid 安装模板 dotnet new install Masa.Template::1.0.0-rc.2 创建 Winform的Bl ...
- 【编程日记】搭建PyCharm集成开发环境
0.相关确定 本教程使用的版本号为专业版PyCharm 2022.3.2,如果您是初学者,为了更好的学习本教程,避免不必要的麻烦,请您下载使用与本教程一致的版本号. 1.PyCharm的下载 官网下载 ...
- odoo开发教程六:工作流、安全机制、向导
一:工作流 工作流是与业务流程相关联的模型,可用于跟踪工序的动态演变过程. 工作流.活动(节点或操作).转换通常在xml里以record定义.在工作流中处理的单个流程称为工作项. 与模型关联的工作流是 ...