2

Here is how I change the TimeZoneInfo (App #1) :

private static void ChangeTimeZone(TimeZoneInfo tzi)
{
    TIME_ZONE_INFORMATION actual = new TIME_ZONE_INFORMATION();
    NativeMethods.GetTimeZoneInformation(out actual);

    if (tzi == null || actual.StandardName == tzi.StandardName)
        return;

    TIME_ZONE_INFORMATION newZone = (TIME_ZONE_INFORMATION)tzi;

    RunWin32Method(() => NativeMethods.SetTimeZoneInformation(ref newZone));

    // Update .NET
    CultureInfo.CurrentCulture.ClearCachedData();
    TimeZoneInfo.ClearCachedData();

    // Notify all windows that we changed a Windows setting.
    // result is True
    IntPtr ptr;
    System.Diagnostics.Debug.WriteLine(NativeMethods.SendMessageTimeout(NativeMethods.HWND_BROADCAST, NativeMethods.WMI_SETTING_CHANGE,
        IntPtr.Zero, IntPtr.Zero, 0x00, 1000, out ptr));
}

When I call my method:

ChangeTimeZone(TimeZoneInfo.GetSystemTimeZones().First(e => !e.SupportsDaylightSavingTime));
// Stopping debugger and watching other .NET App then continue to next instruction
ChangeTimeZone(TimeZoneInfo.GetSystemTimeZones().First(e => e.StandardName.Contains("Romance")));

Here is the other app (App #2):

static void Main(string[] args)
{
    while (true)
    {
        Console.WriteLine(DateTime.Now);
        Thread.Sleep(500);
    }
}

Output of DateTime is never updated to the new TimeZone, why?


EDIT

As @Jon said, by adding CultureInfo.CurrentCulture.ClearCachedData(); the new date will be updated. But as said, I would that ALL other application uses this new TimeZone. I have a lot apps running in background using the DateTime.Now, it would be bad to specify each time to clear the cache before retrieve the local updated date...

Arnaud F.
  • 8,252
  • 11
  • 53
  • 102
  • 1
    `TimeZoneInfo.Local` is created and cached first time it is used (by reading time zone information from the registry). Unless you use `TimeZoneInfo.ClearCachedData` it will not be recreated in the current AppDomain. So you really have to clear the cache if you want to recompute information about the local time zone. To not do that on every call to `DateTime.Now` you need to have a top-level window and react to the `WM_SETTINGCHANGE` message. – Martin Liversage Apr 13 '12 at 08:33

1 Answers1

5

I suspect your second app is just using cached time zone data. (It's in a separate process, after all - clearing the cache in app 1 isn't going to affect any in-process caches in app 2.) Try calling TimeZoneInfo.ClearCachedData in app 2 and see if that sorts out the issue.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • @ArnaudF.: I think it's really up to client apps to clear the cache if they need up-to-date time zone information, unfortunately. I don't *think* .NET even exposes a "time zone information has changed, you may wish to clear the cache" event. (I think there's a Win32 one, but it's not exposed to .NET.) – Jon Skeet Apr 13 '12 at 08:22
  • for me, raising `WMI_SETTINGCHANGE` should do the trick... It's recommended to raise it on MSDN. Why .NET doesn't take this setting into account? I've not the source code of all .NET running app and some of them needs to have the right DateTime... – Arnaud F. Apr 13 '12 at 08:27
  • @ArnaudF.: `WM_SETTINGCHANGE` (note spelling) require a top-level window with a message loop. You don't want .NET to create that for every application that loads .NET. You will have to handle that yourself. – Martin Liversage Apr 13 '12 at 08:34
  • According to me, isn't logical and I thought many developers that are dealing with DateTime expect this result but whatever, will do your way. Thanks. – Arnaud F. Apr 13 '12 at 08:46