locked
DateTime.UtcNow - How to get Local Time (Answered) RRS feed

  • Question

  •  

    Hello,

     

    I'm endeavoring to localize datetime.  To that end, I'm stepping through with DateTime.UtcNow, which is giving bad data if my local machine clock is changed back to DST dates on the calendar.

     

    Assuming: currently 09:37 AM PT

     

    GOOD

    If calendar set to today, 11/19/07.  DateTime.UtcNow gives me 17:37 PM UTC (8 hour offset)

     

    BUT...

     

    BAD

    If I set my calendar back to 8/19/07.  DateTime.UtcNow gives me 16:37 PM UTC (7 hour offset)

     

    UTC time should not reflect DST because it does not observe it!!  UTC should not take into consideration my local calendar, and should return 17:37 PM UTC regardless of whether my calendar considers DST.

     

    Please advise!

     

    Thanks,

    John

     

     

    Monday, November 19, 2007 7:09 PM

Answers

  • Hi John,

    DateTime.UtcNow just adds an offset to the local system time. And the offset is determined by the time zone and whether current datatime is in the daylight saving time period.

    You can get valuable information at:

    http://support.microsoft.com/kb/932955/en-us

     

    Thursday, November 22, 2007 8:58 AM
  • Yes, as the earth rotates, since I observe daylight savings time, 12:36 pm on 7/28/07 was the same time of day as 11:36 am today.  UTC is the time according to the stars in the universe.  It is also the time to which the system clock on my computer is referenced. (Actually the reference is 1/1/0001 12:00 am at Greenwich, England)  The time displayed on my computer is the time according to the politicians in Washington, D.C. and Columbus, Ohio.

    Wednesday, November 28, 2007 6:38 PM

