none
Does WCF consider timezone history when serializing a datetime object? RRS feed

  • Question

  • Hi,

    It seems that .NET/WCF does not consider the timezone history when serializing datetime objects. We have a client in UTC+13 timezone (Auckland) and they came across an issue where an older date like - 1970/01/01 00:00:000 shows differently in Chrome/Firefox & Internet Explorer.

    After diagnosing this, we confirmed that .NET/WCF uses current timezone of UTC+13 when serializing the datetime object, whereas Chrome/Firefox considers the timezone history, which was UTC+12 during 1970/01/01 and therefore showed "Wed Dec 31 1969 23:00:00 GMT+1200 (New Zealand Daylight Time)". I.E used current timezone of UTC+13 and showed - Thu Jan 01 1970 00:00:00 GMT+1300 (New Zealand Daylight Time)

    So, is it possible to have both .NET/WCF & I.E consider timezone history? (maybe we have to install some kind of windows update?)

    Steps to replicate:

    1. Change your timezone to Auckland

    2. Create a simple WCF application & service which returns a datetime object whose value - 1970/01/01 00:00:000. Have the service exposed on json endpoint

    3. Open Chrome/Firefox, construct the date object 

    var utcTicksInSeconds = serviceResult.d.substring(serviceResult.d.indexOf("(") + 1, serviceResult.d.indexOf('+'))
            document.querySelector('input').value = new Date(parseInt(utcTicksInSeconds))

    you'll notice that date object is Wed Dec 31 1969 23:00:00 GMT+1200 (New Zealand Daylight Time), whereas in IE it is Thu Jan 01 1970 00:00:00 GMT+1300 (New Zealand Daylight Time).

    Thank you,

    Nagarjuna



    • Edited by Nagarjuna.B Tuesday, October 30, 2018 3:45 PM corrected a type to avoid any confusion, should serializing not deserializing
    Tuesday, October 30, 2018 10:43 AM

