对于即时 DateTime 跟踪,我使用的是DateTimeOffset
数据类型。以下函数将用户对应的 TimeZone ID 偏移量添加到 UTC DateTime 属性DateTimeOffset
根据文档,UtcDateTime
将对DateTimeOffset
. 下面的代码虽然没有。为什么转换没有发生?
添加 TimeSpan 偏移量的函数,
public static DateTimeOffset GetUtcDateTime (DateTime sourceDateTime, string timeZoneId) {
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById (timeZoneId);
TimeSpan offset = timeZone.GetUtcOffset (sourceDateTime);
DateTimeOffset utcTime = new DateTimeOffset (sourceDateTime, offset);
return utcTime;
}
在这里我试图转换,
DateTimeOffset utcDate = (DateTime.UtcNow);
DateTime fromUtc = utcDate.DateTime;
DateTimeOffset UtcDate = StaticHandlers.GetUtcDateTime (fromUtc, "America/Los_Angeles");
Console.WriteLine ("UTC now is {0} and UTC Date LA is {1} and UtcDateTime LA is {2}", utcDate, UtcDate, utcDate.UtcDateTime);
输出是,
UTC 现在是 5/8/18 6:43:37 AM +00:00 和 UTC Date LA 是 5/8/18 6:43:37 AM -07:00 UtcDateTime LA 是 5/8/18 6:43 :37 上午
我想保留 UTC 和用户偏移量以进行跟踪。在这种情况下,夏令时很重要。下面的例子显示了我在说什么。
DateTime currentDateTime = DateTime.Now;
DateTime beforeDST_LA = new DateTime (2018, 3, 11, 0, 0, 0);
DateTime afterDST_LA = new DateTime (2018, 3, 12, 0, 0, 0);
TimeSpan offsetCurrent = tzi.GetUtcOffset (currentDateTime);
TimeSpan offsetBeforeDST = tzi.GetUtcOffset (beforeDST_LA);
TimeSpan offsetAfterDST = tzi.GetUtcOffset (afterDST_LA);
Console.WriteLine ("Current offset is {0} before DST is {1} and After DST is {2}", offsetCurrent, offsetBeforeDST, offsetAfterDST);
DST 之前的当前偏移量为 -07:00:00,DST 之后为 -08:00:00,DST 之后为 -07:00:00
首先,我不会调用您的 function GetUtcDateTime
,因为它不是这样做的。它试图DateTimeOffset
为特定时间的特定时区获取 ,因此将其称为GetDateTimeOffset
.
您在代码中缺少的主要概念是DateTime
具有.Kind
设置DateTimeKind
值的属性。代码中的几个地方考虑了这种类型:
GetUtcOffset
在确定偏移量之前将转换Utc
或Local
种类到提供的区域。
new DateTimeOffset
如果种类和偏移量冲突(如果您提供偏移量),(构造函数)将出错。
当您将 a 分配DateTime
给 a 时DateTimeOffset
,隐式转换正在评估种类。
当您.DateTime
从调用时DateTimeOffset
,种类将始终为Unspecified
- 无论偏移量如何。
如果您将所有这些都考虑在内,您就会意识到在调用 之前需要自己检查种类GetUtcOffset
。如果不是, Unspecified
那么您需要在获取偏移量之前将其转换为指定的时区。
public static DateTimeOffset GetDateTimeOffset(DateTime sourceDateTime, string timeZoneId)
{
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
// here, is where you need to convert
if (sourceDateTime.Kind != DateTimeKind.Unspecified)
sourceDateTime = TimeZoneInfo.ConvertTime(sourceDateTime, timeZone);
TimeSpan offset = timeZone.GetUtcOffset(sourceDateTime);
return new DateTimeOffset(sourceDateTime, offset);
}
既然已经解决了这个问题,请转到下一组问题,这就是您所说的问题。
DateTimeOffset utcDate = (DateTime.UtcNow);
DateTime fromUtc = utcDate.DateTime;
在第 1 行中,从DateTime
to的隐式转换DateTimeOffset
将偏移量设置为00:00
- 因为DateTime.UtcNow
has .Kind == DateTimeKind.Utc
。
在第 2 行,对.DateTime
属性的调用设置了fromUtc.Kind == DateTimeKind.Unspecified
。从本质上讲,你已经剥离了那种。
所以不是这样,只需DateTime.UtcNow
直接传递到函数中即可。这种类型将持续存在,并且一切都会起作用 - 现在Kind
已经识别并且转换正在函数内部发生。
综上所述,如果您的原始值都是DateTimeOffset
(例如,DateTimeOffset.UtcNow
),那么您根本不需要该功能。直接打电话就行TimeZoneInfo.ConvertTime
了DateTimeOffset
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句