【问题标题】:Convert UTC DateTime to another Time Zone将 UTC DateTime 转换为另一个时区
【发布时间】:2011-02-02 15:26:46
【问题描述】:

我有一个来自数据库记录的 UTC 日期时间值。我还有一个用户指定的时区(TimeZoneInfo 的一个实例)。如何将该 UTC DateTime 转换为用户的本地时区?另外,如何确定用户指定的时区当前是否正在遵守 DST?我正在使用 .NET 3.5。

谢谢, 标记

【问题讨论】:

    标签: c# datetime timezone dst


    【解决方案1】:

    最好的方法就是使用TimeZoneInfo.ConvertTimeFromUtc

    // you said you had these already
    DateTime utc = new DateTime(2014, 6, 4, 12, 34, 0);
    TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
    
    // it's a simple one-liner
    DateTime pacific = TimeZoneInfo.ConvertTimeFromUtc(utc, tzi);
    

    唯一的问题是传入的DateTime 值可能没有DateTimeKind.Local 类型。它必须是 UtcUnspecified

    【讨论】:

    • 呃,如果他们只是让 Convert 函数成为 tzi 实例的成员而不是静态的,我就不必来 stackoverflow 来解决这个问题了。
    【解决方案2】:

    如果要将 DateTimeOffset 转换为另一个 DateTimeOffset,可以使用 TimeZoneInfo 中的专用函数:

    DateTimeOffset newTime = TimeZoneInfo.ConvertTime(
        DateTimeOffset.UtcNow, 
        TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")
    );
    

    【讨论】:

      【解决方案3】:

      看看DateTimeOffset 结构:

      // user-specified time zone
      TimeZoneInfo southPole =
          TimeZoneInfo.FindSystemTimeZoneById("Antarctica/South Pole Standard Time");
      
      // an UTC DateTime
      DateTime utcTime = new DateTime(2007, 07, 12, 06, 32, 00, DateTimeKind.Utc);
      
      // DateTime with offset
      DateTimeOffset dateAndOffset =
          new DateTimeOffset(utcTime, southPole.GetUtcOffset(utcTime));
      
      Console.WriteLine(dateAndOffset);
      

      对于 DST,请参阅 TimeZoneInfo.IsDaylightSavingTime 方法。

      bool isDst = southpole.IsDaylightSavingTime(DateTime.UtcNow);
      

      【讨论】:

      • 我必须多走一步才能得到我的当地时间: var offset = tzi.GetUtcOffset(utcTime); var siteLocalTime = utcTime.Add(offset); return siteLocalTime.ToString("MM/dd/yyyy HH:mm");
      • 此代码无法编译。该时区 ID 不存在,如果将其替换为有效的 ID,则会收到有关 The UTC Offset for Utc DateTime instances must be 0 的错误。
      • 为避免 dateAndOffset 出错选择 DateTime cstTime = utcTime.AddTicks(southPole.BaseUtcOffset.Ticks);
      【解决方案4】:

      南极洲的答案仅适用于与 UTC 匹配的时区。我对这个DateTimeOffset 函数感到非常痛苦,经过数小时的反复试验,我设法生成了一个适用于所有时区的实用转换扩展函数。

      static public class DateTimeFunctions
      {
          static public DateTimeOffset ConvertUtcTimeToTimeZone(this DateTime dateTime, string toTimeZoneDesc)
          {
              if (dateTime.Kind != DateTimeKind.Utc) throw new Exception("dateTime needs to have Kind property set to Utc");
              var toUtcOffset = TimeZoneInfo.FindSystemTimeZoneById(toTimeZoneDesc).GetUtcOffset(dateTime);
              var convertedTime = DateTime.SpecifyKind(dateTime.Add(toUtcOffset), DateTimeKind.Unspecified);
              return new DateTimeOffset(convertedTime, toUtcOffset);
          }
      }
      

      例子:

      var currentTimeInPacificTime = DateTime.UtcNow.ConvertUtcTimeToTimeZone("Pacific Standard Time");
      

      【讨论】:

      • static public?异端,烧死女巫
      【解决方案5】:
             //  TO get Currrent Time in current Time Zone of your System
      
              var dt = DateTime.Now;
      
              Console.WriteLine(dt);
      
              // Display Time Zone of your System
      
              Console.WriteLine(TimeZoneInfo.Local);
      
              // Convert Current Date Time to UTC Date Time
      
              var utc = TimeZoneInfo.ConvertTimeToUtc(dt, TimeZoneInfo.Local);
      
              Console.WriteLine(utc);
      
              // Convert UTC Time to Current Time Zone
      
              DateTime pacific = TimeZoneInfo.ConvertTimeFromUtc(utc, TimeZoneInfo.Local);
      
              Console.WriteLine(pacific);
      
              Console.ReadLine();
      

      【讨论】:

        【解决方案6】:

        还有一个问题:如果您在 Linux 服务器上运行代码,则需要使用 Linux 系统来命名时区。例如,“Central Standard Time”将是“America/Chicago”。 tz 列表在这里:https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

        这是一个使用 isWindows 开关的示例:

        public static class DateTimeHelper
        {
            public static string ConvertUtcToCst(this string dateTimeString)
            {
                if (string.IsNullOrWhiteSpace(dateTimeString))
                {
                    return string.Empty;
                }
        
                if (DateTime.TryParse(dateTimeString, out DateTime outputDateTime))
                {
                    try
                    {
                        var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
                        TimeZoneInfo cstZone = null;
                        if (isWindows)
                        {
                            cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
                        }
                        else
                        {
                            cstZone = TimeZoneInfo.FindSystemTimeZoneById("America/Chicago");
                        }
        
                        var cstDateTime = TimeZoneInfo.ConvertTimeFromUtc(outputDateTime, cstZone);
                        return cstDateTime.ToString();
                    }
                    catch (TimeZoneNotFoundException)
                    {
                        return "The registry does not define the Central Standard Time zone.";
                    }
                    catch (InvalidTimeZoneException)
                    {
                        return "Registry data on the Central Standard Time zone has been corrupted.";
                    }
                    catch (Exception ex)
                    {
                        return $"Error :: {ex.Message} :: {ex.ToString()}";
                    }
                }
        
                return string.Empty;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2011-02-11
          • 2019-06-04
          • 2015-10-16
          • 2013-04-07
          • 2016-09-28
          • 2012-08-06
          • 1970-01-01
          • 1970-01-01
          • 2012-12-05
          相关资源
          最近更新 更多