Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.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# 安全地将UTC日期时间转换为本地时间(基于TZ)进行计算?_C#_Datetime_Timezone_Utc_Datetimeoffset - Fatal编程技术网

C# 安全地将UTC日期时间转换为本地时间(基于TZ)进行计算?

C# 安全地将UTC日期时间转换为本地时间(基于TZ)进行计算?,c#,datetime,timezone,utc,datetimeoffset,C#,Datetime,Timezone,Utc,Datetimeoffset,下面是我的博客,它给了我很多帮助(再次感谢!) 我现在想知道,当日期/时间转换回本地日期/时间时,如何安全地使用存储为UTC的日期/时间 正如Jon在我的最后一个问题中所指出的那样,DateTimeOffset表示时间上的一个瞬间,无法预测一分钟后的本地时间。我需要能够根据这些日期/时间进行计算 那么,当我从数据库中提取日期,将其转换为本地日期/时间,并对其进行具体计算时,我如何确保它们是准确的呢 情景 我的应用程序记录通过电子邮件发送的信息。收到电子邮件的日期/时间记录为提交时间。电子邮件是从

下面是我的博客,它给了我很多帮助(再次感谢!)

我现在想知道,当日期/时间转换回本地日期/时间时,如何安全地使用存储为UTC的日期/时间

正如Jon在我的最后一个问题中所指出的那样,DateTimeOffset表示时间上的一个瞬间,无法预测一分钟后的本地时间。我需要能够根据这些日期/时间进行计算

那么,当我从数据库中提取日期,将其转换为本地日期/时间,并对其进行具体计算时,我如何确保它们是准确的呢

情景

我的应用程序记录通过电子邮件发送的信息。收到电子邮件的日期/时间记录为提交时间。电子邮件是从exchange中提取的

我需要知道的是:


1) 如果这些电子邮件来自不同的国家,我是否将收到的
电子邮件的日期/时间转换为UTC格式并存储?e、 g.
Email.Received.ToUniversalTime()

不,你不能这样假设。UTC时间是完全线性的,您可以安全地对其进行计算。一旦将其转换为本地时间,它就不再是完全线性的

当夏令时发生变化时,本地时间存在重叠或间隔。如果您执行的计算跨越夏令时更改,则结果将减少一小时(如果是时间更改的程度,这是最常见的)


如果在将DateTime/DateTimeOffset值转换为本地时间之前进行计算,结果将始终正确。但是请注意,如果在夏令时更改时该值恰好位于重叠范围内,则将该值转换为本地日期时间值可能会使其变得不明确,无法判断当天的确切时间是第一次还是第二次出现。

正确处理日期/时间的最安全方法是将所有内容存储为UTC,并在当地时间显示。按照Guffa的建议,所有日期/时间的计算都应该在UTC完成。存储在UTC中,并在显示时动态转换为本地时间

如何使时区识别日期/时间 Microsoft有一篇关于如何将DateTime和TimeZoneInfo变量封装到结构中的文章

下面是Microsoft的示例结构,其中添加了1个属性以方便获取本地时间。这需要更多的工作才能充分发挥作用,但这是一个良好的开端

public struct TimeZoneTime
{
   public TimeZoneInfo TimeZone;
   public DateTimeOffset Time;

   public TimeZoneTime(DateTimeOffset time)
   {
      this.TimeZone = TimeZone.Local;
      this.Time = time;   
   }

   public TimeZoneTime(TimeZoneInfo tz, DateTimeOffset time)
   {
      if (tz == null) 
         throw new ArgumentNullException("The time zone cannot be a null reference.");

      this.TimeZone = tz;
      this.Time = time;   
   }

   public TimeZoneTime AddTime(TimeSpan interval)
   {
      // Convert time to UTC
      DateTimeOffset utcTime = TimeZoneInfo.ConvertTime(this.Time, TimeZoneInfo.Utc);      
      // Add time interval to time
      utcTime = utcTime.Add(interval);
      // Convert time back to time in time zone
      return new TimeZoneTime(this.TimeZone, TimeZoneInfo.ConvertTime(utcTime, this.TimeZone));
   }

    public DateTime LocalDate 
    {
        get { return Time.ToOffset(TimeZone); }
    }
}
你的情景
  • 可以,使用邮件对象的ReceivedTime或SentOn并将其转换为UTC进行存储和计算。这比上面的示例要简单得多

    Message msg = new Message();
    DateTime received = msg.ReceivedTime.ToUniversalTime();
    received.AddDays(7);
    Console.WriteLine(received.ToLocalTime());
    

  • 在将结果转换为本地时间之前,您不能在UTC日期/时间上执行计算吗?它们是否为本地时间有关系吗?如果DateTimeOffset只给我一个瞬间的时间,那么任何计算都是准确的吗?你真的错过了UTC的时间点。世界上任何地方都是一样的。不要转换。@Hans:我的意思是-假设我在英国有一个日期/时间,这个日期/时间在不同的时区是不一样的。如果是澳大利亚时间,我需要将UTC时间转换为当地时间,以便对其进行计算(因为英国时间中
    15/04/2010 18:00
    的日期会导致类似
    16/04/2010 04:00
    Aussie time)@Guffa:所以在存储日期/时间时(例如澳大利亚时间)保存前将UTC时间转换为特定时区是否安全?这仍然代表UTC时间吗?(我不是说使用
    ToLocalTime()
    我指的是类似于
    ConvertTimeBySystemTimeZoneId
    。@Guffa:我并不是在假设任何事情:)@James:不,当你将值转换成时区时,就不再是UTC时间了。但是,如果您使用的是DateTimeOffset,其偏移量将相应更改,因此您可以将其转换回原始UTC时间。DateTimeOffset值包含UTC时间的偏移量,但不包含时区,因此在将其转换回UTC时是安全的,对DateTimeOffset值的计算不考虑夏令时。如果您转换为UTC,进行计算并转换回UTC,则计算将是正确的。@James:邮件中的接收日期有一个时间偏移量,因此它对应一个DateTimeOffset值。如果可以成功地将其解析为DateTimeOffset值,则可以安全地将其转换为UTC,并将DateTime值保存为明确的时间点。从那以后,你可以把它转换成任何时区,这样你就可以在任何人的当地时间显示它,如果你愿意的话。@Guffa谢谢,我想我终于开始明白这一切了!还有一件事。有时我需要解析用户自己发送的日期(例如在电子邮件正文中)。我必须把这个日期当作当地时间。如何将其存储为UTC?我是否需要获取时间偏移量(基于时区),然后将其转换为
    DateTimeOffset
    ,然后再转换为UTC datetime?@chilltemp:我应该将其存储为服务器时区UTC还是本地时区UTC?@James:我不明白服务器和本地时区UTC之间的含义。UTC是UTC,没有变化。@James-如果您不知道是使用服务器时间还是客户端时间,请始终使用服务器上的时间。(在任何情况下都应该是UTC,如@chilltemp所说。)使用服务器上的时间可以使所有用户的数据保持一致,而且更安全,因为您通常不控制客户端的时间设置。@James:@Jeffery是正确的。服务器时间最有利于稳定。例外情况是脱机客户端。如果客户端没有到服务器的活动通道,并且将在以后(例如批处理通信)通信数据,则需要使用客户端的时间(UTC)。