Bug 4902 - Determine TimeZone from java.util.TimeZone, not persist.sys.timezone
Summary: Determine TimeZone from java.util.TimeZone, not persist.sys.timezone
Alias: None
Product: Android
Classification: Xamarin
Component: BCL Class Libraries ()
Version: 4.1.x
Hardware: PC Windows
: High critical
Target Milestone: ---
Assignee: Marek Habersack
: 13382 18791 ()
Depends on:
Reported: 2012-05-05 11:45 UTC by Stuart Lodge
Modified: 2014-07-07 10:11 UTC (History)
19 users (show)

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

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 Developer Community or GitHub 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:

Description Stuart Lodge 2012-05-05 11:45:50 UTC

I'm sometimes seeing an exception with details:

System.ArgumentNullException: Argument cannot be null.
Parameter name: path2

>	0x21 in System.IO.Path.Combine at /home/jon/Development/xamarin/mono/mcs/class/corlib/System.IO/Path.cs:103	C#
 	0x6 in System.TimeZoneInfo+ZoneInfoDB.GetTimeZoneData at /home/jon/Development/xamarin/mono/mcs/class/System.Core/System/TimeZoneInfo.Android.cs:179	C#
 	0x5 in System.TimeZoneInfo+ZoneInfoDB._GetTimeZone at /home/jon/Development/xamarin/mono/mcs/class/System.Core/System/TimeZoneInfo.Android.cs:168	C#
 	0x69 in System.TimeZoneInfo+ZoneInfoDB.GetTimeZone at /home/jon/Development/xamarin/mono/mcs/class/System.Core/System/TimeZoneInfo.Android.cs:213	C#
 	0x2A in System.TimeZoneInfo+ZoneInfoDB.get_Default at /home/jon/Development/xamarin/mono/mcs/class/System.Core/System/TimeZoneInfo.Android.cs:274	C#
 	0xA in System.TimeZoneInfo.get_Local at /home/jon/Development/xamarin/mono/mcs/class/System.Core/System/TimeZoneInfo.cs:88	C#
 	0x0 in Newtonsoft.Json.Utilities.DateTimeUtils.GetUtcOffset	C#
 	0x3 in Newtonsoft.Json.JsonConvert.WriteDateTimeString	C#

This is when using the PCL version of JSON.Net

Looking at the call stack I guess this is a monodroid issue?

I haven't got a simple reproduction of this but it's happening frequently in the 
 samples on the vNext mvx branch: https://github.com/slodge/MvvmCross/tree/vnext

Comment 1 Jonathan Pryor 2012-05-24 15:27:43 UTC
Is this inside the debugger? Is this a first-chance exception?

I ask because TimeZoneInfo.Android.cs:213 is in the stack trace, which is clearly in a try/catch block:


This shouldn't be "escaping" to calling code, unless things are going "weird" (which usually occurs when running .apk's which haven't been zipaligned; are you custom signing this app?)

Unrelated, TimeZoneInfo.Android.cs:179 is a Path.Combine call, so the only reason we'd get an ArgumentNullException is if `name` were null, which implies that GetDefaultTimeZoneName() is returning null:


Does your device have the persist.sys.timezone system property set? i.e. what's the output of this command?

    adb shell getprop persist.sys.timezone

It should be a non-empty string, e.g.

Comment 2 Stuart Lodge 2012-05-25 12:46:01 UTC
I can't repro the problem right now - will need to remember the exact problem and remove the workaround.

The problem was a full exception though - it wasn't being handled.

I have seen some odd effects when debugging PLPs - they just don't seem to be "entirely normal" when it comes to stepping in and out of code - but this could be down to me and might be a red herring here.

I can tell you that my Galaxy Note is giving me an empty timezone for that adb call:

C:\Program Files (x86)\Android\android-sdk\platform-tools>adb shell getprop pers

C:\Program Files (x86)\Android\android-sdk\platform-tools>adb shell getprop pers

C:\Program Files (x86)\Android\android-sdk\platform-tools>

I tried it twice just to be sure!
Comment 3 Stuart Lodge 2012-05-25 12:46:24 UTC
placing it back to NEW to see if that adb shell info helps
Comment 4 Jonathan Pryor 2012-06-04 14:45:58 UTC
Very, very strange; AOSP uses the persist.sys.timezone system property:


(TimeZone.getDefault() calls ZoneInfoDB.getDefault() calls TimezoneGetter.getInstance() which is set to an inner class in RuntimeInit which grabs the persist.sys.timezone system property.)

Of course, all of that is subject to change (internal!), but my Galaxy Nexus (Android v4.0.4) still has the persist.sys.timezone system property, so I don't think it's changed that much. :-/

Fortunately, I think I've found an in-Java way to get an appropriate TimeZone string: Java.Util.TimeZone.Default.ID

Can you run a MfA app on your Galaxy Note and print out the value of the Java.Util.TimeZone.Default.ID property? Is it also the empty string or is it something reasonable?

 - Jon
Comment 6 Stuart Lodge 2012-06-06 02:32:01 UTC
Thanks Jon

The value of ID is "GMT"


-		Default	{java.util.SimpleTimeZone[id=GMT,offset=0,dstSavings=3600000,useDaylight=false,startYear=0,startMode=0,startMonth=0,startDay=0,startDayOfWeek=0,startTime=0,endMode=0,endMonth=0,endDay=0,endDayOfWeek=0,endTime=0]}	Java.Util.SimpleTimeZone
-		base	{Java.Util.TimeZone}	Java.Util.TimeZone
-		base	{Java.Lang.Object}	Java.Lang.Object
+		Class	{Java.Lang.Class}	Java.Lang.Class
		Handle	0x40513ba8	System.IntPtr
+		Static members		
+		Non-public members		
		DisplayName	"GMT+00:00"	string
		DSTSavings	0	int
		ID	"GMT"	string
+		Static members		
-		Non-public members		
		ThresholdClass	0x400985a0	System.IntPtr
+		ThresholdType	{System.MonoType}	System.MonoType
		RawOffset	0	int
+		Static members		
+		Non-public members
Comment 7 Atsushi Eno 2012-09-11 11:54:03 UTC
Does it still matter? Since bug #6468 is fixed now and thus Path part should be also working too.
Comment 8 Jonathan Pryor 2012-09-11 12:22:51 UTC
@Eno: Yes, this still matters; this is a different issue.

