Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Timezone issue in Android

I have time in milliseconds and I am displaying that time in my application in "MM/dd/yyyy HH:mm:ss" format, it is working fine.

Problem: if I change the timezone in android device it display different time in my application may be because of some timezone calculation. I want to display same time that is in my database as it is in any timezone.

I am using below code to test timezone issue

Locale locale = new Locale("en", "IN");

TimeZone tz = TimeZone.getDefault();
System.out.println("Default timezon id :: " + tz.getID());
tz.setID("Asia/Calcutta");
String timezon = tz.getDisplayName(false, TimeZone.SHORT, locale);
System.out.println("Timezon id :: " + tz.getID() + " Timezon name :: " + timezon);
Calendar cal = Calendar.getInstance(tz, locale);

System.out.println("TImezon :: " + tz);
// "1319084400775" is the milliseconds of 10/20/2011 05:20:00 in MM/dd/yyyy HH:mm:ss format 
Date date = new Date(Long.parseLong("1319084400775"));
System.out.println("Date :: " + date.toGMTString());
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", locale);

System.out.println("Start date :: " + format.format(date));
// "1319084400775" is the milliseconds of 10/20/2011 05:20:00 in MM/dd/yyyy HH:mm:ss format 
cal.setTimeInMillis(Long.parseLong("1319084400775"));

timezon = cal.getTimeZone().getDisplayName(false, TimeZone.SHORT, locale);
System.out.println("Calender's timezon :: " + timezon);
System.out.println("Start date :: yyyy-mm-dd hh:mm:ss " + cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + "-" + cal.get(Calendar.DAY_OF_MONTH) + " " + cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE));
// "1319084700776" is the milliseconds of 10/20/2011 05:25:00 in MM/dd/yyyy HH:mm:ss format 
cal.setTimeInMillis(Long.parseLong("1319084700776"));
System.out.println("End date :: " + cal.getTime());

Output ::

If I set timezone for "Pacific/Fiji";

10-07 17:03:40.392: INFO/System.out(1193): Default timezon id :: Pacific/Fiji
10-07 17:03:40.392: INFO/System.out(1193): Timezon id :: Asia/Calcutta Timezon name :: GMT+05:30
10-07 17:03:40.406: INFO/System.out(1193): TImezon :: org.apache.harmony.luni.internal.util.ZoneInfo@7b42d3a7
10-07 17:03:40.422: INFO/System.out(1193): Date :: 20 Oct 2011 04:20:00 GMT
10-07 17:03:40.442: INFO/System.out(1193): Start date :: 2011-10-20 16:20:00
10-07 17:03:40.442: INFO/System.out(1193): Calender's timezon :: GMT+05:30
10-07 17:03:40.442: INFO/System.out(1193): Start date :: yyyy-mm-dd hh:mm:ss 2011-9-20 16:20
10-07 17:03:40.452: INFO/System.out(1193): End date :: Thu Oct 20 16:25:00 Pacific/Fiji 2011

If I set timezone for "America/Tijuana";

10-06 22:05:20.702: INFO/System.out(1193): Default timezon id :: America/Tijuana
10-06 22:05:20.712: INFO/System.out(1193): Timezon id :: Asia/Calcutta Timezon name :: GMT+05:30
10-06 22:05:20.712: INFO/System.out(1193): TImezon :: org.apache.harmony.luni.internal.util.ZoneInfo@1294e658
10-06 22:05:20.733: INFO/System.out(1193): Date :: 20 Oct 2011 04:20:00 GMT
10-06 22:05:20.742: INFO/System.out(1193): Start date :: 2011-10-19 21:20:00
10-06 22:05:20.742: INFO/System.out(1193): Calender's timezon :: GMT+05:30
10-06 22:05:20.752: INFO/System.out(1193): Start date :: yyyy-mm-dd hh:mm:ss 2011-9-19 21:20
10-06 22:05:20.752: INFO/System.out(1193): End date :: Wed Oct 19 21:25:00 America/Tijuana 2011

EDIT

I have time in milliseconds now I am displaying that milliseconds in date format in my application but issue is when I changed timezone in device I get date according to that timezone.

like image 461
Dharmendra Avatar asked Oct 07 '11 05:10

Dharmendra


People also ask

What is the time zone data on an Android phone?

The Time Zone Data module updates daylight saving time (DST) and time zones on Android devices, standardizing both the data (which can change frequently in response to religious, political, and geopolitical reasons) and the update mechanism across the ecosystem.


2 Answers

A Date is just an instant in universal time. It has no notion of a time zone. Think of it as "when Kennedy was killed".

When you display this time with a SimpleDateFormat, this date format has a time zone, and you display this instant in time using this time zone. So, if the time zone of the date format is the central standard time, this time will be displayed as 12:30. If the time zone is UTC, it will be displayed as 18:30.

If you want some date to be displayed the same way, regardless of the time zone, than you just have to choose a specific time zone (UTC, for example), and always display the date with this time zone. You thus have to call setTimeZone on the DateFormat before formatting the date.

like image 187
JB Nizet Avatar answered Oct 05 '22 22:10

JB Nizet


In standard Java:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
sdf.setTimeZone(TimeZone.getTimeZone(<your timezone here>);

long millis = <your timestamp here>; //timestamps are not TZ dependent.
Date d = new Date(millis);
String toDisplay = sdf.format(d);

The timezone in the SimpleDateFormat is the fixed timezone you want to use for every displayed date, not the device's default one. Also ensure that the timestamp column in your database starts counting at the same point in time than Java (1/1/1970, AKA Unix epoch), and has the same precission (milliseconds).

There's another android.text.format.DateFormat class, but I don't see any point on using it.

like image 37
Mister Smith Avatar answered Oct 05 '22 22:10

Mister Smith