Reputation: 799
I have a CSV that contains timestamps in the following formats:
yyyy-MM-dd HH:mm:ssX
yyyy-MM-dd HH:mm:ss.SX
yyyy-MM-dd HH:mm:ss.SSX
yyyy-MM-dd HH:mm:ss.SSSX
yyyy-MM-dd HH:mm:ss.SSSSX
yyyy-MM-dd HH:mm:ss.SSSSSX
yyyy-MM-dd HH:mm:ss.SSSSSSX
How can I parse a string that could contain any one of the above formats?
The following code can parse the timestamp when 3-6 nanoseconds are present, but fails when the nano seconds aren't present or are less than 3:
String time = "2018-11-02 11:39:03.0438-04";
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSX");
Date date = sdf.parse(time);
System.out.println("Date and Time: " + date.getTime());
I currently have a method that iterates from 0-6 and generates a string with a number of "S" equal to the value of the iterated variable. The method attempts to parse the string within a try/catch until the string is successfully parsed. For example, the string 2018-11-02 11:39:03.0438-04
will attempt to be parsed five times before being successful.
The CSV is an export of a PostgreSQL table that has columns with type TIMESTAMP WITH TIME ZONE and appears to cut off trailing "0" nanosecond places.
I'm using Java 8 and am open to any external libraries (Joda?).
Upvotes: 1
Views: 2775
Reputation: 22977
You'd better use Java Time API1, from the package java.time
.
Date
, SimpleDateFormatter
and Calendar
classes are flawed and obsolete.
The DateTimeFormatter
class provides numerous options, so you can configure all you need. Note that by using the method appendFraction
, the nanos are right-padded.
String[] dateStrs = {
"2018-11-02 11:39:03.4-04",
"2018-11-02 11:45:22.71-04",
"2018-11-03 14:59:17.503-04"
};
DateTimeFormatter f = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd HH:mm:ss.")
.appendFraction(ChronoField.NANO_OF_SECOND, 1, 9, false)
.appendPattern("X")
.toFormatter();
// Single item:
LocalDateTime date = LocalDateTime.parse("2018-11-02 11:39:03.7356562-04", f);
// Multiple items:
List<LocalDateTime> dates = Arrays.asList(dateStrs).stream()
.map(t -> LocalDateTime.parse(t, f))
.collect(Collectors.toList());
1 Java 8 new Date and Time API is heavily influenced by Joda Time. In fact the main author is Stephen Colebourne, the author of Joda Time.
Upvotes: 6
Reputation: 3131
I'm not sure but something like this seems to work for me:
String time = "2018-11-02 11:39:03.0438-04";
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSX");
Date date = sdf.parse(time);
System.out.println("Date and Time: " + date.getTime());
In general, you want to you the longest format possible, with 6x S
in this case.
Upvotes: 0
Reputation: 76436
The first 19 characters are identical.
Also, you have different length
s in the different cases. You can use a switch
to test the length
of the String
and handle the separate case
s for the different possible values.
Upvotes: 0