简体   繁体   中英

.NET CF 3.5 SetTimeZoneInformation problem

I want to programatically set time zone in C# CF 3.5 application. The reason I want to do this is the fact that the application is installed on hundreds of Motorola MC55 devices and some of them get periodically discharged. After charging, the timezone device timezone is set to some "exotic" value not equal to my time zone (UTC+1 Warsaw). I use OpenNETCF.WindowsCE.DateTimeHelper.SetTimeZoneInformation API to set the timezone. I get the OpenNETCF.WindowsCE.TimeZoneInformation object by getting list of OpenNETCF.WindowsCE.TimeZoneCollection and searching the keyword "Warsaw". Thus I have a correctly set OpenNETCF.WindowsCE.TimeZoneInformation object that I pass to OpenNETCF.WindowsCE.DateTimeHelper.SetTimeZoneInformation API call. The problem is that this timezone is "Day light saving" and recently (after recent summer time set) the local time in my application is 1 hour late than it should be. The best is that the problem exists on some devices only, not on all.

What may be the reason?

The OpenNETCF TimeZoneCollection is getting data directly from the OS, it's not doing anything but acting as a data marshaler. If you're seeing incorrect DST offsets, DST dates or TZ biases, it's because the OS you have has these defined incorrectly.

This is not unusual, especially since different parts of the world like to periodically change the definitions for local time calculations and the OS build has no idea that these have happened. THere a loads of CE 5.0 and earlier devices out there that still improperly calculate DST change dates in the US because of this.

The solution is to update the device with an OS that was built with the proper definitions.

Now if you're seeing a problem where you set the TimeZone to something like "UTC +1 PlaceA" and you get back "UTC +1 PlaceB" then I think that's an known issue (I think I recall some questions on this in the past 5 years anyway) because it's not handled well at all down in the OS. Just look at the source:

public static void SetTimeZoneInformation( TimeZoneInformation tzi )
{
    // Call CE function (implicit conversion occurs to
    // byte[]).
    if (!NativeMethods.SetTimeZoneInformation(tzi))
    {
        throw new System.ComponentModel.Win32Exception(
            Marshal.GetLastWin32Error(), "Cannot Set Time Zone");
    }
}

You can see, we're just passing the TZI retrieved from the device (from the registry in the case of non-WinMo) and assembled in the TimeZoneCollection class (starting at line 129).

In a solution we created that had to handle timezones, DST, etc. we actually ended up writing our own service that handled all DST/TZ calculations. We used the OS to store GMT and nothing else, then did all offsets manually. The product is sold is several couries covering several time zones and we've heard of no problems (and since it's a time clock, any issues with time would become evident really quick).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM