javadate-parsing

Wonky dating in Java


The following Java code just parses a date (with time portion) 2009-01-28-09:11:12 using SimpleDateFormat. Let's have look at it.

final public class Main
{
    public static void main(String[] args)
    {            
        try
        {
            DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
            Date d = df.parse("2009-01-28-09:11:12");
            System.out.println(d);
        }
        catch (ParseException ex)
        {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

The date (with time) displayed (after parsing) by the above code is as follows,

Sun Nov 30 22:07:51 IST 2008

even though we are attempting to parse the date 2009-01-28-09:11:12. It looks somewhat wonky. Why does it parse so?


Solution

  • Shouldn't your date format be something like this:

    DateFormat df = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
    

    to match this format:

    Date d = df.parse("2009-01-28-09:11:12");
    

    ?

    As for why, per this:

    the parser actually looks at these as numbers, and the trick is that - is a part of a number, representing negative numbers. So if you do:

    df.parse("2009-01-02-00:00:00")
    

    it gives:

    Mon Dec 01 00:02:00 EST 2008
    

    That parses 2009 as yyyy, then -0 as MM (which is previous month as months start from 1), then 1 as dd, etc.

    As per parse in DateFormat:

    By default, parsing is lenient: If the input is not in the form used by this object's format method but can still be parsed as a date, then the parse succeeds. Clients may insist on strict adherence to the format by calling setLenient(false).

    I guess, if you have an option, it would be better to use slashes instead of dashes, if you like formats like 2009/01/02 12:34:56. This:

    df.parse("2009/01/02-00:00:00")
    

    will throw an exception:

    ERROR java.text.ParseException:
    Unparseable date: "2009/01/02-00:00:00"
    

    I can only conclude it's a very good thing that / is not considered a number division by DateFormat...