Convert UTC/GMT time to local time

前端 未结 11 982
情深已故
情深已故 2020-11-22 04:39

We are developing a C# application for a web-service client. This will run on Windows XP PC\'s.

One of the fields returned by the web service is a DateTime field. Th

相关标签:
11条回答
  • 2020-11-22 05:05

    I'd look into using the System.TimeZoneInfo class if you are in .NET 3.5. See http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx. This should take into account the daylight savings changes correctly.

    // Coordinated Universal Time string from 
    // DateTime.Now.ToUniversalTime().ToString("u");
    string date = "2009-02-25 16:13:00Z"; 
    // Local .NET timeZone.
    DateTime localDateTime = DateTime.Parse(date); 
    DateTime utcDateTime = localDateTime.ToUniversalTime();
    
    // ID from: 
    // "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Time Zone"
    // See http://msdn.microsoft.com/en-us/library/system.timezoneinfo.id.aspx
    string nzTimeZoneKey = "New Zealand Standard Time";
    TimeZoneInfo nzTimeZone = TimeZoneInfo.FindSystemTimeZoneById(nzTimeZoneKey);
    DateTime nzDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, nzTimeZone);
    
    0 讨论(0)
  • 2020-11-22 05:10

    I know this is an older question, but I ran into a similar situation, and I wanted to share what I had found for future searchers, possibly including myself :).

    DateTime.Parse() can be tricky -- see here for example.

    If the DateTime is coming from a Web service or some other source with a known format, you might want to consider something like

    DateTime.ParseExact(dateString, 
                       "MM/dd/yyyy HH:mm:ss", 
                       CultureInfo.InvariantCulture, 
                       DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)
    

    or, even better,

    DateTime.TryParseExact(...)
    

    The AssumeUniversal flag tells the parser that the date/time is already UTC; the combination of AssumeUniversal and AdjustToUniversal tells it not to convert the result to "local" time, which it will try to do by default. (I personally try to deal exclusively with UTC in the business / application / service layer(s) anyway. But bypassing the conversion to local time also speeds things up -- by 50% or more in my tests, see below.)

    Here's what we were doing before:

    DateTime.Parse(dateString, new CultureInfo("en-US"))
    

    We had profiled the app and found that the DateTime.Parse represented a significant percentage of CPU usage. (Incidentally, the CultureInfo constructor was not a significant contributor to CPU usage.)

    So I set up a console app to parse a date/time string 10000 times in a variety of ways. Bottom line:
    Parse() 10 sec
    ParseExact() (converting to local) 20-45 ms
    ParseExact() (not converting to local) 10-15 ms
    ... and yes, the results for Parse() are in seconds, whereas the others are in milliseconds.

    0 讨论(0)
  • 2020-11-22 05:10

    Don't forget if you already have a DateTime object and are not sure if it's UTC or Local, it's easy enough to use the methods on the object directly:

    DateTime convertedDate = DateTime.Parse(date);
    DateTime localDate = convertedDate.ToLocalTime();
    

    How do we adjust for the extra hour?

    Unless specified .net will use the local pc settings. I'd have a read of: http://msdn.microsoft.com/en-us/library/system.globalization.daylighttime.aspx

    By the looks the code might look something like:

    DaylightTime daylight = TimeZone.CurrentTimeZone.GetDaylightChanges( year );
    

    And as mentioned above double check what timezone setting your server is on. There are articles on the net for how to safely affect the changes in IIS.

    0 讨论(0)
  • 2020-11-22 05:11

    DateTime objects have the Kind of Unspecified by default, which for the purposes of ToLocalTime is assumed to be UTC.

    To get the local time of an Unspecified DateTime object, you therefore just need to do this:

    convertedDate.ToLocalTime();
    

    The step of changing the Kind of the DateTime from Unspecified to UTC is unnecessary. Unspecified is assumed to be UTC for the purposes of ToLocalTime: http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspx

    0 讨论(0)
  • 2020-11-22 05:13

    For strings such as 2012-09-19 01:27:30.000, DateTime.Parse cannot tell what time zone the date and time are from.

    DateTime has a Kind property, which can have one of three time zone options:

    • Unspecified
    • Local
    • Utc

    NOTE If you are wishing to represent a date/time other than UTC or your local time zone, then you should use DateTimeOffset.


    So for the code in your question:

    DateTime convertedDate = DateTime.Parse(dateStr);
    
    var kind = convertedDate.Kind; // will equal DateTimeKind.Unspecified
    

    You say you know what kind it is, so tell it.

    DateTime convertedDate = DateTime.SpecifyKind(
        DateTime.Parse(dateStr),
        DateTimeKind.Utc);
    
    var kind = convertedDate.Kind; // will equal DateTimeKind.Utc
    

    Now, once the system knows its in UTC time, you can just call ToLocalTime:

    DateTime dt = convertedDate.ToLocalTime();
    

    This will give you the result you require.

    0 讨论(0)
  • 2020-11-22 05:14

    I had the problem with it being in a data set being pushed across the wire (webservice to client) that it would automatically change because the DataColumn's DateType field was set to local. Make sure you check what the DateType is if your pushing DataSets across.

    If you don't want it to change, set it to Unspecified

    0 讨论(0)
提交回复
热议问题