Error in handling of /etc/localtime file to retrieve time zone on Linux

On Linux Mono uses the /etc/localtime file to figure out the time zone. If appears that if /etc/localtime is an actual file instead of a symbolic link to the file building mono fails with a System.TimeZoneNotFoundException when mdoc is run:

MDOC [net_4_5] cs-errors.tree
mdoc: System.TimeZoneNotFoundException: Exception of type 'System.TimeZoneNotFoundException' was thrown.

  at System.TimeZoneInfo.get_Local () <0x100003bd0930 + 0x00134> in <filename unknown>:0 
  at System.TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc (DateTime time, System.Boolean& isAmbiguousLocalDst) <0x100003bd0848 + 0x00038> in <filename unknown>:0 
  at System.DateTime.get_Now () <0x100003bcff98 + 0x00084> in <filename unknown>:0 
  at ICSharpCode.SharpZipLib.Zip.ZipEntry..ctor (System.String name, Int32 versionRequiredToExtract, Int32 madeByInfo) <0x100003bcfcd0 + 0x00088> in <filename unknown>:0 
  at ICSharpCode.SharpZipLib.Zip.ZipEntry..ctor (System.String name) <0x100003bcfbb8 + 0x0003c> in <filename unknown>:0 
  at Monodoc.Storage.ZipStorage.SetupEntry (ICSharpCode.SharpZipLib.Zip.ZipOutputStream zipOutput, System.String& id) <0x100003bcf9d8 + 0x000fc> in <filename unknown>:0 
  at Monodoc.Storage.ZipStorage.Store (System.String id, System.IO.Stream stream) <0x100003bcc808 + 0x00064> in <filename unknown>:0 
  at Monodoc.Providers.ErrorProvider.CloseTree (Monodoc.HelpSource hs, Monodoc.Tree tree) <0x100003ba7f50 + 0x00278> in <filename unknown>:0 
  at Mono.Documentation.MDocAssembler.Run (IEnumerable`1 args) <0x100002c3b0f8 + 0x014c4> in <filename unknown>:0 
  at Mono.Documentation.MDoc.Run (System.String[] args) <0x100002bd4688 + 0x00d64> in <filename unknown>:0 
  at Mono.Documentation.MDoc.Main (System.String[] args) <0x100002bd3af0 + 0x00084> in <filename unknown>:0 

Various test cases also fail with the same exception when doing a make check as well.


If I set the TZ environment variable then everything works OK. For example this works:

export TZ="/usr/share/zoneinfo/US/Central"


On different Linux varieties /etc/localtime is either an actual file or a symbolic link to a file. Some varieties require it to be one or the other. On Ubuntu it is an actual file for instance. On the Ubuntu system I am using:

seurer@genoa:~/mono-git/mono$ ls -l /etc/localtime
-rw-r--r-- 1 root root 3559 Apr 27 08:16 /etc/localtime

That is an actual file. It is a copy of another file from the zoneinfo directory tree:

seurer@genoa:~/mono-git/mono$ ls -l /usr/share/zoneinfo/US/Central
-rw-r--r-- 1 root root 3559 Apr 26 17:57 /usr/share/zoneinfo/US/Central

If I compare the two they are the same:

seurer@genoa:~/mono-git/mono$ diff --binary /etc/localtime /usr/share/zoneinfo/US/Central
seurer@genoa:~/mono-git/mono$

Note that this is the same file that worked when I set the TZ environment variable.


Reference: https://bugzilla.xamarin.com/show_bug.cgi?id=30360