Reputation: 349
I need to convert a String
containing a date into a date object.
The String
will be in the format "yyyy-mm-dd HH:mm:ss"
and I want the "MM/dd/yyyy HH:mm:ss a "
format as result.
String dateString = "2018-03-20 09:31:31";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss a",
Locale.ENGLISH);
LocalDate date = LocalDate.parse(dateString , formatter);
The code above is throwing an exception.
Upvotes: 3
Views: 7775
Reputation: 23
That's a common error, based on the misconception that dates have formats - but they actually don't.
Date/time objects have only values, and those values - usually numerical - represent the concept of a date (a specific point in the calendar) and a time (a specific moment of the day).
If you have a String
, then you don't actually have a date. You have a text (a sequence of characters) that represents a date. Note that all of the strings below are different (they have a different sequence of characters), but all represent the same date (the same values, the same point in the calendar):
2018-03-20 09:31:31
03/20/2018 9:31:31 AM
(using USA's format: month/day/year)Tuesday, March 20th 2018, 09:31:31 am
What you want to do is to get one format (one String
, one text representing a date) and transform it to another format (anoter String
, another different sequence of characters that represents the same date).
In Java (and in many other languages - if not all - btw) you must do it in 2 steps:
String
to a date/time object (convert the text to the numerical values) - that's what the parse
method doesThat said, when you call the parse
method, you're trying to transform a String
(a text, a sequence of characters) into a date/time object. This means that the DateTimeFormatter
must have a pattern that matches the input.
The input is 2018-03-20 09:31:31
, which is year-month-day hour:minute:second
. And the formatter you used to parse it has the pattern MM/dd/yyyy HH:mm:ss a
(month/day/year hour:minute:second am/pm
).
You used the output pattern (the one that should be used in step 2) to parse the input. That's why you've got an exception: the formatter tried to parse a month with 2 digits followed by a /
when the input actually contains a year with 4 digits followed by a -
.
You must use a different DateTimeFormatter
for each step, using the correct pattern for each case. YCF_L's answer has the code that does the job, I'd just like to add one little detail. The formatter used for the output (step 2) is:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
"MM/dd/yyyy HH:mm:ss a", Locale.ENGLISH
);
Note that HH
is used for the hours. Take a look at the javadoc and you'll see that uppercase HH
represents the hour-of-day fields (values from 0 to 23 - so 1 AM is printed as 01
and 1 PM is printed as 13
).
But you're also printing the AM/PM field (the a
in the pattern), so maybe what you need is actually the lowercase hh
, which is the clock-hour-of-am-pm (values from 1 to 12) or even KK
(hour-of-am-pm (values from 0 to 11)).
Upvotes: 2
Reputation: 3325
You need to do a 2 steps conversion:
LocalDateTime.toLocalDate()
From this LocalDateTime object into the your String object in the right format
String dateString = "2018-03-20 09:31:31";
DateTimeFormatter formatterForWrongFormat = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(" ")
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.toFormatter();
//1- from String(wrong format) into datetime object
LocalDateTime dateTime = LocalDateTime.parse(dateString , formatterForWrongFormat);
// 1.1 extract date object (Optional)
LocalDate myDate = dateTime.toLocalDate();
// 2- now from your LocalDateTime to the String in the RIGHT format
DateTimeFormatter formatterForRightFormat = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss a",
Locale.ENGLISH);
System.out.println("right format: "+dateTime.format(formatterForRightFormat));
you can test this code here
Upvotes: 0
Reputation: 469
String dateString = "2018-03-20 09:31:31";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date date = formatter.parse(dateInString);
DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
String reportDate = df.format(date );
} catch (ParseException e) {
e.printStackTrace();
}
Upvotes: 0
Reputation: 60046
You have to use two Formatter
, one to covert String
to LocalDateTime
and the other to format this date as you want :
From String to LocalDateTime :
String dateString = "2018-03-20 09:31:31";
LocalDateTime date = LocalDateTime.parse(
dateString,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH)
);
Now From LocalDateTime to String :
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
"MM/dd/yyyy HH:mm:ss a", Locale.ENGLISH
);
String newDate = date.format(formatter);
System.out.println(newDate);// 03/20/2018 09:31:31 AM
Note : You have to use LocalDateTime
instead of just LocalDate
, your format contain both date and time, not just date, else you will get an error :
java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: HourOfDay
Upvotes: 5
Reputation: 81
You can use the SimpleDateFormatter which is easier to implement and permit you to change the format of your date easily.
More here : What are the date formats available in SimpleDateFormat class?
Hope this will help you !
Upvotes: -1