如何设置 DateTime 值的时区(或种类)?

Posted

技术标签:

【中文标题】如何设置 DateTime 值的时区(或种类)?【英文标题】:How to set a time zone (or a Kind) of a DateTime value? 【发布时间】:2011-09-08 13:24:45 【问题描述】:

我的意思是将严格的 UTC 时间存储在 DateTime 变量中,并以 ISO 8601 格式输出。

最后我使用了.ToString("yyyy-MM-ddTHH:mm:sszzz"),它发现时区是UTC+01:00。

我尝试使用 .Kind = DateTimeKind.Utc,但它说 Kind 属性没有设置器。

如何明确指定时间为 UTC? Kind 属性是如何设置的?

【问题讨论】:

【参考方案1】:

虽然 DateTime.Kind 属性没有设置器,但静态方法 DateTime.SpecifyKind 会创建一个具有指定 Kind 值的 DateTime 实例。

另外有几个 DateTime constructor overloads 采用 DateTimeKind 参数

【讨论】:

DateTimeKind 仅包含本地、未指定和 UTC。我可能不想使用一个特定的时区。 @hardywang 如果您只需要指定时间和与 UTC 的偏移量,那么您可以使用DateTimeOffset。如果您确实需要识别特定时区,则需要将 DateTime 与TimeZoneInfo 结合使用。请参阅Choosing Between DateTime, DateTimeOffset, and TimeZoneInfo 进行讨论。 DateTimeKind 除了在转换时间时充当参考点之外,并没有真正做很多事情。如果将其应用于现有的 DateTime,它实际上不会改变任何内容。【参考方案2】:

如果您想利用本地机器时区,您可以使用 myDateTime.ToUniversalTime() 从本地时间获取 UTC 时间,或使用 myDateTime.ToLocalTime() 将 UTC 时间转换为本地机器的时间。

// convert UTC time from the database to the machine's time
DateTime databaseUtcTime = new DateTime(2011,6,5,10,15,00);
var localTime = databaseUtcTime.ToLocalTime();

// convert local time to UTC for database save
var databaseUtcTime = localTime.ToUniversalTime();

如果您需要将时间从/到其他时区,您可以使用TimeZoneInfo.ConvertTime()TimeZoneInfo.ConvertTimeFromUtc()

// convert UTC time from the database to japanese time
DateTime databaseUtcTime = new DateTime(2011,6,5,10,15,00);
var japaneseTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
var japaneseTime = TimeZoneInfo.ConvertTimeFromUtc(databaseUtcTime, japaneseTimeZone);

// convert japanese time to UTC for database save
var databaseUtcTime = TimeZoneInfo.ConvertTimeToUtc(japaneseTime, japaneseTimeZone);

List of available timezones

TimeZoneInfo class on MSDN

【讨论】:

【参考方案3】:

你也可以试试这个,很容易实现

TimeZone time2 = TimeZone.CurrentTimeZone;
DateTime test = time2.ToUniversalTime(DateTime.Now);
var singapore = TimeZoneInfo.FindSystemTimeZoneById("Singapore Standard Time");
var singaporetime = TimeZoneInfo.ConvertTimeFromUtc(test, singapore);

将文本更改为您想要更改的标准时间。

使用C#的TimeZone特性来实现。

【讨论】:

【参考方案4】:

我在网络框架 4.8 中的 System.DateTime 中遇到了时区问题。我想这个版本的框架有一个错误。

我在 net framework 4.8 和 net 5.0 下运行了这段代码(+3 是我的本地时区)。

var dateTime = new DateTime(2021, 3, 3, 12, 13, 14);
var dateTimeKindUtc = new DateTime(2021, 3, 3, 12, 13, 14, DateTimeKind.Utc);
var dateTimeSpecifyKind = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc);
var dateTimeToUniversalTime = dateTime.ToUniversalTime();
var timeZoneInfoConvertTimeToUtc = TimeZoneInfo.ConvertTimeToUtc(dateTime);

Console.WriteLine($"nameof(dateTime) dateTime:yyyy-MM-ddTHH:mm:sszzz");
Console.WriteLine($"nameof(dateTimeKindUtc) dateTimeKindUtc:yyyy-MM-ddTHH:mm:sszzz");
Console.WriteLine($"nameof(dateTimeSpecifyKind) dateTimeSpecifyKind:yyyy-MM-ddTHH:mm:sszzz");
Console.WriteLine($"nameof(dateTimeToUniversalTime) dateTimeToUniversalTime:yyyy-MM-ddTHH:mm:sszzz");
Console.WriteLine($"nameof(timeZoneInfoConvertTimeToUtc) timeZoneInfoConvertTimeToUtc:yyyy-MM-ddTHH:mm:sszzz");

net framework 4.8 输出

dateTime 2021-03-03T12:13:14+03:00
dateTimeKindUtc 2021-03-03T12:13:14+03:00
dateTimeSpecifyKind 2021-03-03T12:13:14+03:00
dateTimeToUniversalTime 2021-03-03T09:13:14+03:00
timeZoneInfoConvertTimeToUtc 2021-03-03T09:13:14+03:00

净 5.0 输出

dateTime 2021-03-03T12:13:14+03:00
dateTimeKindUtc 2021-03-03T12:13:14+00:00
dateTimeSpecifyKind 2021-03-03T12:13:14+00:00
dateTimeToUniversalTime 2021-03-03T09:13:14+00:00
timeZoneInfoConvertTimeToUtc 2021-03-03T09:13:14+00:00

【讨论】:

来自docs:对于 DateTime 值,“zzz”自定义格式说明符表示 本地操作系统的时区与 UTC 的有符号偏移量,以小时和分钟。它不反映实例的 DateTime.Kind 属性的值。 因此,不建议将“zzz”格式说明符与 DateTime 值一起使用。

以上是关于如何设置 DateTime 值的时区(或种类)?的主要内容,如果未能解决你的问题,请参考以下文章

防止对 DateTime 值的反序列化进行时区转换

python中datetime怎么设置时区

如何表示各个时区的时间DateTime.ToString

如何修复 RuntimeWarning:DateTimeField 在时区支持处于活动状态时收到天真> datetime?

如何将表单(国家/城市)中的字符串时区转换为 datetime.tzinfo

如何在 Python 中获取或打印 GMT 时区的当前日期时间? [复制]