Question

How to parse the date string like '21Jul12'. I have tried the following way:

import org.apache.commons.lang.time._

DateUtils.parseDate("21Jul12", Array("ddMMMyy"));

but it can't work due to the error:

java.text.ParseException: Unable to parse the date: 21Jul21
    at org.apache.commons.lang.time.DateUtils.parseDateWithLeniency(DateUtils.java:359)
    at org.apache.commons.lang.time.DateUtils.parseDate(DateUtils.java:285)
    at .<init>(<console>:20)
    at .<clinit>(<console>)
    at .<init>(<console>:11)
    at .<clinit>(<console>)
    at $print(<console>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
    at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
    at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
    at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
    at java.lang.Thread.run(Thread.java:662)

Even I use java.text.SimpleDateFormat, i got a similiar exception:

java.text.ParseException: Unparseable date: "21Jul12"
    at java.text.DateFormat.parse(DateFormat.java:337)
    at .<init>(<console>:13)
    at .<clinit>(<console>)
    at .<init>(<console>:11)
    at .<clinit>(<console>)
    at $print(<console>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
    at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
    at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
    at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
    at java.lang.Thread.run(Thread.java:662)
Was it helpful?

Solution 2

it works when I set the locale to Locale.en_US explicitly. Exception thrown because of the default locale setting is Locale.CHINA

OTHER TIPS

Here is the code for the above mentioned dates to parse

System.out.println("ddMMMyy >>>" + DateUtils.parseDate("21Jul12", new String[] { "ddMMMyy" }));

System.out.println("yyyy-MM-dd >>>" + DateUtils.parseDate("2012-07-21", new String[] { "yyyy-MM-dd" }));

System.out.println("yyyy MMM dd >>>" + DateUtils.parseDate("2012 Jul 21", new String[] { "yyyy MMM dd" }));

and the result on the console

ddMMMyy >>>Sat Jul 21 00:00:00 CEST 2012
yyyy-MM-dd >>>Sat Jul 21 00:00:00 CEST 2012
yyyy MMM dd >>>Sat Jul 21 00:00:00 CEST 2012

maybe you tried to parse "2012 Jul 21" with "ddMMMyy"

System.out.println("ddMMMyy >>>" + DateUtils.parseDate("2012 Jul 21", new String[] { "ddMMMyy" }));

gives your stack

java.text.ParseException: Unable to parse the date: 2012 Jul 21
at org.apache.commons.lang.time.DateUtils.parseDateWithLeniency(DateUtils.java:359)
at org.apache.commons.lang.time.DateUtils.parseDate(DateUtils.java:285)
at com.collibra.dgc.core.model.activity.impl.TestTree.testname(TestTree.java:88)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

We use a process of elimination for our date parsing, basically, we use an array of commonly used date formats (for our application) and the one that doesn't throw an exception is the one we use. Not the cleanest of solutions, but it works...

For example

parse("2012 Jul 21", "ddMMMyy", "yyyy MMM dd");
parse("21Jul12", "ddMMMyy", "yyyy MMM dd");


public Date parse(String value, String... formats) throws ParseException {
    Date date = null;

    for (String format : formats) {
        try {
            date = new SimpleDateFormat(format).parse(value);
        } catch (ParseException exp) {
        }
    }

    if (date == null) {
        throw new ParseException(value + " is an unrecognized date format", 0);
    }

    return date;
}
String date="21JUL12";
        try {
            System.out.println(new   SimpleDateFormat("ddMMMyy").parse(date));
        }
        catch(ParseException ex) {
            ex.printStackTrace();
        }

the above code gives me this output:

Sat Jul 21 00:00:00 BST 2012

tl;dr

LocalDate.parse(                                          // Represent a date-only value without time-of-day and without time zone using the `LocalDate` class.
    "21Jul12" ,                                           // A poor choice of format for date value as text. Instead use standard ISO 8601 formats.
    DateTimeFormatter.ofPattern( "ddMMMuu" , Locale.US )  // Specify `Locale` to determine the human language and cultural norms used in translating.
)

No need for Apache utilities.

java.time

The modern approach uses java.time classes.

String input = "21Jul12" ; 
DateTimeFormatter f = DateTimeFormatter.ofPattern( "ddMMMuu" , Locale.US ) ;
LocalDate ld = LocalDate.parse( input , f ) ;

ld.toString(): 2012-07-21

Two tips:

  • Use 4-digit years.
    • Saving the space of two digits is not worth the ambiguity, confusion, and errors I have seen spawned both among programmers and users/readers. Pixels and toner are cheap enough nowadays that I suspect you can afford the two extra digits for century.
    • In any event, the java.time classes assume 21st century (20xx) if omitted.
  • Use standard ISO 8601 formats for exchanging date-time values as text.
    • These formats are wisely designed to be unambiguous, easy to parse by machine, and easy to read by humans across various cultures.
    • The java.time classes use these standard formats by default when parsing/generating strings.

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top