Sino
Sino

Reputation: 886

Android converting calendar in one TimeZone to local TimeZone

I am using following code to convert timezone (GMT-3) to device local timezone.

int hour=17,minute=0,day=12,month=6,year=2014;

Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT-3"));
cal.set(year, (month-1), day,hour,minute);  

cal.setTimeZone(TimeZone.getDefault());
Log.d("Time", cal.get(Calendar.DATE)+"/"+cal.get(Calendar.MONTH)+"/"+cal.get(Calendar.YEAR)+" , "+cal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE)+" "+cal.get(Calendar.AM_PM));

My local timezone is GMT+5:30
Expected result is
Time 13/5/2014, 1:30 0
But I am getting the result
12/5/2014 , 13:30 1

Upvotes: 1

Views: 2173

Answers (1)

Meno Hochschild
Meno Hochschild

Reputation: 44061

Sorry for you, GregorianCalendar is sometimes the hell. Your problem is following:

If you immediately set the timezone after having set the fields for year, month etc. then this mutable calendar class will only shift the timezone retaining the already set fields containing the local time. Those fields for year, month etc. will NOT be recalculated. This behaviour causes a shift on the global timeline represented by cal.getTime(), too.

In order to force the calendar object to recalculate the fields you need to call a getter. Watch out for following code and especially remove the comment marks to see the effect.

int hour = 17, minute = 0, day = 12, month = 6, year = 2014;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ");
TimeZone tz1 = TimeZone.getTimeZone("GMT-3");
sdf.setTimeZone(tz1);

Calendar cal = new GregorianCalendar(tz1);
cal.set(year, (month - 1), day, hour, minute);
//      System.out.println(sdf.format(cal.getTime()));
//      System.out.println("Hour=" + cal.get(Calendar.HOUR_OF_DAY));

TimeZone tz2 = TimeZone.getTimeZone("GMT+0530");
sdf.setTimeZone(tz2);
cal.setTimeZone(tz2);
System.out.println(sdf.format(cal.getTime()));
System.out.println("Hour=" + cal.get(Calendar.HOUR_OF_DAY));

Output with comment-disabled lines:

2014-06-12T17:00+0530
Hour=17

Output with enabled lines after having removed the comment marks:

2014-06-12T17:00-0300
Hour=17
2014-06-13T01:30+0530
Hour=1

Upvotes: 3

Related Questions