5

我正在尝试将转换时间转换为用户的时区,但我没有 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);
}
4

4 回答 4

6

您可以使用以下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);
于 2013-08-17T20:03:01.700 回答
1

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

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

于 2013-08-17T20:10:52.290 回答
1

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

那么你就没有进行正确转换所需的东西了。阅读时区标签 wiki中的“时区!= 偏移量” 。

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

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

现在您有了通常所说的 XY 问题。您不需要单独使用偏移量。

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

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

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

于 2013-08-17T20:19:26.000 回答
-1

有包含"Pacific Standard Time"的时区字符串。完整列表可在此处找到。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)));
}
于 2013-08-17T20:10:07.350 回答