【问题标题】:c# DataTime: Assume EST convert to GTMc# DateTime: 假设 EST 转换为 GMT
【发布时间】:2016-09-02 18:25:59
【问题描述】:

我有一个在纽约运行的服务器,它以当地时间将 DateTime 保存到数据库中。

然后,我有一个在 GMT 时区运行的客户端应用程序,它需要在纽约本地时间保存一个 DateTime 我可以使用:

TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"))

或者我需要考虑夏令时?

现在在我的 UI 中,我需要显示 2 列。 1)数据库中的日期时间和数据库中的日期时间转换为格林威治标准时间

我该怎么做?

【问题讨论】:

  • 如果真的在 EST,你可以加 5 个小时。但我怀疑它更有可能在东部时间 - 有时是美国东部时间,有时是美国东部时间。那时,您需要准确地知道哪个东部时间,因为不同版本的 ET 在不同时间过渡,或者在历史上做过......
  • 谢谢乔恩。我不需要考虑夏令时而不是仅仅增加 5 小时吗?
  • 您拥有的代码实际上会将 DST 考虑在内。至少当我前段时间在这里测试它时确实如此。这很容易测试。使用您的代码转换属于 EST 的日期/时间和属于 EDT 的日期/时间。您应该会看到不同的时间增量。
  • 对,已经开始在这里写答案,但后来不得不接听电话。我在这里唯一要补充的是,通过记录当地时间,您会丢失信息:您将无法区分 11 月 5 日星期日凌晨 1:30 的第一次出现和第二次出现之间的区别。你应该弄清楚在这种情况下你想做什么。
  • 您应该永远将本地时间存储在数据库中。这是一个非常糟糕的想法。正如评论中所解释的,它可能会导致一些歧义。此外,如果服务器曾经移动,代码可能会使用另一个时区,所以所有时间都会因为不正确。这是一个糟糕的设计决策,最好的办法是修改数据并修复代码。

标签: c# .net datetime


【解决方案1】:

TimeZoneInfo 类应该可以满足您的需求。

var date = (DateTime)reader[0]; // Retrieve data from database however you normally get it

var est = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var utcTime = TimeZoneInfo.ConvertTimeToUtc(date, est);

var localTime = utcTime.ToLocalTime();

编辑:您修改了您的问题以表明您已经查看了 TimeZoneInfo,因此这不再增加太多内容。但是,要解决 Jon 提到的时间不明确问题,请查看 IsAmbiguousTime()GetAmbiguousTimeOffsets() 方法以检测无法明确转换的值。

【讨论】:

    【解决方案2】:

    这是一个示例,表明它应该可以按预期工作。也就是说,它将进行 DST 转换。

    DateTime dt1 = new DateTime(2016, 06, 01, 08, 00, 00, DateTimeKind.Unspecified);  // Daylight saving time
    DateTime dt2 = new DateTime(2016, 12, 01, 08, 00, 00, DateTimeKind.Unspecified);  // Standard time
    
    var dt1Converted = TimeZoneInfo.ConvertTimeToUtc(dt1,
        TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"));
    var dt2Converted = TimeZoneInfo.ConvertTimeToUtc(dt2,
        TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"));
    
    var diff1 = (dt1Converted - dt1).TotalHours;
    var diff2 = (dt2Converted - dt2).TotalHours;
    
    Console.WriteLine($"dt1: {dt1}, converted: {dt1Converted}, diff: {diff1}");
    Console.WriteLine($"dt2: {dt2}, converted: {dt2Converted}, diff: {diff2}");
    

    输出:

    dt1: 2016-06-01 08:00:00, converted: 2016-06-01 12:00:00, diff: 4
    dt2: 2016-12-01 08:00:00, converted: 2016-12-01 13:00:00, diff: 5
    

    【讨论】:

      【解决方案3】:

      您是否有机会将其更改为使用 DateTimeOffset ?它旨在解决所有这些问题

      【讨论】:

        猜你喜欢
        • 2017-08-26
        • 1970-01-01
        • 2011-07-26
        • 2014-06-25
        • 2020-12-14
        • 1970-01-01
        • 2023-03-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多