Date/Time/Timezone manipulation and conversion in Java: a few examples
February 14th, 2010 in Java/J2EE. 2 commentsJava date/time manipulation, formatting and conversion can be very tricky with things getting even more complicated when timezones are taken into consideration. A lot of developers (even seasoned ones) often run into problems when playing with date/time values.
Here’s a ready reference of some common date manipulation/formatting tricks that can be quite handy. They have been tested on Jdk 1.5.
-
Convert a String to a java.util.Date object:
Date doStringToDate(String date,String inFormat){ DateFormat df = new SimpleDateFormat(inFormat); Date dt=null; try { dt= df.parse(date); } catch (ParseException e) { //handle exception } return dt; } -
Convert java.util.Date object to a String:
Specify the format of the String that you want using the SimpleDateFormat.String doDateToString(Date dt){ SimpleDateFormat formatter=new SimpleDateFormat("MMM d KK:mm a E Z"); String s=formatter.format(dt); return s; } -
Convert a date String in one format to a different format:
The following will convert the String inDate in inFormat to a date String in outFormat. Again remember that inFormat must exactly match the format of inDate.String oneFormatToAnother(String inDate,String inFormat,String outFormat){ DateFormat inDf = new SimpleDateFormat(inFormat);//input date is in this format Date dt=null; String outDate; try { dt= inDf.parse(inDate); } catch (ParseException e) { //handle exception } DateFormat outDf=new SimpleDateFormat(outFormat); outDate=outDf.format(dt); return outDate; }So calling the above method in the following way- oneFormatToAnother(”02/11/2009″,”dd/MM/yyyy”,”E MMM d KK:mm a Z”) will return “Nov 2 00:00 AM -0500″ if your JVM is in EST.
-
Date and Time calculation:
Use the methods of the Calendar class if you need to perform date Calculations. An example is given below:void dateCalculationExample(Date d1){ Calendar c= Calendar.getInstance(); c.setTime(d1); c.add(Calendar.YEAR, 2); c.add(Calendar.HOUR,5); c.add(Calendar.DAY_OF_MONTH,-4); Date d2=c.getTime(); System.out.println("modified date="+d2.toString()); } -
Timezone conversion of a date String:
Changing the timezone of a Date object is not recommended and might produce unexpected results. What will work however is timezone conversion of a date string. The following will convert a date string ‘inDateStr’ which is in ‘inTz’ Timezone and in format ‘inFormat’ into another date string in ‘outTz’ timezone and formatted as in ‘outFormat’.String changeTimeZone(String inTZ,String outTZ, String inDateStr, String inFormat,String outFormat){ //convert the incoming date string to a date object Date inDate=null; DateFormat inDf=new SimpleDateFormat(inFormat); inDf.setTimeZone(TimeZone.getTimeZone(inTZ)); try{ inDate=inDf.parse(inDateStr); }catch(ParseException e){ //handle exception } //System.out.println("inDate tostring="+inDate.toString());//Note this will give you time in default TZ and not in inTZ DateFormat outDf=new SimpleDateFormat(outFormat); outDf.setTimeZone(TimeZone.getTimeZone(outTZ)); String st=outDf.format(inDate); return st }Example: changeTimeZone(”America/Denver”,”Asia/Calcutta”,”02/08/2010 15:00:20″,”MM/dd/yyyy HH:mm:ss”,”dd/MM/yy HH:mm:ss z”); will result in ‘09/02/10 03:30:20 IST’.
-
Convert timezones of a timestamp when storing into a database:
Very often date/time information in an application must be stored in a fixed timezone even though users may enter time from any timezone. Therefore there is always a need to convert time into this fixed timezone. It is not a good idea to use the database default timezone in this case as this may change due to administrative reasons. Instead the conversion should be done explicitly.
If you have a date string ‘inDateStr’ in Timezone ‘inTz’ and need to convert it to a different timezone(outTz) when storing in a database column of type Timestamp use the following, paying particular attention to lines 24 and 25.public void loadTimeInDB(String inDateStr, String inTz,String inFormat,String outTz){ Connection oraConn=null; PreparedStatement stmt=null; Date inDate=null; //convert to Date object DateFormat inDf=new SimpleDateFormat(inFormat); inDf.setTimeZone(TimeZone.getTimeZone(inTz)); try{ inDate=inDf.parse(inDateStr); }catch(ParseException e){ //handle exception } try{ //do DB stuff Class.forName("oracle.jdbc.OracleDriver"); oraConn = DriverManager.getConnection("jdbc:oracle:thin:@host:port:sid", "username","pw"); stmt=oraConn.prepareStatement("insert into test_date values(?,SYSDATE)"); //timezone conversion takes place here with a Calendar Object Timestamp dbTs=new Timestamp(inDate.getTime()); Calendar cal=Calendar.getInstance(TimeZone.getTimeZone(outTz)); stmt.setTimestamp(1,dbTs,cal); //update and close connection stmt.executeUpdate(); stmt.close(); oraConn.close(); }catch(Exception e){ //handle exception } }So if you call the above method with the parameters loadTimeInDB(”02/08/2010 15:36:20″,”America/New_York”,”MM/dd/yyyy HH:mm:ss”,”Europe/Paris”) the timestamp column in the databse should show as 08-FEB-10 09.36.20.000000000 PM. or something similar.
Caveat: The above was tested in Oracle 10g and did the conversion correctly, but in MySQL it did not. So use it carefully. If this did not work for you, you might try manually calculating the offset of your target timezone as described next. -
Convert timezones using offset and store in database:
Timezone conversions can also be achieved by calculating the time difference between the two timezones (using java.util.Timezone’s getOffset() method) and adding this difference to the time that needs to be converted. So you might think this should be pretty straight forward.
However in our example above, when you do a inDate.getTime(), this automatically converts the time given by ‘inDateStr’ and ‘inTz’ to the application’s (jvm) timezone.
In other words if the time component ‘inDateStr’ is “16:15:20″ and ‘inTz’ is “America/Denver”, then when you do a inDate.getTime(), the time is implicitly converted to ‘18:15:20′ if your jvm’s default timezone is “America/New_York” (+2 hours). For this reason, the time difference between the target timezone ‘outTz’ and jvm’s timezone is used in the calculateOffset() method below, instead of the time difference between ‘inTz’ and ‘outTz’. Note that this behavior might differ from jvm to jvm, so make sure to test thoroughly. The modified code is as below:void loadTimeInDB(String inDateStr, String inTz,String inFormat,String outTz){ Connection oraConn=null; PreparedStatement stmt=null; Date inDate=null; //convert to Date object DateFormat inDf=new SimpleDateFormat(inFormat); inDf.setTimeZone(TimeZone.getTimeZone(inTz)); try{ inDate=inDf.parse(inDateStr); }catch(ParseException e){ //handle exception } try{ //do DB stuff Class.forName("oracle.jdbc.OracleDriver"); oraConn = DriverManager.getConnection("jdbc:oracle:thin:@host:port:sid", "username","pw"); stmt=oraConn.prepareStatement("insert into test_date values(?,SYSDATE)"); //timezone conversion takes place here using the calculateOffset method Timestamp dbTs=new Timestamp(inDate.getTime()+calculateOffset(inDate,outTz)); stmt.setTimestamp(1,dbTs); //update and close connection stmt.executeUpdate(); stmt.close(); oraConn.close(); }catch(Exception e){ //handle exception } } long calculateOffset(Date onDate,String outTz){ //First get offset from UTC of Target Timezone TimeZone Tz1=TimeZone.getTimeZone(outTz); long outTzOffset= Tz1.getOffset(onDate.getTime()); //Now get the offset from UTC of your application (JVMs) default timezone Calendar cal=Calendar.getInstance(); TimeZone jvmTz=cal.getTimeZone(); long inTzOffset=jvmTz.getOffset(onDate.getTime()); //calculate offset of target timezone from jvm timezone long offset=(outTzOffset - inTzOffset); //double offsetInHrs=offset/(1000*60*60); //offset in hours: use for debugging return offset; }So calling the above function with these parameters: loadTimeInDB(”02/09/2010 22:34:20″,”Europe/Paris”,”MM/dd/yyyy HH:mm:ss”,”Asia/Shanghai”) will store the time as “10-FEB-10 05.34.20.000000000 AM” in the database, which is the time that corresponds to 10:34 PM of the previous day (Feb 9th) in Paris.
In the above, the inFormat parameter must exactly match the format of the date represented by the date parameter, for example if date is “13/12/2007″ then inFormat must be “dd/MM/yyyy”, if date is “13 Dec 07″ then format must be “dd MMM yyyy” and so on. See the javadocs for SimpleDateFormat for more.


May 23rd, 2011 at 12:28 am says:
Very useful for me, thanks for sharing.
August 29th, 2011 at 6:18 pm says:
Thank you for a very useful article.