2

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

xingbin
  • 27,410
  • 9
  • 53
  • 103
Ashok Kumar
  • 393
  • 1
  • 7
  • 17
  • 2
    `dd/MM/yyyy, hh:mm:ss` – Aniket Sahrawat Mar 27 '18 at 13:02
  • 1
    `mm` represents minutes not months. `MM` represents months – davidxxx Mar 27 '18 at 13:02
  • Exactly, refer to [SimpleDateFormat javadoc](https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html) section `Date and Time Patterns` – xxxvodnikxxx Mar 27 '18 at 13:04
  • tried replacing 'mm' with 'MM' for months it still din't work – Ashok Kumar Mar 27 '18 at 13:05
  • The error message, "error while parsing milliseconds to date", seems unrelated to the code here. – Basil Bourque Mar 27 '18 at 20:09
  • FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/9/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/9/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/9/docs/api/java/time/package-summary.html) classes built into Java 8 & Java 9. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Mar 27 '18 at 20:24

4 Answers4

7

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

A. Bandtock
  • 1,233
  • 8
  • 14
3

You should use the same format with input string:

DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy, hh:mm:ss");
xingbin
  • 27,410
  • 9
  • 53
  • 103
2

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");
davidxxx
  • 125,838
  • 23
  • 214
  • 215
1

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • Hm, although I see and understand that you are a big fan of new `java.time`-package, your recommendation of using it would unfortunately not have prevented the OP from using the wrong pattern. So the fact remains that `java.time` is still not clever enough to prevent such user mistakes (although certainly the better library compared with `SimpleDateFormat`). And as usual practice in most of your time-related posts, advertising an extra 3rd-party-libry although completely unrelated to the concrete problem of the OP is at least to say superfluous. – Meno Hochschild Mar 29 '18 at 10:04
  • One detail of my previous comment was imprecise. `java.time` would reject the pattern in parsing by throwing a runtime exception with a message which might not be very clear for many users. And for formatting/printing, `java.time` would not even complain about such an obviously wrong pattern! – Meno Hochschild Mar 29 '18 at 10:23