如何在特定时区创建新的DateTime实例?

9

如果我有一个特定的TimeZoneInfo实例,如何在指定的时区创建一个新的DateTime实例?例如,如果我有:

var tz = TimeZoneInfo.FindSystemTimeZoneById("US Eastern Standard Time");
var date = new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Unspecified);
Console.WriteLine(TimeZoneInfo.ConvertTime(date, tz));

无论我定义的DateTimeKind(Utc,Local或Unspecified),我总是收到2016年12月31日晚上7:00:00。

我该如何声明一个新的DateTime,在美国东部标准时间下的2017年1月1日0:00:00?


1
有很多方法,其中之一是利用 TimeZoneInfo.BaseUtcOffset,还有 TimeZoneInfo.GetUtcOffset(DateTime)TimeZoneInfo.GetUtcOffset(DateTimeOffset) - Der Kommissar
请问您期望的输出是什么?您想将一个特定时区的 DateTime 转换为本地时间吗? - Federico Dipuma
@FedericoDipuma 不,我想为特定时区定义一个新的DateTime。例如,我想要一个DateTime实例,表示2017年1月1日美国东部标准时间(EST)。我不想依赖本地服务器时间,因为服务器可能不在我的客户所在的位置。因此,我为每个客户保存了TimeZoneInfo,并希望根据此实例化时间。 - Marko
1
DateTime 只区分本地时间和 UTC 时间,其中没有特定的时区信息。您可以将其从您的时区转换为 UTC(然后转换为本地时间,如果需要),或者使用 DateTimeOffset,即使它没有时区信息,但至少具有存储在 UTC 中的内置偏移量。此外,请注意,使用客户端时区存储时间戳几乎总是不明智的,最好存储 UTC 日期/时间,然后在客户端内部进行时区转换以进行可视化。 - Federico Dipuma
2个回答

8
你可以使用TimeZoneInfo来获取你所在的时区。
你可以在这里找到时区
var zn = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

如果要表达您正在使用本地东部标准时间,请使用DateTimeOffset结构,而不是DateTime。

DateTimeOffset dateTimeOffset = new DateTimeOffset(new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Unspecified), zn.BaseUtcOffset); 

为什么要使用DateTimeOffset

DateTimeOffset是瞬时时间(也称为绝对时间)的一种表示方式。


我需要使用TimeZoneInfo实例,因为它对我可用,您能告诉我TimeSpan如何映射到TimeZoneInfo吗?你只是手动编写-5小时的时间差。 - Marko
@Marko你的意思是既然这可用,你是指动态检索区域吗? - BRAHIM Kamel
1
这对我来说是正确的答案,因为它通过dateTimeOffset.DateTime给了我一个DateTime实例,并且通过dateTimeOffset.Offset给了我一个-5的偏移量。 - Marko

2

您可以像使用它来指定要创建日期时间对象的时区一样使用timezoneID。

TimeZoneInfo tzone= TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard 
Time");
DateTime dt = DateTime.Now;

稍后您只需要将日期时间转换为所需的时区即可。

var datetime2 = TimeZoneInfo.ConvertTimeFromUtc(dt , tzone);

这是一个链接,你可以在其中找到所有时区的ID。TimeZoneIDs

谢谢,希望这能帮到你。


2
DateTime.Now 会提供使用系统当前时区设置的时间。我想您是指 DateTime.UtcNow - daniefer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接