How to convert string offset to timespan in c#

2019-06-24 12:12发布

I'm trying to convert the convert time to the user's time zone, but I don't have the windows time zone string such as "Pacific Standard Time". All I have is a string offset such as "-07:00". Looks like I need to create a timespan. Is the only way to parse this string manually?. Seems like there should be a way to convert a time using a string offset, but maybe I am missing something.

I have this but it requires the timezone. I'm trying to modify it to use the offset instead, but you can see the timespan that is created for the conversion and I need to get my offset to the timespan.

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条回答
疯言疯语
2楼-- · 2019-06-24 12:20

There are time zone strings which includes "Pacific Standard Time". The complete list can be found here. http://www.xiirus.net/articles/article-_net-convert-datetime-from-one-timezone-to-another-7e44y.aspx

Any DateTime object can be converted to some timezone -

    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")); 

So you method can be modified as -

static DateTimeOffset ConvertUtcTimeToTimeZone(DateTime dateTime, string toTimeZoneDesc)
{
   return new DateTimeOffset(TimeZoneInfo.ConvertTime(dateTime, TimeZoneInfo.FindSystemTimeZoneById(toTimeZoneDesc)));
}
查看更多
ゆ 、 Hurt°
3楼-- · 2019-06-24 12:27

You can just use the TimeSpan.Parse method:

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

Or if you want be a little more safe, try the TimeSpan.TryParse method:

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

But of course if all you want to do is convert a UTC date/time to a local date/time, you can just do this:

DateTime localDateTime = utcDateTime.ToLocalTime();

Or to convert it to any timezone:

TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(toTimeZoneDesc);
DateTime localDateTime = TimeZoneInfo.ConvertTime(utcDateTime, tzi);
查看更多
放荡不羁爱自由
4楼-- · 2019-06-24 12:33

For more complicated/non-standard formats you can also use TimeSpan.ParseExact(String, String, IFormatProvider), where the second String is a Custom TimeSpan Format String.

API information is available at msdn.microsoft.com, and is linked above.linked.

查看更多
做个烂人
5楼-- · 2019-06-24 12:34

I'm trying to convert the convert time to the user's time zone, but I don't have the windows time zone string such as "Pacific Standard Time". All I have is a string offset such as "-07:00".

Then you don't have what you need to make the correct conversion. Read "Time Zone != Offset" in the timezone tag wiki.

It is important to understand that the "Pacific Standard Time" value is the .Id for the TimeZoneInfo object that is used for US Pacific Time. It covers both Pacific Standard Time (UTC-8) and Pacfic Daylight Time (UTC-7).

All I have is a string offset such as "-07:00". Looks like I need to create a timespan.

Now you have what is commonly called the XY Problem. You shouldn't have any need to work with the offset by itself.

In your code, there is a call to dateTime.Add(toUtcOffset). When doing time zone conversions, this is a code smell that you are doing it wrong. You should never have to manually add or subtract time just to manipulate time zones. That should be reserved for actually changing the moment in time you are talking about.

What you should be doing is to collect a real time zone id from your user. Either "Pacific Standard Time" for use with TimeZoneInfo, or "America/Los_Angeles" for use with a TZDB implementation like Noda Time.

If time zone conversions aren't important in your context, then you might just want to collect a full DateTimeOffset value such as 2013-08-17T13:27:00.000-07:00 instead.

查看更多
登录 后发表回答