任何语言,框架,和日期时间相关的知识点就三大块:
前两个知识点,我们已经通过2个章节讲解完毕了,接下来就是时区了。
TimeZoneInfo 类
ASP.NET Core 或者说 C# 中和时区相关的逻辑都封装在 System
命名空间下的 TimeZoneInfo
类中。
TimeZoneInfo
类的实例有以下属性
属性 | 说明 | 范例 |
---|---|---|
Id |
时区唯一编号 | Asia/Shanghai |
BaseUtcOffset |
与格林威治时间(UTC)之间的时间偏移|08:00:00 |
|
DaylightName |
时区的夏令时的显示名称 | China Daylight Time |
DisplayName |
时区友好可读名称 | (UTC+08:00) China Standard Time |
StandardName |
时区的名称 | China Standard Time |
SupportsDaylightSavingTime |
是否支持夏令时 | True |
最重要的属性有2个 Id
和 BaseUtcOffset
,前者关系到时区的获取,或者关系到本地时间和 UTC 时间的偏差。
最最重要的事情
为了简化使用,TimeZoneInfo
有两个静态的属性 TimeZoneInfo.Utc
和 TimeZoneInfo.Local
分别用于表示格林威治时区 (+0UTC)
和本地时区
using System; namespace datetime { class Program { static void Main(string[] args) { Console.WriteLine(TimeZoneInfo.Utc); Console.WriteLine(TimeZoneInfo.Local); } } }
输出结果如下
(UTC) Coordinated Universal Time (UTC+08:00) China Standard Time
获取所有时区和时间偏移 TimeZoneInfo.GetSystemTimeZones()
TimeZoneInfo.GetSystemTimeZones()
返回所有支持的时区列表
using System; namespace datetime { class Program { static void Main(string[] args) { var tzi = TimeZoneInfo.GetSystemTimeZones(); foreach (var tz in tzi) { Console.WriteLine(tz); } } } }
运行结果如下
// 以上忽略 (UTC+08:00) Australian Western Standard Time (UTC+08:00) Brunei Darussalam Time (UTC+08:00) Central Indonesia Time (UTC+08:00) China Standard Time (UTC+08:00) China Standard Time (UTC+08:00) Hong Kong Standard Time (UTC+08:00) Irkutsk Standard Time (UTC+08:00) Malaysia Time (UTC+08:00) Malaysia Time (UTC+08:00) Philippine Standard Time (UTC+08:00) Singapore Standard Time (UTC+08:00) Taipei Standard Time (UTC+08:00) Ulaanbaatar Standard Time (UTC+08:00) Ulaanbaatar Standard Time (UTC+08:45) Australian Central Western Standard Time // 以下忽略
根据时区编号获取一个时区 TimeZoneInfo.FindSystemTimeZoneById()
我们可以通过 TimeZoneInfo.GetSystemTimeZones()
返回的时区列表的 Id
来获取一个时区,使用的就是
TimeZoneInfo
的静态方法 FindSystemTimeZoneById()
。比如我们要获取上海这个时区 Asia/Shanghai
则可以如下
TimeZoneInfo.FindSystemTimeZoneById("Asia/Shanghai");
使用范例如下
using System; namespace datetime { class Program { static void Main(string[] args) { var tzi = TimeZoneInfo.FindSystemTimeZoneById("Asia/Shanghai"); Console.WriteLine(tzi.DisplayName); } } }
创建一个自定义的时区 TimeZoneInfo.CreateCustomTimeZone()
我们还可以使用静态方法 TimeZoneInfo.CreateCustomTimeZone()
创建一个自定义的时区
TimeZoneInfo.CreateCustomTimeZone( "zh", // 编号 TimeSpan.FromHours(8), // 时间偏移 "中国时区", // 显示名称 "China time zone" // 可读性名称 );
使用范例如下
using System; namespace datetime { class Program { static void Main(string[] args) { var cnTimeZoneInfo = TimeZoneInfo.CreateCustomTimeZone("zh", TimeSpan.FromHours(8), "中国时区", "China time zone"); Console.WriteLine(cnTimeZoneInfo.DisplayName); } } }
跟时区相关的时间处理 DateTimeOffset.Parse()
和 DateTimeOffset.ToOffset()
我们可以通过静态方法 DateTimeOffset.Parse()
或者实例方法 [DateTimeOffset].ToOffset()
将日期时间从一个时区切换到另一个时区
using System; namespace datetime { class Program { static void Main(string[] args) { // 获取 UTC 时间 var dtu = DateTime.UtcNow; Console.WriteLine(dtu); // 获取 Asia/Shanghai 时区 var tzi = TimeZoneInfo.FindSystemTimeZoneById("Asia/Shanghai"); Console.WriteLine(tzi); var tzo = new DateTimeOffset(dtu); Console.WriteLine(tzo.ToOffset(tzi.BaseUtcOffset).DateTime); } } }
输出结果如下
10/27/2021 9:18:08 AM (UTC+08:00) China Standard Time 10/27/2021 5:18:08 PM
这里不得不说下 DateTimeOffset
类的构造函数,它有好多个构造函数,最值得注意的就2个,DateTimeOffset(DateTime)
和 DateTimeOffset(DateTime,TimeSpan)
,前者默认使用的是 UTC
时区,后者则需要传递 tzi.BaseUtcOffset
这个参数,也就是时区的时间偏移函数。
ASP.NET Core 设置默认时区 TZ
环境变量
好了,说回今天的重点,我们学习这么多,最主要的就是要知道 ASP.NET Core 如何设置默认的时区。
说起来有点悲哀,只有一种方法
使用 TZ
环境变量
Unix 类系统,比如 Ubuntu、CentOS、MacOS
export TZ=Asia/Shanghai
Windows 系统,点击 开始 -> 设置 -> 时间与语言 -> 日期与时间