Bug 24947 - Current TimeZone is not updated after the system timezone is changed by a java call
Summary: Current TimeZone is not updated after the system timezone is changed by a jav...
Status: RESOLVED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: Mono runtime / AOT Compiler ()
Version: 5.1
Hardware: PC Windows
: --- normal
Target Milestone: 5.1
Assignee: Jonathan Pryor
URL:
: 28716 ()
Depends on:
Blocks:
 
Reported: 2014-12-01 03:37 UTC by floriang
Modified: 2015-04-03 09:45 UTC (History)
6 users (show)

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


Attachments
Scratch.Bxc24947.zip (11.24 KB, application/zip)
2014-12-12 15:45 UTC, Jonathan Pryor
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 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:
Status:
RESOLVED FIXED

Description floriang 2014-12-01 03:37:02 UTC
[Problem]
After changing the timezone from a background service, using Java API like:
         private boolean setTimeZone(Context context, Intent intent) {
	    String timeOffset = intent.getStringExtra("TIMEZONE");

	    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
	        Settings.Global.putInt(context.getContentResolver(),Settings.Global.AUTO_TIME, 0);
			Settings.Global.putInt(context.getContentResolver(),Settings.Global.AUTO_TIME_ZONE, 0);
	    } else {
	    	Settings.System.putInt(context.getContentResolver(),Settings.System.AUTO_TIME, 0);
			Settings.System.putInt(context.getContentResolver(),Settings.System.AUTO_TIME_ZONE, 0);
	    }
		
	    TimeZone tz = TimeZone.getTimeZone("GMT"+timeOffset);
	    String[] tzs = TimeZone.getAvailableIDs(tz.getRawOffset());
		
		AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
		am.setTimeZone(tzs[0]);
		
		return true;
	}
The timezone in the Xamarin.Android application is not updated.
Clearing the cache by reflection as suggested in bug 18132 didn't solve the issue.
https://bugzilla.xamarin.com/show_bug.cgi?id=18132

Also clearing the cache using:
System.TimeZoneInfo.ClearCachedData();
System.Globalization.CultureInfo.CurrentCulture.ClearCachedData();
System.Globalization.CultureInfo.CurrentUICulture.ClearCachedData();
did not solve the issue either.

[Basic example]
After setting timezone from "GMT-2" to "GMT+3" using the Java API, System.TimeZone.CurrentTimeZone returns "GMT-2".
However, in this case Java.Util.TimeZone.Default.ID returns the correct timezone ("Etc/GMT+3").

[Additional explanations]
Instead of doing:
DateTime GetLocalTime() {
    return DateTime.Now
}

We had to do:
DateTime GetLocalTime() {
   var tz = TimeZoneInfo.FindSystemTimeZoneById(Java.Util.TimeZone.Default.ID);
   DateTime ret = TimeZoneInfo.ConvertTimeFromUtc(date.ToDateTime().ToUniversalTime(), tz);
   return ret;
}

It is very annoying since people usually use DateTime.Now directly in lots of place in the code.
Comment 1 floriang 2014-12-01 04:03:59 UTC
Reproduced after updating to latest version of Xamarin.Android.
Comment 2 Jonathan Pryor 2014-12-12 15:45:04 UTC
Created attachment 9060 [details]
Scratch.Bxc24947.zip

Sample App.
Comment 3 Jonathan Pryor 2014-12-12 16:03:27 UTC
Fixed in mono/ade02c3f and monodroid/78a55099.

https://github.com/mono/mono/commit/ade02c3f

Verification steps:

 1. Build and run attachment #9060 [details].

 2. Verify that the DateTime.Now & Java timestamps shown on the
    button are the same.

 3. Change the TimeZone on the device:
 3.a: Open the Settings app.
 3.b: Tap Date & time > Select time zone.
 3.c: Select a timezone with an offset that differs from the current
      TimeZone offset.

 4. Return to the app.

 5. Tap the button.

The button text will be updated to show the current time. The time
shown should (1) be in the current/new TimeZone, and
(2) match the Java time shown.
Comment 4 Jonathan Pryor 2014-12-12 16:07:26 UTC
floriang: Using CultureInfo.ClearCachedData() didn't work because of bugs within both DateTime and TimeZoneInfo.AndroidTimeZones. This commit should provide sufficient information to let you know which fields to clear via Reflection if necessary:

https://github.com/mono/mono/commit/ade02c3f
Comment 5 Richard Shaw 2015-01-07 12:05:05 UTC
For those who have come across this thread looking for a solution (and you haven't gotten the fix yet from the latest Xamarin.Android or Xamarin.Forms):

var atz = typeof(TimeZoneInfo).GetNestedType (@"AndroidTimeZones", BindingFlags.NonPublic | BindingFlags.Static);
			if (atz != null) {
				var atzField = atz.GetField (@"defaultZone", BindingFlags.NonPublic | BindingFlags.Static);
				if (atzField != null) {
					atzField.SetValue (null, null);
				}
			}

var tmp = DateTime.Now;

This little bit of code will ensure that in your app, the now changed TimeZone is getting pulled in.

I know that there is some committed code that is fixing this, but I still experienced the same issue using Xamarin.Forms on Android.
Comment 6 Jonathan Pryor 2015-04-03 09:45:22 UTC
*** Bug 28716 has been marked as a duplicate of this bug. ***