All replies

  • Could you check that the "Automatically adjust clock for daylight saving changes" checkbox is set properly in the Time Zone settings for that computer.

     

    When you moved the date backwards, the system needed to know whether or not your time zone observed DST to properly set the clock (which in Windows is, in fact, a UTC clock).

    Monday, November 19, 2007 8:03 PM
  • Thank you for your response.  Yes, the checkbox is checked with the label, "Automatically adjust clock for DST".

     

    Thanks for looking into this,

    John

    Tuesday, November 20, 2007 2:24 PM
  • Hi John,

    DateTime.UtcNow just adds an offset to the local system time. And the offset is determined by the time zone and whether current datatime is in the daylight saving time period.

    You can get valuable information at:

    http://support.microsoft.com/kb/932955/en-us

     

    Thursday, November 22, 2007 8:58 AM
  • Thank you for your reply.

     

    This is precisely my problem.  The content in the link you provided declares, "UTC is not subject to local time zones or to DST."  Therefore, it is my expectation that DateTime.UTCNow should NOT "just add an offset to the local system time" nor should it consider DST.  Because UTC time, as it exists, where it exists, neither considers local time nor DST.

     

    To the best of my understanding, THIS IS A BIG BUG.

     

    Please advise!

     

    Thank you for your expertise. 

    Tuesday, November 27, 2007 3:44 PM
  • No, I do not think that it adds an offset.  I would think that it calls the GetSystemTime API which returns the UTC time.  See http://msdn2.microsoft.com/en-us/library/ms724390.aspx for information on this API.

     

    The difficulty lies in the Time Control Panel.  The UI does not provide you a straight path into SetSystemTime.  Instead, it forces you to enter a local time.  Then, it needs to apply an offset to get the UTC time so that it can call SetSystemTime.  The offset to use depends on (i.e., is a function of) the date and time entered, the time zone selected, and whether or not the DST checkbox is checked in the user interface.

    Tuesday, November 27, 2007 6:43 PM
  • The issue is reproduceable.  Simply set DateTime.UTCNow, then step through it twice.  Once through for today, then set your system calendar back to a date in the summer and try again.  You'll see the DST offset is applied to what is supposed to be UTC time.

     

    I'm fine with DST being applied to DateTime.Now, but DateTime.UTCNow should remain constant as it is a neutral standard which we offset from no matter what day of the year it is and no matter where we are.

     

    If UTC does not remain constant, it means that our localization calculations in code will always be tied to the local settings of the server the code runs on, which is subject to change.

     

     

    Wednesday, November 28, 2007 3:39 PM
  • The test you are performing is invalid.  You cannot use the control panel to change the date/time unless the time zone and DST checkbox are chosen correctly.  That control panel converts the date and time you enter to a UTC time and then calls the SetSystemTime API with that UTC time.  The UTC time to be set is a function of the specific date and time, time zone selection, and DST checkbox.  If any of these are wrong, the UTC time might be set incorrectly.

     

    If you are familiar with C, you could try calling the SetSystemTime API directly.  Then, you can set the UTC time directly and I strongly suspect you will not see any irregularity.

    Wednesday, November 28, 2007 4:29 PM
  • Right now it is 11:36 am on my clock.  UTCNow returns: 4:36 pm.  If I set my time to the same time of day on July 28, 2007, 12.36 pm, UTCNow returns 4.36 pm.  It seems consistent to me.

     

    Wednesday, November 28, 2007 4:40 PM
  • Thank you for your reply, however, I'm not quite understanding why the test is invalid.

     

    I only changed the date on the calendar.  The time and the time zone selection remains the same, as does the checkbox that says "Automatically adjust for Daylight Savings". 

     

    I do not change anything but the date.  How is this any different, if it were presently that date?

     

    Thank you for any insight you may offer.

    Wednesday, November 28, 2007 4:42 PM
  • JohnWein,

     

    Are you saying that 11/28/07 11:36 am is the same time of day as 7/28/07 12:36 pm? 

     

    Perhaps that's the source of my confusion in testing this.

     

    Thanks,

    John

    Wednesday, November 28, 2007 4:46 PM
  • One of those dates is in the Daylight Saving Time range of dates and the other is not.

     

    Like I said, the Windows clock is in UTC, but the time that is actually set when you use that control panel is a function of several things and this is one of them.

    Wednesday, November 28, 2007 5:50 PM
  • Yes, as the earth rotates, since I observe daylight savings time, 12:36 pm on 7/28/07 was the same time of day as 11:36 am today.  UTC is the time according to the stars in the universe.  It is also the time to which the system clock on my computer is referenced. (Actually the reference is 1/1/0001 12:00 am at Greenwich, England)  The time displayed on my computer is the time according to the politicians in Washington, D.C. and Columbus, Ohio.

    Wednesday, November 28, 2007 6:38 PM
  • JohnW, thank you, you're a genius.  Both the criteria and expected outcome of my test were wrong.  For anyone out there testing DST/UTC offsets...

     

    If it is 8:12 AM PT:

     

    11/29/07 8:12 AM PDT is the same time of day in UTC terms as 7/29/07 9:12 AM PST.

     

    Thanks for helping me see why that is in fact correct. 

     

    Since you all have been so helpful, I thought I'd share some code to help other folks who try to get local time.

     

    1.) DST Dates

    I use a DST table that contains start and end dates, on session init, I set a bool to see if the current date is between those dates to determine if we are currently observing DST.  I found the dates here:  http://webexhibits.org/daylightsaving/b.html

     

    2.) Locations/Offsets/Timezones

    I use a Locations table with 42,903 records of data I downloaded from http://www.zip-code-database.org/Download/DB/.

     

    I updated the table to include the following fields:

    Zip (i.e. 94530)

    City (i.e. San Diego)

    State (i.e. CA)

    OffsetStandardTime (i.e. -8)

    AbbrStandardTime (i.e. PST)

    AbbrDaylightTime (i.e. PDT)

    AbbrTimeZone (i.e. PT)

    ObservesDST (i.e. True)

     

    3.) Local Time Method

     

    public static String GetLocalTime(String zipCode)

    {

     String result = String.Empty;

     try

     {

       if (!String.IsNullOrEmpty(zipCode))

       {

          AdminService ws = CommonUtility.GetWebService<AdminService>();

          MMLocationDefData location = ws.GetLocation(zipCode);

          if (location != null)

          {

            short utcOffset = location.OffsetStandardTime.GetValueOrDefault(0);

            String timeZone = location.AbbrStandardTime;

     

            if (location.ObservesDST.GetValueOrDefault(false)) //if zipcode observes dst

            {

              if (SessionInfo.isDST) //if USA is currently observing dst for the current calendar year

              {

                timeZone = location.AbbrDaylightTime;

                utcOffset++; //i.e. PDT -8 + 1 = -7

              }

            }

     

            DateTime utcTime = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc);

            DateTime localTime = DateTime.SpecifyKind(utcTime.AddHours(utcOffset), DateTimeKind.Local);

     

            result = localTime.ToShortTimeString().Trim() + " " + timeZone;

          }

       }

    }

    catch (Exception ex)

    {

    ExceptionManager.Publish(ex);

    }

    return result;

    }

     

     

     

     

    Thursday, November 29, 2007 4:34 PM