Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
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
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.
Could you take a look at this?
TimeZoneInfo.Local in OS X is loaded from /etc/localtime.
/etc/localtime is either a symbolic link or a copy of /usr/share/zoneinfo/<OLSON_ID>
From the file data we cannot obtain the Olson Id, only the short standard and DST name of the last rule (e.g CET, EST, GMT, ..).
When we compare /etc/localtime with /usr/share/zoneinfo/* there can be multiple matches.
We cannot change the Id from "Local" to the standard name because the local TZ can have base offset changes thus previous standard names. We would have the following test failing in those timezones:
//This loads /etc/localtime
var tz1 = TimeZoneInfo.Local.Id;
//This would load /usr/share/zoneinfo/<standard name>
var tz2 = TimeZoneInfo.FindSystemTimeZoneById(tz1.Id);
DateTime date = <time before the time zone base offset change>;
Can this case be re-examined? This is breaking behavior. For example, NodaTime does not work properly in Mono on OSX: http://nodatime.org/1.1.x/userguide/mono.html
The Olson ID can be unambiguously had using readlink.
private static extern int readlink(string path, byte buffer, int buflen);
public static string ReadLink(string path)
var buf = new byte;
var ret = readlink(path, buf, buf.Length);
return ret == -1
: Encoding.UTF8.GetString(buf, 0, ret);
static DateTimeZone GetLocalTimeZoneId()
const string pathprefix = "/usr/share/zoneinfo/";
// eg: /usr/share/zoneinfo/America/Los_Angeles
var timezonepath = ReadLink("/etc/localtime");
if (timezonepath == null || !timezonepath.StartsWith(pathprefix))
throw new Exception("Couldn't determine local timezone.");
Maybe we could check the symlink to figure out what's the actual local TZ, what do you think?
I did a pull request that uses the symbolic link to figure out the Olson Id:
Fixed in master 83985b4ab6d3ffdd17fa08862a8ab1b838054ce8.