Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么UtcDateTime函数不向UTC日期添加偏移量?_C#_.net_Datetime_Timezone_Datetimeoffset - Fatal编程技术网

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
是我在这里的最佳选择