The problem here is that some devices lack the persist.sys.timezone system property (Comment #2), which TimeZoneInfo uses to determine the default timezone:


(Hopefully that link is correct; I cannot currently verify as github is down).

Since some devices don't have the persist.sys.timezome system property, it cannot be relied upon.

The solution is to have a "cross call" from System.Core.dll into Mono.Android.dll; see e.g. mcs/class/System/AndroidPlatform.cs. This "cross call" would invoke a method within Mono.Android.dll which would return the value of Java.Util.TimeZone.Default.ID, thus allowing the default timezone to be looked up even on platforms that don't provide persist.sys.timezone. (Furthermore, this "cross-call" should be used INSTEAD OF the current system property lookup code.)
Comment 9 Stuart Lodge 2013-01-03 11:21:35 UTC
I think I might have just stumbled upon this issue again - or maybe its something similar to it?

Basically, I'm trying to use JSON.Net in MonoDroid to save an object.

This object includes a time which has been created using System.DateTime.UtcNow

When I run it, it hits a NullReferenceException in:

		StackTrace	"  at Newtonsoft.Json.Utilities.DateTimeUtils.GetUtcOffset (DateTime d) [0x00000] in <filename unknow…"	string

Looking at the code - https://github.com/ayoung/Newtonsoft.Json/blob/master/Newtonsoft.Json/Utilities/DateTimeUtils.cs

It seems this is most likely caused by:

    utcOffset = TimeZoneInfo.Local.GetUtcOffset(d); 

so TimeZoneInfo.Local is null

Testing this in a simple app, confirms this.

Totally understand that this might be 'something special' about my Galaxy Note - but thought I'd report it anyway - as I think TimeZoneInfo.Local should never be null?
Comment 10 Stuart Lodge 2013-01-17 10:01:01 UTC
I'm seeing this crash a lot at present.

Is there any fix planned for this?

If not, can we move this bug to REJECTED? POSTPONED? etc

I'm finding it a bit embarrassing explaining to my customer that this bug is still NEW where it was reported 8 months ago.


Comment 11 Stuart Lodge 2013-01-17 10:08:51 UTC
Or maybe I've confused things... and this is actually >1 bug?
Comment 12 NiWa 2013-05-30 02:52:34 UTC
What about this Bug? As far as I know there is no solution or fix for this problem.

Comment 13 Atsushi Eno 2013-06-28 03:27:15 UTC
I adb shell getprop persist.sys.timezone and "Console.WriteLine (Java.Util.TimeZone.Default.ID);" on my Galaxy Note, and both returned Asia/Tokyo (as expected).

I wonder if UK (GMT) is handled specially somewhere (either in Android, mono, or XA).
Comment 14 NiWa 2013-06-28 03:38:04 UTC
@Eno: I really think this has something to do with the device used. On my Galaxy SII (GT-I9100) with Android 4.0.4 it does not work no matter what timezone (de-DE or somthing else) is set.
Comment 15 NiWa 2013-06-28 03:46:59 UTC
Java.Util.TimeZone.Default.ID returns "GMT" only.
Comment 16 NiWa 2013-07-01 03:08:08 UTC
Please forget the mention of locale de-DE, because it *obviously* has nothing to do with the current issue.

BUT, after further testing I was able to observe the correct behavior of the JSON serializer, after I turned off the automatic timezone update and manually set the timezone to GMT+1.

After that 'getprop persist.sys.timezone' returns the expected value and the JSON serializer runs successfully through the serialization of a DateTime object.
Comment 17 Jonathan Pryor 2013-07-22 15:55:37 UTC
*** Bug 13382 has been marked as a duplicate of this bug. ***
Comment 18 José Pereira 2013-08-21 11:12:34 UTC
I'm having this same issue...
I run the 'adb shell getprop persist.sys.timezone' command and it returns:


Still, when I try to serialize na object that has a DateTime property, it throwns an exception...

I've tried to set manually the timezone and the result is the same...
I'm testing it on a Sony Experia L with Android 4.1.2

Any news regarding this bug. How can I overcome this behaviour?
Comment 19 Stephen Feest 2013-08-28 13:09:40 UTC
I am having the same issue with Xamarin.Android 4.8.1 on my Nexus 7 running Android 4.3. Namely when I try to serialize a DateTime value with Json.NET I get a NullReferenceException in Newtonsoft.Json.Utilities.DateTimeUtils.GetUtcOffset(DateTime d). Using a very simple test project I can confirm that the cause of this is TimeZoneInfo.Local returning null.

On this particular tablet I've tried changing the time zone manually and disabling 'Automatic date & time' but that doesn't seem to change anything.

adb shell getprop persist.sys.timezone returns the correct time zone "Europe/London"

In my opinion this is quite a serious bug as there doesn't seem to be any obvious workaround for those of us whose apps rely on timezone information.
Comment 20 Jonathan Pryor 2013-08-28 14:16:25 UTC
@José Pereira: What's the exception you get when deserializing the DateTime?

This bug (Bug #4902) is about proper behavior when the persist.sys.timezone isn't set; if it is set, that's a different bug, for which I'll need additional information.
Comment 22 Stephen Feest 2013-08-28 15:03:45 UTC
Thanks Jonathan. The problem I'm experiencing does indeed look like it's caused by bug #13686. Sorry for the confusion!
Comment 23 Chuck Pinkert 2013-09-08 22:51:01 UTC
Also having this problem using mvvmcross / json.net in one app and my other app has it when just trying to reference the current timezone on some devices that don't set persist.sys.timezone.
Comment 24 vlad.dimitrov 2013-10-06 03:23:33 UTC
Also having the same issue while trying to serialize an object. This is what I get:

{System.NullReferenceException: Object reference not set to an instance of an object
  at Newtonsoft.Json.Utilities.DateTimeUtils.GetUtcOffset (DateTime d) [0x00000] in <filename unknown>:0 
  at Newtonsoft.Json.JsonConvert.WriteDateTimeString (System.IO.TextWriter writer, DateTime value, DateFormatHandling format) [0x00000] in <filename unknown>:0 
  at Newtonsoft.Json.JsonTextWriter.WriteValue (DateTime value) [0x00000] in <filename unknown>:0 
  at Newtonsoft.Json.JsonWriter.WriteValue (System.Object value) [0x00000] in <filename unknown>:0 
  at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializePrimitive (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonPrimitiveContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) [0x00000] in <filename unknown>:0 
  at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonContract valueContract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) [0x00000] in <filename unknown>:0 
  at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract collectionContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) [0x00000] in <filename unknown>:0 }
    base: {System.SystemException}

