【问题标题】:How to represent the current UK time?如何表示当前的英国时间?
【发布时间】:2011-05-01 09:35:15
【问题描述】:

我在转换我的服务器和客户端之间的日期时遇到了一个问题,两者都在德国运行。客户端机器上的区域设置可以设置为英国或德国。我从服务器收到 CET 格式的日期,我需要在 UI 上将这个时间表示为英国时间。例如,从服务器收到的时间,例如 01/07/2010 01:00:00 在 UI 上应表示为 01/07/2010 00:00:00。我为此目的编写了一个转换器,但是在运行它时会出现 2 小时的时差。下面是代码,您能帮忙吗?

public class LocalToGmtConverter : IDateConverter
{
    private readonly TimeZoneInfo timeZoneInfo;

    public LocalToGmtConverter()
        : this(TimeZoneInfo.Local)
    {

    }
    public LocalToGmtConverter(TimeZoneInfo timeZoneInfo)
    {
        this.timeZoneInfo = timeZoneInfo;
    }

    public DateTime Convert(DateTime localDate)
    {
        var utcKind = DateTime.SpecifyKind(localDate, DateTimeKind.Utc);
        return utcKind;
    }

    public DateTime ConvertBack(object fromServer)
    {
        DateTime serverDate = (DateTime)fromServer;

        var utcOffset = timeZoneInfo.GetUtcOffset(serverDate);

        var uiTime = serverDate- utcOffset;

        return uiTime;

    }
}

【问题讨论】:

  • 您是从服务器获取德国时间还是格林威治标准时间?
  • 更好的方法有两个时间在 UTC 并根据需要转换为本地
  • GMT 现已失效,已被 UTC 取代。他们告诉我有区别,但据我所知,唯一的区别是它不是以地点命名的。也许不同之处在于它永远不会随着 DST 而变化,而 GMT 会变化。我不知道。
  • 等到本周末之后。由于英国时间将与 UTC 重合,因此转换将正常工作到明年 3 月。

标签: c# datetime


【解决方案1】:

这就是我的工作:

    var BritishZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");

    DateTime dt = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Unspecified);

    DateTime DateTimeInBritishLocal = TimeZoneInfo.ConvertTime(dt, TimeZoneInfo.Utc, BritishZone);

我需要添加 SpecifyKind 部分,否则 ConvertTime 会引发异常

【讨论】:

  • 不处理 BST(英国夏令时)并且示例的第 3 行缺少 var
  • 感谢@uniquelau 的提醒。现在应该可以工作了。
  • 没问题@noelicus,现在可以了!我检查了 LinqPad 中的代码 ?
【解决方案2】:

我知道问题是针对 C#,但如果您只想进行一次转换,您可以从 PowerShell 命令行执行此操作:

$d = [DateTime]::Parse("04/02/2014 17:00:00")
$gmt = [TimeZoneInfo]::FindSystemTimeZoneById("GMT Standard Time");
[TimeZoneInfo]::ConvertTime($d, $gmt, [TimeZoneInfo]::Local)

此脚本会将英国时间 17:00 转换为您当地的时区。 对我来说,那将是 CST。有趣的是,如果我将日期设置为 2014 年 3 月 27 日,结果会有所不同,因为英国夏令时的生效日期与美国不同。

【讨论】:

    【解决方案3】:

    处理当地时间的更好方法是将它们存储在统一的表示中,例如 UTC。

    因此,您可以将所有输入时间转换为 UTC(通过.ToUniversalTime()),并存储(或传输)其值。当您需要显示它时,只需使用.ToLocalTime() 转换回来。

    因此您无需知道哪个时区是原始值,并且可以轻松显示不同时区的存储值。

    您还可以避免遇到麻烦,因为您必须编写特定的逻辑来处理下一个时区的时间,试图弄清楚如何在所有可用的时间之间转换它们。

    【讨论】:

    • 我认为这里的问题是他不想要当地时间,他在德国 (CET) 并且想要显示英国 (GMT) 的时间。
    • @Steve Haigh,多亏了这一点,但他可以毫无问题地将值从 UTC 转换为他想要的任何时区。但是 OP 说从服务器接收和显示日期,所以我认为他的应用程序只能在不同的时区工作。
    【解决方案4】:

    我认为您正在转换为 UTC(而不是英国)时间。由于中欧仍有夏季时间(如果温度另有说明,则事件),到 10 月 31 日之前的时间差为 +2 小时。

    如果您知道您要从德国转换为英国(即夏季从 CEST 转换为 BST,冬季从 CET 转换为 GMT),为什么不只减去 1 小时?

    如果你想要英国的时区信息,你可以使用

    var britishZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
    

    然后你可以使用转换日期

    var newDate = TimeZoneInfo.ConvertTime(serverDate, TimeZoneInfo.Local, britishZone);
    

    【讨论】:

    • 是的,真正的 UTC 和英国时区(在 UI 中通常称为 UTC 都柏林、爱丁堡、里斯本、伦敦)不是一回事。您需要获取英国时区信息,这应该涵盖您的夏令时。
    • 仅供参考 GMT 不校正夏令时,因此例如现在它落后 1 小时。
    【解决方案5】:

    使用TimeZoneInfo.ConvertTime 将原始输入时区 (CET) 转换为目标时区 (UK)。

    public static DateTime ConvertTime(
        DateTime dateTime,
        TimeZoneInfo sourceTimeZone,
        TimeZoneInfo destinationTimeZone
    )
    

    MSDN 上的完整指南here

    时区之间的时间转换

    来自 MSDN 的修改代码示例:

    DateTime ceTime = new DateTime(2007, 02, 01, 08, 00, 00);
    try
    {
       TimeZoneInfo ceZone = TimeZoneInfo.FindSystemTimeZoneById("Central Europe Standard        Time");
       TimeZoneInfo gmtZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
       Console.WriteLine("{0} {1} is {2} GMT time.", 
               ceTime, 
               ceZone.IsDaylightSavingTime(ceTime) ? ceZone.DaylightName : ceZone.StandardName, 
               TimeZoneInfo.ConvertTime(ceTime, ceZone, gmtZone));
    }
    catch (TimeZoneNotFoundException)
    {
       Console.WriteLine("The registry does not define the required timezones.");
    }                           
    catch (InvalidTimeZoneException)
    {
       Console.WriteLine("Registry data on the required timezones has been corrupted.");
    }
    

    【讨论】:

      猜你喜欢
      • 2018-01-25
      • 2013-07-28
      • 2011-09-03
      • 2019-08-25
      • 1970-01-01
      • 1970-01-01
      • 2012-05-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多