【问题标题】:How to convert string offset to timespan in c#如何在c#中将字符串偏移量转换为时间跨度
【发布时间】:2013-08-20 00:15:13
【问题描述】:

我正在尝试将转换时间转换为用户的时区,但我没有 Windows 时区字符串,例如“太平洋标准时间”。我所拥有的只是一个字符串偏移量,例如“-07:00”。看起来我需要创建一个时间跨度。是手动解析此字符串的唯一方法吗?似乎应该有一种方法可以使用字符串偏移量转换时间,但也许我遗漏了一些东西。

我有这个,但它需要时区。我正在尝试修改它以改用偏移量,但您可以看到为转换创建的时间跨度,我需要将我的偏移量设置为时间跨度。

static void Main(string[] args)
{
    var currentTimeInPacificTime = ConvertUtcTimeToTimeZone(DateTime.UtcNow, "Pacific Standard Time");
    //TimeSpan ts = new TimeSpan("-07:00");
    Console.ReadKey();
}

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

【问题讨论】:

    标签: c# timezone timespan


    【解决方案1】:

    您可以只使用TimeSpan.Parse 方法:

    TimeSpan ts = TimeSpan.Parse("-07:00");
    Console.WriteLine(ts);   // -07:00:00
    

    小心去掉前导的“+”,因为 TimeSpan.Parse 将在此处失败。 “+01:00”不正确,但“01:00”有效。

    或者如果你想更安全一点,试试TimeSpan.TryParse 方法:

    TimeSpan ts;
    if (TimeSpan.TryParse("-07:00", out ts))
        Console.WriteLine(ts);   // -07:00:00
    

    当然,如果您只想将 UTC 日期/时间转换为本地日期/时间,您可以这样做:

    DateTime localDateTime = utcDateTime.ToLocalTime();
    

    或将其转换为任何时区:

    TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(toTimeZoneDesc);
    DateTime localDateTime = TimeZoneInfo.ConvertTime(utcDateTime, tzi);
    

    【讨论】:

    • 谢谢!也很简单。没想到要找 parse 方法。
    • TimeSpan.Parse 对问题的那一部分是正确的,但要小心.ToLocalTime(),因为那将在它运行的计算机的时区 - 这可能是其他时区的服务器。最后一个代码块是正确的,但他说他没有要输入的时区 id。
    • 如果您的偏移字符串包含+ 字符,这将不起作用。这必须先删除。
    【解决方案2】:

    对于更复杂/非标准的格式,您还可以使用TimeSpan.ParseExact(String, String, IFormatProvider),其中第二个字符串是Custom TimeSpan Format String

    API 信息可在 msdn.microsoft.com 上获得,并链接到 above.linked。

    【讨论】:

      【解决方案3】:

      我正在尝试将转换时间转换为用户的时区,但我没有 Windows 时区字符串,例如“太平洋标准时间”。我所拥有的只是一个字符串偏移量,例如“-07:00”。

      那么您没有进行正确转换所需的东西。阅读timezone tag wiki 中的“时区!= 偏移量”。

      了解"Pacific Standard Time" 值是用于美国太平洋时间的TimeZoneInfo 对象的.Id 很重要。它涵盖太平洋标准时间 (UTC-8) 和太平洋夏令时间 (UTC-7)。

      我只有一个字符串偏移量,例如“-07:00”。看来我需要创建一个时间跨度。

      现在您有了通常所说的the XY Problem。您应该不需要单独使用偏移量。

      在您的代码中,调用了dateTime.Add(toUtcOffset)。在进行时区转换时,这是一个code smell,你做错了。您永远不必为了操纵时区而手动添加或减去时间。这应该保留用于实际更改您所谈论的时间。

      您应该做的是从您的用户那里收集一个实时时区 ID。 "Pacific Standard Time"TimeZoneInfo 一起使用,或者"America/Los_Angeles"Noda Time 等TZDB 实现一起使用。

      如果时区转换在您的上下文中并不重要,那么您可能只想收集完整的 DateTimeOffset 值,例如 2013-08-17T13:27:00.000-07:00

      【讨论】:

        【解决方案4】:

        有包含“太平洋标准时间”的时区字符串。完整列表可在此处找到。 http://www.xiirus.net/articles/article-_net-convert-datetime-from-one-timezone-to-another-7e44y.aspx

        任何 DateTime 对象都可以转换为某个时区 -

            TimeZoneInfo timeZoneInfo; 
            DateTime dateTime ; 
        
            //Set the time zone information to Pacific Standard Time
            timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"); 
            //Get date and time in US Mountain Standard Time 
            dateTime = TimeZoneInfo.ConvertTime(DateTime.Now, timeZoneInfo);
            //Print out the date and time
            Console.WriteLine(dateTime.ToString("yyyy-MM-dd HH-mm-ss")); 
        

        所以你的方法可以修改为 -

        static DateTimeOffset ConvertUtcTimeToTimeZone(DateTime dateTime, string toTimeZoneDesc)
        {
           return new DateTimeOffset(TimeZoneInfo.ConvertTime(dateTime, TimeZoneInfo.FindSystemTimeZoneById(toTimeZoneDesc)));
        }
        

        【讨论】:

        • 您通过使用DateTime.Now 并再次将Unspecified 类型的DateTime 传递给DateTimeOffset 构造函数,让本地时区潜入转换。
        • @MattJohnson - 这只是一个例子,对大多数人来说,一个提示就足够了。
        • 也许是一个如何做到这一点的例子......而且大多数人只会复制粘贴而不考虑它。
        • 让我明确一点,最后两行应该合并为一行:return TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, timeZoneInfo);。这将返回一个DateTimeOffset,其中时间和偏移量对于提供的timeZoneInfo 是正确的。
        • 有一些拼写错误,除此之外我看不出代码有任何问题。
        猜你喜欢
        • 1970-01-01
        • 2018-11-26
        • 1970-01-01
        • 1970-01-01
        • 2021-08-21
        • 1970-01-01
        • 2021-03-02
        相关资源
        最近更新 更多