Reputation: 1638
Does the style of the formatter in the parse method of the DateTime class have to match the exact style of the string? For instance, I'm getting a TimeStamp object from the database (Oracle) and converting it to a string. In the database the TimeStamp is stored like this
08-AUG-12 12.00.00.000000000 AM
I set my formatter to this style
String pattern = "dd-MMM-yy";
I get this exception
java.lang.IllegalArgumentException: Invalid format: "08-AUG-12 12.00.00 AM" is malformed at " 12.00.00 AM"
org.joda.time.format.DateTimeFormatter.parseDateTime(DateTimeFormatter.java:866)
org.joda.time.DateTime.parse(DateTime.java:144)
What exactly does this mean and how would I go about fixing it? When I set my formatter to "yy-MMM-dd hh.mm.ss aa"
I don't get an exception but it prints in the browser like this: 2008-08-12T00:00:00.000-04:00
, but I need for it to print out as "dd-MMM-yy hh:mm:ss aa"
Upvotes: 20
Views: 70049
Reputation: 79075
java.time
In March 2014, Java 8 introduced the modern, java.time
date-time API which supplanted the error-prone legacy java.util
date-time API. Any new code should use the java.time
API*.
Also, shown below is a notice on the Joda-Time Home Page:
Note that from Java SE 8 onwards, users are asked to migrate to
java.time
(JSR-310) - a core part of the JDK which replaces this project.
Does the style of the formatter in the parse method of the DateTime class have to match the exact style of the string?
Mostly 'Yes'. However, there are some exceptions e.g. a single u
can parse a 4-digit year, a single M
can parse one/two-digit month, a single d
can parse one/two-digit day-of-month etc. e.g. LocalDate.parse("15/10/2024", DateTimeFormatter.ofPattern("d/M/u"))
. I recommend you go through DateTimeFormatter
documentation to learn more about it.
In the database the TimeStamp is stored like this
08-AUG-12 12.00.00.000000000 AM
I suggest you build a case-insensitive DateTimeFormatter
to deal with cases like AUG/Aug, AM/am etc. The demo below shows how to create such a DateTimeFormatter
.
Also, use an appropriate Locale
whenever the date-time string you are parsing has alphabets (e.g. AUG, AM etc.) as they are Locale
-sensitive. You may like to check Always specify a Locale
with a SimpleDateFormat
, and a DateTimeFormatter
for custom formats.
Demo:
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("dd-MMM-uu hh.mm.ss.SSSSSSSSS a")
.toFormatter(Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse("08-AUG-12 12.00.00.000000000 AM", dtf);
System.out.println(ldt);
}
}
Output:
2012-08-08T00:00
Note: As suggested by https://stackoverflow.com/users/5772882/anonymous, retrieving it as a LocalDateTime
from your database is even better. Given below is a sample code:
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE <some condition>");
while (rs.next()) {
// Assuming the column index of columnfoo is 1
LocalDateTime ldt = rs.getObject(1, LocalDateTime.class));
System.out.println(ldt);
}
rs.close();
st.close();
Check this answer and this answer to learn more about this option.
Learn more about the modern Date-Time API from Trail: Date Time.
Upvotes: 0
Reputation: 120858
Use LocalDateTime instead:
String input = "08-AUG-12 12.00.00 AM";
String pattern = "dd-MMM-yy hh.mm.ss aa";
LocalDateTime localDateTime = LocalDateTime.parse(input, DateTimeFormat.forPattern(pattern));
EDIT
As a matter of fact you can do it with DateTime also:
private static String parseDateTime(String input){
String pattern = "dd-MMM-yy hh.mm.ss aa";
DateTime dateTime = DateTime.parse(input, DateTimeFormat.forPattern(pattern));
return dateTime.toString("dd-MMM-yy hh:mm:ss aa");
}
Upvotes: 54
Reputation: 1638
Figured it out. To get the correct format, you have to call formatter.print(localDateTime object) and it worked.
Upvotes: 2