Ashok Kumar
Ashok Kumar

Reputation: 403

Getting unable to parse date exception

I have date and time on string type 20/03/2018, 18:20:44 Is it possible to change it to date format in java? I tried this code:

public static Date getDate(String dateString) {
    DateFormat formatter = new SimpleDateFormat("dd/mm/yyyy hh:mm:ss");
    formatter.setTimeZone(TimeZone.getTimeZone("PST"));
    try {
        Date date = formatter.parse(dateString);
        return date;
    } catch (ParseException e) {
        logger.error("error while parsing milliseconds to date" + dateString, e);
    }
    return null;
}

I get unable to parse exception and returned with null

Upvotes: 2

Views: 5292

Answers (4)

Basil Bourque
Basil Bourque

Reputation: 339917

tl;dr

Your formatting pattern was incorrect, using the wrong case and omitting the comma.

Also, you are using troublesome classes supplanted years ago by java.time classes.

LocalDateTime.parse(                                       // Create a `LocalDateTime` object as the input string lacks any time zone or offset-from-UTC.
    "20/03/2018, 18:20:44" , 
    DateTimeFormatter.ofPattern( "dd/MM/uuuu, HH:mm:ss" )  // Define a formatting pattern to match the input.
)
.atZone(                                                   // Assign a time zone to the `LocalDateTime` to create a `ZonedDateTime` object.
    ZoneId.of( "America/Los_Angeles" )                     // Specify time zone to be assigned. Always use proper zone names `continent/region`; never use 3-4 character pseudo-zones.
)

2018-03-20T18:20:44-07:00[America/Los_Angeles]

java.time

You are using troublesome old date-time classes that are now legacy, supplanted by the java.time classes.

Parse your string as a LocalDateTime since it lacks an indicator of time zone or offset-from-UTC.

String input = "20/03/2018, 18:20:44" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu, HH:mm:ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;

ldt.toString(): 2018-03-20T18:20:44

Lacking a time zone or offset-from-UTC means that this does not represent a moment, is not a point on the timeline. Without the context of a zone/offset, this represents only a vague idea about potential moments along a range of 26-27 hours.

Apparently you are certain this input was actually meant to be in certain time zone. Apply a ZoneId to this LocalDateTime to get a ZonedDateTime object.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Los_Angeles" ) ; 
ZonedDateTime zdt = ldt.atZone( z ) ;

Conversion

Best to avoid the troublesome legacy classes. But if you must produce a java.util.Date to inter-operate with old code not yet updated for java.time, you can convert. To convert back and forth, call new methods on the old classes.

A java.util.Date represents a point on the timeline in UTC, with a resolution of milliseconds. So its replacement in java.time is Instant. An Instant is also a point on the timeline in UTC, with a finer resolution of nanoseconds. To get to a Date, we need an Instant, which we can pull from our ZonedDateTime.

Instant instant = zdt.toInstant() ;  // Same moment, same point on the timeline, different wall-clock time.

Now we can get the legacy class object, Date, by calling Date.from.

java.util.Date date = Date.from( instant ) ;  // Do this only if you *must* work with `Date` class.

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.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for 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.

Upvotes: 1

xingbin
xingbin

Reputation: 28289

You should use the same format with input string:

DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy, hh:mm:ss");

Upvotes: 3

davidxxx
davidxxx

Reputation: 131496

You did two mistakes :

  • mm represents minutes. MM represents months.
    But You specify mm in the month part of the date format.
  • the coma character : , provided in the input has also to be present in the date format.

So with a String input in this form : "20/03/2018, 18:20:44", you should use this DateFormat :

DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy, hh:mm:ss");

Upvotes: 2

A. Bandtock
A. Bandtock

Reputation: 1241

You've used the wrong string replacements inside your simple date format, it should be dd/MM/yyyy, HH:mm:ss. Note the capitalisation of the HH as well, your time is in 24 hour format so it must be HH over hh

So with the applied changes your code will look like this:

public static Date getDate(String dateString) {
  DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy, HH:mm:ss");
  formatter.setTimeZone(TimeZone.getTimeZone("PST"));
  try {
    return formatter.parse(dateString);
  } catch (ParseException e) {
    logger.error("error while parsing milliseconds to date" + dateString, e);
  }
  return null;
}

Read more on the various patterns available here, as an aside it is generally recommended to use the ISO 8601 format for dates, so yours would be yyyy-MM-ddTHH:mm:ss

Upvotes: 7

Related Questions