【问题标题】:Converting UTC DateTime to Local DateTime in C#在 C# 中将 UTC 日期时间转换为本地日期时间
【发布时间】:2019-06-21 03:51:53
【问题描述】:

我想显示将根据用户的时区管理的事件的日期和时间。要检查时区,我将系统时区更改为另一个时区,但我的代码仍然是本地时区。 这是我的代码

我正在使用 Cassandra 数据库和 C# .NET MVC

DateTime startTimeFormate = x.Startdate;
DateTime endTimeFormate = x.Enddate;
TimeZone zone = TimeZone.CurrentTimeZone;
DateTime startTime = zone.ToLocalTime(startTimeFormate);
DateTime endTime = zone.ToLocalTime(endTimeFormate);

【问题讨论】:

  • 如果您关心时区,请至少使用DateTimeOffset,而不是DateTime。至于您的问题,x.StartDatex.EndDateDateTimeKind 值是多少?本地、UTC 还是未指定? ToLocalTime 仅在您想将 UTC 转换为本地时才有意义。在其他情况下,唯一合乎逻辑的结果是返回与 DateTimeKindLocal 相同的日期时间值。
  • 如果值来自数据库,它们可能是Unspecified,因为数据库提供者不知道它们代表什么样的日期,或者使用哪个偏移量。
  • 最后,要将DateTime 值从一个时区转换为另一个时区,请使用TimezoneInfo.ConvertTime

标签: c# datetime timezone


【解决方案1】:

要将UTC DateTime 转换为您的Local DateTime,您必须使用TimeZoneInfo,如下所示:

DateTime startTimeFormate = x.Startdate; // This  is utc date time
TimeZoneInfo systemTimeZone = TimeZoneInfo.Local;
DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(startTimeFormate, systemTimeZone);

此外,如果您想将UTC DateTime 转换为特定于用户的Local DateTime,请执行以下操作:

string userTimeZoneId = "New Zealand Standard Time";
TimeZoneInfo nzTimeZone = TimeZoneInfo.FindSystemTimeZoneById(userTimeZoneId);
DateTime userLocalDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, userTimeZoneId);

注意:.NET 中的 TimeZone 现在是 obsolete,它已被弃用。请改用TimeZoneInfo

【讨论】:

    【解决方案2】:

    TimeZone.CurrentTimeZoneTimeZoneInfo.LocalToLocalTime 使用服务器的本地时区,而不是最终用户。

    相反,请先查看how to reliably get the end-users's time zone in your .NET code

    那么,假设您现在有一个TimeZoneInfo 对象,只需使用TimeZoneInfo.ConvertTimeFromUtc 方法。

    【讨论】:

      【解决方案3】:

      根据MSDN documentation of the TimeZone.CurrentTimeZone property,本地时区在第一次调用TimeZone.CurrentTimeZone后被缓存。实际上,这意味着只要不支持运行中时区的动态更新,您的代码就应该可以正常运行。为了立即看到更改,在调用 TimeZone.CurrentTimeZone 之前,您应该调用

      TimeZoneInfo.ClearCachedData();
      

      这在 MSDN 文章中记录如下:

      来电者须知

      本地时区数据在第一次使用 CurrentTimeZone 后被缓存 检索时区信息。如果系统的本地时区 随后发生变化,CurrentTimeZone 属性不反映 这种变化。如果您需要处理时区更改,而您的 应用程序正在运行,使用 TimeZoneInfo 类并调用其 ClearCachedData() 方法。

      【讨论】:

        【解决方案4】:

        这些是我使用的 DateTime 助手,涵盖了我目前需要的所有情况。

        public static class DateTimeHelpers
          {
            public static DateTime ConvertToUTC(DateTime dateTimeToConvert, string sourceZoneIdentifier)
            {
              TimeZoneInfo sourceTZ = TimeZoneInfo.FindSystemTimeZoneById(sourceZoneIdentifier);
              TimeZoneInfo destinationTZ = TimeZoneInfo.FindSystemTimeZoneById("UTC");
        
              return TimeZoneInfo.ConvertTime(dateTimeToConvert, sourceTZ, destinationTZ);
            }
        
            public static DateTime ConvertToTimezone(DateTime utcDateTime, string destinationZoneIdentifier)
            {
              TimeZoneInfo sourceTZ = TimeZoneInfo.FindSystemTimeZoneById("UTC");
              TimeZoneInfo destinazionTZ = TimeZoneInfo.FindSystemTimeZoneById(destinationZoneIdentifier);
        
              return DateTime.SpecifyKind(TimeZoneInfo.ConvertTime(utcDateTime, sourceTZ, destinazionTZ), DateTimeKind.Local);
            }
        
            public static DateTime GetCurrentDateTimeInZone(string destinationZoneIdentifier)
            {
              TimeZoneInfo sourceTZ = TimeZoneInfo.FindSystemTimeZoneById("UTC");
              TimeZoneInfo destinazionTZ = TimeZoneInfo.FindSystemTimeZoneById(destinationZoneIdentifier);
        
              return DateTime.SpecifyKind(TimeZoneInfo.ConvertTime(DateTime.UtcNow, sourceTZ, destinazionTZ), DateTimeKind.Local);
            }
          }
        

        【讨论】:

          猜你喜欢
          • 2012-10-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-15
          • 1970-01-01
          • 2016-07-29
          • 2012-02-18
          • 2011-06-13
          相关资源
          最近更新 更多