Java Convert GMT/UTC to Local time doesn't work as expected
In Order to show a reproducible scenario, I am doing the following
Get the current system time (local time)
Convert Local time to UTC // Works Fine Till here
-
Reverse the UTC time, back to local time. Followed 3 different approaches (listed below) but all the 3 approaches retains the time in UTC only.
{
long ts = System.currentTimeMillis(); Date localTime = new Date(ts); String format = "yyyy/MM/dd HH:mm:ss"; SimpleDateFormat sdf = new SimpleDateFormat (format); // Convert Local Time to UTC (Works Fine) sdf.setTimeZone(TimeZone.getTimeZone("UTC")); Date gmtTime = new Date(sdf.format(localTime)); System.out.println("Local:" + localTime.toString() + "," + localTime.getTime() + " --> UTC time:" + gmtTime.toString() + "-" + gmtTime.getTime()); // Reverse Convert UTC Time to Locale time (Doesn't work) Approach 1 sdf.setTimeZone(TimeZone.getDefault()); localTime = new Date(sdf.format(gmtTime)); System.out.println("Local:" + localTime.toString() + "," + localTime.getTime() + " --> UTC time:" + gmtTime.toString() + "-" + gmtTime.getTime()); // Reverse Convert UTC Time to Locale time (Doesn't work) Approach 2 using DateFormat DateFormat df = new SimpleDateFormat (format); df.setTimeZone(TimeZone.getDefault()); localTime = df.parse((df.format(gmtTime))); System.out.println("Local:" + localTime.toString() + "," + localTime.getTime() + " --> UTC time:" + gmtTime.toString() + "-" + gmtTime.getTime()); // Approach 3 Calendar c = new GregorianCalendar(TimeZone.getDefault()); c.setTimeInMillis(gmtTime.getTime()); System.out.println("Local Time " + c.toString());
}
Solution 1:
I also recommend using Joda as mentioned before.
Solving your problem using standard Java Date
objects only can be done as follows:
// **** YOUR CODE **** BEGIN ****
long ts = System.currentTimeMillis();
Date localTime = new Date(ts);
String format = "yyyy/MM/dd HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(format);
// Convert Local Time to UTC (Works Fine)
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date gmtTime = new Date(sdf.format(localTime));
System.out.println("Local:" + localTime.toString() + "," + localTime.getTime() + " --> UTC time:"
+ gmtTime.toString() + "," + gmtTime.getTime());
// **** YOUR CODE **** END ****
// Convert UTC to Local Time
Date fromGmt = new Date(gmtTime.getTime() + TimeZone.getDefault().getOffset(localTime.getTime()));
System.out.println("UTC time:" + gmtTime.toString() + "," + gmtTime.getTime() + " --> Local:"
+ fromGmt.toString() + "-" + fromGmt.getTime());
Output:
Local:Tue Oct 15 12:19:40 CEST 2013,1381832380522 --> UTC time:Tue Oct 15 10:19:40 CEST 2013,1381825180000
UTC time:Tue Oct 15 10:19:40 CEST 2013,1381825180000 --> Local:Tue Oct 15 12:19:40 CEST 2013-1381832380000
Solution 2:
You have a date with a known timezone (Here Europe/Madrid
), and a target timezone (UTC
)
You just need two SimpleDateFormats:
long ts = System.currentTimeMillis(); Date localTime = new Date(ts); SimpleDateFormat sdfLocal = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss"); sdfLocal.setTimeZone(TimeZone.getTimeZone("Europe/Madrid")); SimpleDateFormat sdfUTC = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss"); sdfUTC.setTimeZone(TimeZone.getTimeZone("UTC")); // Convert Local Time to UTC Date utcTime = sdfLocal.parse(sdfUTC.format(localTime)); System.out.println("Local:" + localTime.toString() + "," + localTime.getTime() + " --> UTC time:" + utcTime.toString() + "-" + utcTime.getTime()); // Reverse Convert UTC Time to Locale time localTime = sdfUTC.parse(sdfLocal.format(utcTime)); System.out.println("UTC:" + utcTime.toString() + "," + utcTime.getTime() + " --> Local time:" + localTime.toString() + "-" + localTime.getTime());
So after see it working you can add this method to your utils:
public Date convertDate(Date dateFrom, String fromTimeZone, String toTimeZone) throws ParseException { String pattern = "yyyy/MM/dd HH:mm:ss"; SimpleDateFormat sdfFrom = new SimpleDateFormat (pattern); sdfFrom.setTimeZone(TimeZone.getTimeZone(fromTimeZone)); SimpleDateFormat sdfTo = new SimpleDateFormat (pattern); sdfTo.setTimeZone(TimeZone.getTimeZone(toTimeZone)); Date dateTo = sdfFrom.parse(sdfTo.format(dateFrom)); return dateTo; }