C# 为什么UtcDateTime函数不向UTC日期添加偏移量?
对于即时日期时间跟踪,我使用了C# 为什么UtcDateTime函数不向UTC日期添加偏移量?,c#,.net,datetime,timezone,datetimeoffset,C#,.net,Datetime,Timezone,Datetimeoffset,对于即时日期时间跟踪,我使用了DateTimeOffset数据类型。以下函数将用户对应的时区ID偏移量添加到DateTimeOffset 根据,UtcDateTime将对DateTimeOffset执行时区转换和类型转换。但下面的代码不支持。为什么转换没有发生 用于添加时间跨度偏移的函数 public static DateTimeOffset GetUtcDateTime (DateTime sourceDateTime, string timeZoneId) { TimeZoneInfo
DateTimeOffset
数据类型。以下函数将用户对应的时区ID偏移量添加到DateTimeOffset
根据,UtcDateTime
将对DateTimeOffset
执行时区转换和类型转换。但下面的代码不支持。为什么转换没有发生
用于添加时间跨度偏移的函数
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日期LA是5/8/18
美国东部时间上午6:43:37-07:00洛杉矶时间是2018年5月8日上午6:43:37
使现代化
我希望保留UTC和用户偏移量,以便于跟踪。DST在这方面很重要。下面的例子说明了我所说的
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
-07:00:00
首先,我不会调用您的函数
GetUtcDateTime
,因为它不是这样做的。它试图为特定时间的特定时区获取一个DateTimeOffset
,因此将其称为类似于GetDateTimeOffset
代码中缺少的主要概念是DateTime
具有.Kind
属性,该属性设置一个DateTimeKind
值。您的代码中有几个地方考虑了这种类型:
将GetUtcOffset
或Utc
类型转换为确定偏移量之前提供的区域Local
(构造器)将在种类和偏移量冲突时出错,如果您提供偏移量new DateTimeOffset
- 当您将
分配给日期时间
时,隐式转换将评估该种类日期时间偏移量
- 从
调用DateTimeOffset
时,无论偏移量是多少,该类型始终是.DateTime
未指定的
GetUtcOffset
之前需要自己检查这类代码。如果它不是未指定的,则需要将其转换为指定的时区,然后才能获得偏移量
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
到DateTimeOffset
的隐式转换将偏移设置为00:00
——因为DateTime.UtcNow
具有.Kind==DateTimeKind.Utc
在第2行中,对.DateTime
属性的调用设置fromUtc.Kind==DateTimeKind.Unspecified
。基本上,你已经剥去了那种
因此,只需将DateTime.UtcNow
直接传递到函数中即可。该类将持续存在,并且它将全部工作-现在类
已被识别,并且转换正在函数内部进行
总之,如果您的原始值都是
DateTimeOffset
(例如,DateTimeOffset.UtcNow
),那么您根本不需要该函数。直接用DateTimeOffset
调用TimeZoneInfo.ConvertTime
。输出看起来正确。18年8月5日上午6:43:37 UTC是18年8月5日上午6:43:37 UTC,即使是在洛杉矶。当然,本地时区将有一个与UTCso的偏移量,UtcDateTime LA
部分输出不应返回7小时?正确。UTC的历史基准是伦敦时间(没有夏令时)。所以世界各地都是一样的。它从不存在时区问题,因为它完全忽略了它们。这就是为什么我们喜欢它;-)。只有本地时间有偏移量。所以基本上我在这里做的是错误的,我应该存储DateTime。现在和偏移量一起存储吗?我怎么能在这里进行转换呢?我的意思是在上面的例子中显示7小时后的时间?非常感谢您的详细回答TimeZoneInfo.ConvertTime
是我在这里的最佳选择