Answers

  • Just confirmed that both .NET/WCF & I.E do indeed consider timezone history, its just that the history was limited to only a few recent years.

    All the timezone history info is stored in the registry under Time Zones key

    Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\New Zealand Standard Time\Dynamic DST

    It is not exactly in readable/understandable format, but you can print out some understandable info using some c# code (see https://docs.microsoft.com/en-us/dotnet/api/system.timezoneinfo.adjustmentrule?view=netframework-4.7.2)

    In my case, the output was - 

    TimeZoneInfo.DisplayName = (UTC+12:00) Auckland, Wellington
    TimeZoneInfo.StandardName = New Zealand Standard Time
    TimeZoneInfo.DaylightName = New Zealand Daylight Time
    TimeZoneInfo.BaseUtcOffset = 12:00:00
    TimeZoneInfo.SupportsDaylightSavingTime = True
    New Zealand Standard Time Adjustment rules
       Adjustment rule #1
          Start Date: Monday, January 1, 0001
          End Date: Sunday, December 31, 2006
          Time Change: 1:00 hours
          Annual Start: The First Sunday of October at 2:00 AM
          Annual End: The Third Sunday of March at 3:00 AM
       Adjustment rule #2
          Start Date: Monday, January 1, 2007
          End Date: Monday, December 31, 2007
          Time Change: 1:00 hours
          Annual Start: The Last Sunday of September at 2:00 AM
          Annual End: The Third Sunday of March at 3:00 AM
       Adjustment rule #3
          Start Date: Tuesday, January 1, 2008
          End Date: Friday, December 31, 9999
          Time Change: 1:00 hours
          Annual Start: The Last Sunday of September at 2:00 AM
          Annual End: The First Sunday of April at 3:00 AM

    Notice that the date - 1970-01-01 falls under Adjustment rule #1, and the timezone would end up being UTC+13 (Daylight savings time), this is what both .NET/WCF & IE use and therefore IE too would end up showing the correct date(i.e 1970-01-01 00:00:00), because both client and server timezones are same.

    Chrome/Firefox would show a different date - 1969-12-31 23:00:00 (an hour early) because  they actually use correct timezone for that date (the correct timezone for that date is UTC+12, see https://www.timeanddate.com/time/zone/new-zealand/auckland?syear=1970&eyear=1973)

    So, it comes down to this - 
    a. Have windows provide an update/patch for older years, I believe msdn support site would be appropriate place for this (I came across few msdn blog posts which mention some timezone updates being delivered, but only for recent years  - 2000 or more, but never came across any posts mentioning updates for older years, might have to find out whether MS even has an intention to provide timezone updates for older years in first place)
    b. Add timezone entries for older years yourselves, might not be advisable but still an option. Moreover there was even a utility(tzedit) provided in one of the msdn blogs to easily add your own timezone entries, but the link appears to be dead - https://blogs.msdn.microsoft.com/mthree/2007/02/07/your-questions-where-can-i-find-tzedit-exe-to-edit-time-zone-info/. Also, this link might help in understanding the format to be used & some code - https://www.codeproject.com/tips/700884/fixing-daylight-saving-time-of-windows-for-next

    I was able to add my own entry in the registry and notice that both .NET/WCF & I.E use it (you might have to close and reopen IE & do an iisreset on the server)


    • Marked as answer by Nagarjuna.B Wednesday, October 31, 2018 2:21 PM
    • Edited by Nagarjuna.B Wednesday, October 31, 2018 2:32 PM
    Wednesday, October 31, 2018 2:20 PM

All replies

  • It seems that .NET/WCF does not consider the timezone history when deserializing datetime objects. We have a client in UTC+13 timezone (Auckland) and they came across an issue where an older date like - 1970/01/01 00:00:000 shows differently in Chrome/Firefox & Internet Explorer.

    WCF is not responsible for object serialization. It just uses serialization that is provided by the .NET Framework, which is just taking an object and   serializing and deserializing the object with no regard as to the data in the object. 

    So, is it possible to have both .NET/WCF & I.E consider timezone history? (maybe we have to install some kind of windows update?)

    No which is probably based on settings the O/S provides and/or what the browser is doing as far as settings. 

    Tuesday, October 30, 2018 12:32 PM
  • I tried converting a date object from one timezone to another, that too didn't seem to consider timezone history. By WCF I mean - the default serializer used by WCF, I believe that would be - DataContractJSONSerializer. Also, unless there is some specialized library which was written to address this, I would expect any seriailzers to use the framework/OS and if the framework/OS inherently does not support this, then there would be no way to address this.

    There were some articles mentioning there were some windows updates delivered for the timezones, 

    https://stackoverflow.com/questions/43403628/w-aus-standard-time-net-timezoneinfo-supportsdaylightsavingstime-issue

    see the links mentioned in the first answer, they redirect to microsoft blog which mentions a bunch of updates delivered for some timezones.

    I believe this might be a serious problem, majority of the browsers are supporting previous timezones. If .NET/Windows does not support that, it would result in end users seeing incorrect dates(like the one mentioned above)

    I want to know if Microsoft wants to address this problem or not, if it does, will it be with a windows update? (or maybe as you suggested, with some setting?, if so what settings need to be changed for this?)


    • Edited by Nagarjuna.B Tuesday, October 30, 2018 2:07 PM
    Tuesday, October 30, 2018 2:07 PM
  • What are you sending a Data Transfer Object an individual DTO or DTO(s) in a collection? Are you sending dataset with datatable?

    Tuesday, October 30, 2018 2:46 PM

  • Didnt get you!.

    Below are some sample WCF API methods we use.

    public DateTime GetLastModifiedDate();

    public UserDetails GetUserDetails();  // UserDetails is a class with LastModifiedDate DateTime property. Both suffer the problem

    Tuesday, October 30, 2018 3:34 PM

  • Didnt get you!.

    Below are some sample WCF API methods we use.

    public DateTime GetLastModifiedDate();

    public UserDetails GetUserDetails();  // UserDetails is a class with LastModifiedDate DateTime property. Both suffer the problem

    What is a DTO?

    https://en.wikipedia.org/wiki/Data_transfer_object

    https://www.codeproject.com/Articles/1050468/Data-Transfer-Object-Design-Pattern-in-Csharp

    So are you sending DTO(s) as serializable datacontracts or are you sending serializable dataset with datatable or sending serializable datatable between WCF client and WCF service?


    • Edited by DA924x Tuesday, October 30, 2018 11:19 PM
    Tuesday, October 30, 2018 11:18 PM
  • DTO.
    Wednesday, October 31, 2018 5:06 AM
  • I would say that the service-side code that I'll assume is persisting data using a timestamp must store the timestamp properly.

    https://medium.com/@vivekmadurai/how-to-deal-with-date-and-time-across-time-zones-39b1bd747f35

    <copied>

    Most of the application converts their timestamp to UTC before storing it in database, so that you can convert it back to user timezone while displaying.

    <end>

    JavaScript client-side code at the browser must make the adjustments based on machine and/or browser timezone settings to display timestamp properly.

    https://www.toptal.com/software/definitive-guide-to-datetime-manipulation.

    WCF has nothing to do with the data persistence and WCF has nothing to do object serialization and deseralization, which is done by the .NET Framework serialization namespace.

    WCF is only the technology that allows the client using frontend client-side code to communicate with the backend service-side code over the LAN or WAN.

    Wednesday, October 31, 2018 8:22 AM
  • Just confirmed that both .NET/WCF & I.E do indeed consider timezone history, its just that the history was limited to only a few recent years.

    All the timezone history info is stored in the registry under Time Zones key

    Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\New Zealand Standard Time\Dynamic DST

    It is not exactly in readable/understandable format, but you can print out some understandable info using some c# code (see https://docs.microsoft.com/en-us/dotnet/api/system.timezoneinfo.adjustmentrule?view=netframework-4.7.2)

    In my case, the output was - 

    TimeZoneInfo.DisplayName = (UTC+12:00) Auckland, Wellington
    TimeZoneInfo.StandardName = New Zealand Standard Time
    TimeZoneInfo.DaylightName = New Zealand Daylight Time
    TimeZoneInfo.BaseUtcOffset = 12:00:00
    TimeZoneInfo.SupportsDaylightSavingTime = True
    New Zealand Standard Time Adjustment rules
       Adjustment rule #1
          Start Date: Monday, January 1, 0001
          End Date: Sunday, December 31, 2006
          Time Change: 1:00 hours
          Annual Start: The First Sunday of October at 2:00 AM
          Annual End: The Third Sunday of March at 3:00 AM
       Adjustment rule #2
          Start Date: Monday, January 1, 2007
          End Date: Monday, December 31, 2007
          Time Change: 1:00 hours
          Annual Start: The Last Sunday of September at 2:00 AM
          Annual End: The Third Sunday of March at 3:00 AM
       Adjustment rule #3
          Start Date: Tuesday, January 1, 2008
          End Date: Friday, December 31, 9999
          Time Change: 1:00 hours
          Annual Start: The Last Sunday of September at 2:00 AM
          Annual End: The First Sunday of April at 3:00 AM

    Notice that the date - 1970-01-01 falls under Adjustment rule #1, and the timezone would end up being UTC+13 (Daylight savings time), this is what both .NET/WCF & IE use and therefore IE too would end up showing the correct date(i.e 1970-01-01 00:00:00), because both client and server timezones are same.

    Chrome/Firefox would show a different date - 1969-12-31 23:00:00 (an hour early) because  they actually use correct timezone for that date (the correct timezone for that date is UTC+12, see https://www.timeanddate.com/time/zone/new-zealand/auckland?syear=1970&eyear=1973)

    So, it comes down to this - 
    a. Have windows provide an update/patch for older years, I believe msdn support site would be appropriate place for this (I came across few msdn blog posts which mention some timezone updates being delivered, but only for recent years  - 2000 or more, but never came across any posts mentioning updates for older years, might have to find out whether MS even has an intention to provide timezone updates for older years in first place)
    b. Add timezone entries for older years yourselves, might not be advisable but still an option. Moreover there was even a utility(tzedit) provided in one of the msdn blogs to easily add your own timezone entries, but the link appears to be dead - https://blogs.msdn.microsoft.com/mthree/2007/02/07/your-questions-where-can-i-find-tzedit-exe-to-edit-time-zone-info/. Also, this link might help in understanding the format to be used & some code - https://www.codeproject.com/tips/700884/fixing-daylight-saving-time-of-windows-for-next

    I was able to add my own entry in the registry and notice that both .NET/WCF & I.E use it (you might have to close and reopen IE & do an iisreset on the server)


    • Marked as answer by Nagarjuna.B Wednesday, October 31, 2018 2:21 PM
    • Edited by Nagarjuna.B Wednesday, October 31, 2018 2:32 PM
    Wednesday, October 31, 2018 2:20 PM
  • Hi,

    As far as I know, WCF is not related to serialization, and the serializer is provided by the c# class library. It does not do process the data on timezone issue. For timezone synchronization, you should consider both client and server timezone Settings in Operation system. It is best to use server time uniformly.

    Best Regards

    Abraham

    Wednesday, October 31, 2018 2:23 PM
    Moderator