Monday, January 24, 2011

Agony with Dates, Timezone and Java Date Utilities

Am not a guru when it comes to dealing with dates and timezone and it just got worse when I was dealing with Java Library to get done with a date related task. Job was to display current date in IST (India) timezone. As it may sound to be quite simple, it did give me few sweaty hours with my system on EST timezone. Let's talk code:

public class DateConversionTest {  
public static void main(String[] args) {
  Calendar cal = Calendar.getInstance();
  DateFormat dateFormat = new SimpleDateFormat();
  dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta"));

  //L1: Convert date to IST timezone 
  String dateString = dateFormat.format(cal.getTime());
  System.out.println(dateString);

  //L2: Use parse method to get Date object, as advised by java.util.Date
  try{
      System.out.println("Date using parse method: "+

                              dateFormat.parse(dateString));
  }catch (ParseException e) { 
       e.printStackTrace();
  }

  //L3: Use date constructor

   System.out.println("Date using constructor: " +new Date(dateString));
  }
}

SimpleDateFormat provides the capability to convert date to particular timezone. I could have used Calendar for it, but let me get to it later why I opted out . The string "dateString" from DateFormat(//L1) provided the correct date in IST timezone. I had a mandate of returning "Date" object so the next step was to convert this to a Date object.
I looked up the javadoc and the constructor of java.util.Date with String parameter was deprecated and said "Deprecated. As of JDK version 1.1, replaced by DateFormat.parse(String s)."
As per the doc, I used the alternative but to my surprise the above method returned back my system date in EST timezone(look at output for details). Instead of using DateFormat I tried to replace the program with Calendar object but Calendar.getTime() would also return date in my system timezone inspite of converted dated already provided to it. This was the reason I did not use it in my test code.
After much of experiments, I tried to use the date constructor with String parameter(//L3) which finally returned the expected date in IST as stored in "dateString" object.

Output:
String date from formatter: 1/25/11 2:35 AM
Date using parse method: Mon Jan 24 16:05:00 EST 2011
Date using constructor: Tue Jan 25 02:35:00 EST 2011


Why should a deprecated constructor work as expected and DateFormat worked so strangely?
With my research it looked like DateFormat.parse internally works using Calendar object which returns date (Calendar.getTime()) based on the timezone of the JVM. (TimeZone.getDefault()). If I alter this, I get date in expected timezone. Note, JavaDoc does state that it returns date in UTC format but it always return in default timezone of JVM.
When a certain date is already provided by developer, shouldn't this auto conversion avoided by Java? I would like to hear how other developers would solve it in more effective way as it clearly doesn't leave me satisfied.

Tuesday, January 11, 2011

Library to validate Phone Numbers

Recently came across this article in server side that talks about libphonenumber, which is library to validate international phone numbers. Java and Javascript libraries looks promising and can be quite useful in building applications.

http://code.google.com/p/libphonenumber/

One of the direct use case I can think of is when we have to send notifications from application to mobile device. It would help to have this validation handy when users feed in their numbers to the applications.

Twilio developers can also be excited about this as they can build more reliable voice and sms application.

Happy playing with libphonenumber.