Bug 2791 - TimeZoneInfo.Local not implemented on windows
Summary: TimeZoneInfo.Local not implemented on windows
Status: RESOLVED FIXED
Alias: None
Product: Class Libraries
Classification: Mono
Component: mscorlib ()
Version: unspecified
Hardware: PC Windows
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2012-01-09 07:50 UTC by Jonathan Shore
Modified: 2013-07-02 04:12 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
diff -c patch (2.91 KB, text/plain)
2012-01-15 12:26 UTC, Jonathan Shore
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Jonathan Shore 2012-01-09 07:50:22 UTC
So I have a mono application which works fine on OSX and Linux that uses System.TimeZoneInfo.Local, amongst other TimeZoneInfo facilities.

On windows calling TimeZoneInfo.Local throws a TimeZoneNotFoundException.

Looking at the class library code in "src/mono-2.10/mcs/class/System.Core/System/TimeZoneInfo.cs" it is clear why this will throw an exception.   The current code is oriented for Unix or mobile devices, looking for /etc/localtime or Local in specific parts of the filesystem.  Code needs to be added to extract the local time from the registry (or win32 api)?

There is what I've gathered from the net in terms of what needs to be done to find the local zone:

When using the registry, look for the Windows time zone and use a mapping to translate this to an Olson time zone name.

- Windows Vista and 2008
Look in "SYSTEM/CurrentControlSet/Control/TimeZoneInformation/" for a node named "/TimeZoneKeyName". If this exists, we use this key to look up the Olson time zone name in our mapping.

- Windows NT, Windows 2000, Windows XP, Windows 2003 Server
Look in "SOFTWARE/Microsoft/Windows NT/CurrentVersion/Time Zones/" and loop through all of its sub keys.

For each sub key, compare the value of the key with "/Std" appended to the end to the value of "SYSTEM/CurrentControlSet/Control/TimeZoneInformation/StandardName". This gives one the English name of the Windows time zone, which we use to look up the Olson time zone name.
Comment 1 Miguel de Icaza [MSFT] 2012-01-13 18:05:14 UTC
We do not really have a lot of developers working on Mono/Windows, so this might take a while.

Might you be interested in providing a patch that implements the above behavior?
Comment 2 Jonathan Shore 2012-01-15 10:36:39 UTC
I don't use windows really either (I use OSX), but want to support my code on windows for colleagues that do.  That said, I'll try putting together a fix.  Is the least I can do, given the huge amount you collectively have contributed to the community.

I can't do a proper windows build, so will test the adjustments to class on windows and just post the diffs here ...
Comment 3 Jonathan Shore 2012-01-15 12:26:38 UTC
Created attachment 1196 [details]
diff -c patch

I've fixed the problem (though I am not able to build in the full source context on windows).  I tested the functionality outside of the mono libraries and reinserted into the source for diff purposes.   Find the context-diff enclosed
Comment 4 Jonathan Shore 2012-01-15 12:30:23 UTC
Is there an easy way for one to rebuild just the runtime libraries, without requiring (or being able to) build the mono CLR proper?

So I found some other issues in the timezone stuff (that worked around), at some point would like to submit patches for those.   For example, the daylight savings time rule evaluation has some issues.   I'm not going to have time to submit for those right now, but will be more convenient to do so if can do just library build / install, separately from the full mono build.
Comment 5 Miguel de Icaza [MSFT] 2012-01-15 15:04:11 UTC
Jonathan,

Thanks for the patch.

You need to at least have an initial build of the runtime and Mono before you can just build individual pieces, once you do that, you can do:

cd mono/mcs/class/SOME-ASSEMBLY
make 

And that will build the assembly.

It might be possible to modify the scripts to use the MS.NET compiler but there is no easy way of doing that now.
Comment 6 Miguel de Icaza [MSFT] 2012-01-15 15:10:20 UTC
Applied the patch, let us open a new bug for any new issues.
Comment 7 Ivan Samygin 2013-07-02 03:25:47 UTC
Applied the patch locally and found it doesn't work on Windows XP SP3.
There's no "TimeZoneKeyName" value under
HKLM "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones" key. But I found such value under 
HKCU "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones".

So to get it work I created another property UserZoneKey and in get accessor of TimeZoneInfo.Local property I try LocalZoneKey first, then UserZoneKey:

// TimeZoneInfo.Local
	if (IsWindows) {
		string name = null;
		if (LocalZoneKey != null)
			name = (string)LocalZoneKey.GetValue ("TimeZoneKeyName");
		if (name == null && UserZoneKey != null)
			name = (string)UserZoneKey.GetValue ("TimeZoneKeyName");
		if (name != null) {
			name = TrimSpecial (name);
			local = TimeZoneInfo.FindSystemTimeZoneById (name);
		}
	}

	if (local == null)
		throw new TimeZoneNotFoundException ();

// TimeZoneInfo.UserZoneKey
	static RegistryKey userZoneKey = null;
	static RegistryKey UserZoneKey {
		get {
			if (userZoneKey != null)
				return userZoneKey;
			
			if (!IsWindows)
				return null;
			
			userZoneKey = Registry.CurrentUser.OpenSubKey (
				"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones", false);
			
			return userZoneKey;
		}
	}
Comment 8 Ivan Samygin 2013-07-02 04:12:33 UTC
Sorry, I make a mistake in previous comment https://bugzilla.xamarin.com/show_bug.cgi?id=2791#c7
In Windows XP doesn't exist value "TimeZoneKeyName" under
HKLM "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation"
(I wrote "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones" by mistake).