Search code examples
javaandroidstringsimpledateformatjava.util.date

Java : DATE_EXCEPTION Unparseable date : "2017-06-28 08:30 AM" (at offset 17)


I wanted to get a java.util.Date Object by parsing a String date : "2017-06-28 08:30 AM". This parsing is used in my Android application. This is working without any parsing exception in many Android versions. Like 7.0, 4.4.2 and 5.1. But this is not working in Android 6.0.

This is my error log and SimpleDateFormat,

W/System.err: java.text.ParseException: Unparseable date: "2017-06-28 08:30 AM" (at offset 17)
at java.text.DateFormat.parse(DateFormat.java:579)
at biz.spsolutions.peopleedge.RosterClockInActivity.setData(RosterClockInActivity.java:531)
at biz.spsolutions.peopleedge.RosterClockInActivity.onCreate(RosterClockInActivity.java:391)
at android.app.Activity.performCreate(Activity.java:6877)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1136)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3208)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3351)
at android.app.ActivityThread.access$1100(ActivityThread.java:222)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1796)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7230)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

And This is my SimpleDateFormat,

SimpleDateFormat currentFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm a")

Also I have tried in this format too,

SimpleDateFormat currentFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm aaa")

How can I handle this exception ? Have any ideas ?


Solution

  • tl;dr

    No problem when using the modern java.time classes.

    LocalDateTime.parse( 
        "2017-06-28 08:30 AM" , 
        DateTimeFormatter.ofPattern( "uuuu-MM-dd hh:mm a" , Locale.US ) 
    )
    

    2017-06-28T08:30

    Using java.time

    You are using troublesome old date-time classes that are now legacy, supplanted by the java.time classes. For Android, see last bullet below.

    Note that I specify Locale.US as part of my formatter. The locale determines the cultural norms used in determining issues such as capitalization. I suspect your JVM’s current default may set to a locale expecting "AM/PM" to be in lowercase. Always specify the expected/desired locale rather than rely implicitly on the current default locale which can changed at any time by any code in app of your JVM. For more info, see other Question.

    String input = "2017-06-28 08:30 AM" ;
    DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd hh:mm a" , Locale.US ) ;
    LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
    

    See this code run live at IdeOne.com.

    ldt.toString(): 2017-06-28T08:30


    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.

    Where to obtain the java.time classes?