考虑夏令时从一个时区转换到另一个时区

问题描述 投票:0回答:5

我想将日期时间从一个时区转换为另一个时区。为此,我需要将区域 id 传递给方法 FindSystemTimeZoneById。但我没有这些信息,需要通过使用 switch-case 来确定。
在这里我还需要考虑夏令时。但为了确定某个时间是否处于夏令时,我需要事先获得该区域 ID。
有没有办法在没有区域 ID 的情况下确定时间是否处于夏令时。我的服务器位于区域 1,我想将时间转换到区域 2。

这是片段:

public DateTime ConvertToDestTime(DateTime currentTime, string sourceTimeZoneUtc, string serverTimeZoneUtc)
    {
        TimeZoneInfo sourceTimeZone = TimeZoneInfo.FindSystemTimeZoneById(ReturnTimeZoneString(sourceTimeZoneUtc));
        TimeZoneInfo serverTimeZone = TimeZoneInfo.FindSystemTimeZoneById(ReturnTimeZoneString(serverTimeZoneUtc));
        DateTime serverTime = TimeZoneInfo.ConvertTime(currentTime, sourceTimeZone, serverTimeZone);
        return serverTime;
    }

    private string ReturnTimeZone(string utcOffset)
    {
        string timezone = string.Empty;
        string isDaylight = //need to determine whether time is in DST here

        if (isDaylight == "N")
        {
            switch (utcOffset)
            {
                case "-04:00":
                    timezone = "Atlantic Standard Time";
                    break;
                case "-05:00":
                    timezone = "Eastern Standard Time";
                    break;

            }
        }
        else
        {
            switch (utcOffset)
            {
                case "-04:00":
                    timezone = "Eastern Standard Time"; 
                    break;
                case "-05:00":
                    timezone = "Central America Standard Time";
                    break;                    
            }
        }

        return timezone;
c# timezone dst
5个回答
2
投票

将源时间转换为 UTC 时间。

string sourceTimeZone="Atlantic Standard Time;
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(sourceTimeZone);
DateTime sourceUTCTime = TimeZoneInfo.ConvertTimeToUtc(currentTime, timeZoneInfo);

然后使用转换后的 UTC 时间获取目的地时间,如下所示,

string destinationTimeZone="India Standard Time";
TimeZoneInfo destTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(destinationTimeZone);
DateTime destinationUTCTime = TimeZoneInfo.ConvertTimeFromUtc(sourceUTCTime, destTimeZoneInfo);

希望这有帮助!!!


0
投票

查看 Microsoft 的“永恒”文章 在 .NET Framework 中使用 DateTime 进行编码最佳实践

这篇文章可能已经有几年了,但原理和问题场景仍然是今天的主题。

有专门的章节介绍处理夏令时

通过在之前将您的本地时间视图转换为通用时间 进行计算,您就可以克服时间问题 准确度。

因此,请先将本地时间转换为 UTC 格式,然后再转换为目标时间格式。


0
投票

您无法可靠地执行此类反向映射。任何特定偏移量都可能落入两个可能的时区。

  • 请参阅 时区标签 wiki 中的“TimeZone != Offset”。

  • 另请参阅所有可能使用

    -04:00
    的地方

  • 最后,请认识到,由于北美的每个时区都会回退到各自的当地时间,因此某些值同时由两个时区共享。

    例如,

    2014-11-02T01:00:00-05:00
    可能属于 美国中部时间 (CDT) 或美国东部时间 (EST),如此处所示


0
投票
一个有点老的问题,但可能有人会喜欢下面的扩展

public static class DateTimeExtension { public static DateTime ConvertBetweenTimeZones(this DateTime d, string sourceTimeZone, string destinationTimeZone) { var tziSource = TimeZoneInfo.FindSystemTimeZoneById(sourceTimeZone); var tziDestination = TimeZoneInfo.FindSystemTimeZoneById(destinationTimeZone); var utcDate = TimeZoneInfo.ConvertTimeToUtc(d, tziSource); return TimeZoneInfo.ConvertTimeFromUtc(utcDate, tziDestination); } }
还有一些单元测试:

[TestClass] public class DateTimeTests { [TestMethod] public void ConvertBetweenTimeZonesTest() { var dateTime = new DateTime(2023, 1, 27, 21, 0, 0); var sourceTimeZone = "Central European Standard Time"; var destTimeZone = "UTC-02"; var dateResult = dateTime.ConvertBetweenTimeZones(sourceTimeZone, destTimeZone); var expectedDate = new DateTime(2023, 1, 27, 18, 0, 0); Assert.AreEqual(expectedDate, dateResult); } } [TestClass] public class TimeZoneInfoTests { [TestMethod] public void ConvertBetweenTimeZonesTest() { var timeZone = "Central European Standard Time"; var tzi = TimeZoneInfo.FindSystemTimeZoneById(timeZone); Assert.AreEqual("UTC+01:00", tzi.GetShortName()); } }
    

0
投票
Jarek,您的解决方案中缺少方法:

public static String GetShortName(this TimeZoneInfo info) { return info.DisplayName.Split('(')[1].Split(')')[0]; }
    
© www.soinside.com 2019 - 2024. All rights reserved.