I am using Xamarin.Android 4.8.03009 and am running the code on LG P500
Comment 25 vlad.dimitrov 2013-10-06 03:53:24 UTC
Looks like the problem is coming from the fact that TimeZoneInfo.Local == null.

This on this device because the Time zone info was set to automatic and there was no SIM card inside so it could not determine the time zone.

After setting the time zone manually the code started working.
Comment 26 Dale King 2014-02-17 16:38:05 UTC
Any chance this bug will get fixed soon? High, critical bug still open after 1 year and a half?!!?

It is easy to replicate. All I have to do is create a new emulator (GenyMotion in my case) and don't set a timezone. It is set to automatic and TimeZoneInfo.Local will be null. If you set a timezone it isn't.
Comment 27 Greg Shackles 2014-03-20 16:05:53 UTC
Are there any plans for getting a fix for this in the roadmap? I'm hitting this in my apps as well.
Comment 28 Andrew 2014-04-04 11:00:25 UTC
In case of Genymotion, go to Android settings and set your/any timezone. After that TimeZoneInfo.Local will not be null.
Comment 29 Dale King 2014-04-04 13:12:58 UTC
Yes I know how to work around it in my emulator, the point was it is dead simple to reproduce, so should not be that much work to fix.
Comment 30 Marek Habersack 2014-04-16 11:00:54 UTC
The bug is fixed in the master branch, in the following commits:


The fix implements a fall-back to retrieve the default time zone name from Java.Util.TimeZone.Default.ID should the 'persist.sys.timezone' system property be missing.
Comment 31 Jonathan Pryor 2014-04-22 11:10:19 UTC
*** Bug 18791 has been marked as a duplicate of this bug. ***
Comment 32 Ram Chandra 2014-07-07 10:11:17 UTC
I have checked this issue with following builds:

Mac OS X 10.8.5
Xamarin Studio : 5.2 (build 179)
Xamarin.Android : 4.14.0

Build Information
Release ID: 502000179
Git revision: 3dbcdf64de0826aa76b5f108ae80644511b4e587
Build date: 2014-07-03 17:37:41-04
Xamarin addins: 116ce67c67d933645f95fb370690487b18b8624e

I observed that now to define the default time zone we are using "__XA_USE_JAVA_DEFAULT_TIMEZONE_ID__" variable.  we are checking that if  variable “__XA_USE_JAVA_DEFAULT_TIMEZONE_ID__” is null we are setting values to the “persist.sys.timezone” property. 

Now, If the device doesn't set the "persist.sys.timezone". we are able to define the default time zone.

Screencast: http://www.screencast.com/t/ZAkViXi0F0t

Please let me know is this sufficient to verify this issue? If I am missing anything then please suggest the correct steps to verify this issue. 

As of now I am changing its status as verified.