Java-CSV Date using Csv parser - java

I have a CSV file I'm trying to import using java. File with date column and dates in different formats I'd like to parse dates suitable for myqsl.
My code as:
CSVFormat format = CSVFormat.RFC4180.withHeader().withDelimiter(',');
CSVParser parsernew =CSVParser(File, format)
List<CSVRecord> csvRecordList = parser.getRecords();
String cellvalue=csvRecordList.get(0);
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = dateFormat .parse(cellvalue);
I'm trying to parse date column value but got Exception
java.text.ParseException: Unparseable date:
date column values as likes
10/31/2014
12/13/2013
2001-02-04
7/27/2001
2001-02-04
5/15/2008
Is there any way to parse different date formats and date format changes run time time how to handle that..
in excel
Thanks!

Fix the source of data
Firstly, you should educate the publisher of this data about using only standard ISO 8601 formats when serializing date-time values as text. For a date-only without time-of-day and without time zone, that would be YYYY-MM-DD.
Attempt parsing each of the two known formats
Fortunately, your example data shows only two formats: the standard YYYY-MM-DD format, and M/D/YYYY.
So try parsing with a pair of formatters, one for each case. If both fail, throw an exception to alert you to the publisher’s unfortunate use of even more formats.
java.time
Use only java.time classes. Never use the terrible old date-time classes such as Date and DateFormat. Those legacy classes were supplanted years ago with the adoption of JSR 310 in Java 8 and later.
DateTimeFormatter
Define the pair of formatters. The standard one is already defined as a constant: DateTimeFormatter.ISO_LOCAL_DATE. Define the other.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "M/d/uuuu" ) ;
Get your input string in your code using the Apache Commons CSV library. But your code looks wrong in the Question. You need to add a loop for each of the CSVRecord objects in your list. Then extract each column from each row represented by that object.
CSVRecord record = = csvRecordList.get( i ) ; // Fetch nth object from list.
String cellvalue = csvRecordList.get( 0 ) ; // Extract each column/cell from each row/object. Must use annoying zero-based index counting.
Catch DateTimeParseException
Attempt to parse the input using each of the two formatters using LocalDate.parse. Catch the DateTimeParseException.
LocalDate ld = null;
if( Objects.isNull( ld ) ) {
try {
ld = LocalDate.parse( cellvalue , DateTimeFormatter.ISO_LOCAL_DATE ) ;
} catch ( DateTimeParseException e ) {
// Swallow this particular exception in this particular case.
}
}
if( Objects.isNull( ld ) ) {
try {
ld = LocalDate.parse( cellvalue , f ) ;
} catch ( DateTimeParseException e ) {
// Swallow this particular exception in this particular case.
}
}
if( Objects.isNull( ld ) ) {
// Yikes! Failing all parsing attempts above means we encountered an unexpected format.
// FIXME: Handle this error scenario.
}
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?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.

You can use SimpleFlatMapper to define different date formats.
As an example:
CsvParser.mapWith(CsvMapperFactory.newInstance()
.addColumnProperty(k -> k.getName().toLowerCase().contains("date"), new DateFormatProperty("dd/MM/yyyy"))
.addColumnProperty(k -> k.getName().toLowerCase().contains("date"), new DateFormatProperty("dd-MM-yyyy"))
.newMapper(Trade.class))
.stream(reader).collect(toList());

Related

Convert any incoming date format to standard format in Java

Is there any class in Java that could convert incoming dates , which would be in different formats into a standard format .I know SimpleDateFormat does convert date to specific formats, but I need a method that could actually convert all below dates in format which is YYYY-MM-DD_HH:MM:SS_inputstring:
inputs
20170112_125645
20170915 137546
09122017:135292
2014012014132390 -- milliseconds in here
output
YYYY-MM-DD_HH:MM:SS_inputstring
We are expecting input date values in multiple formats, which should be converted to YYYY-MM-DD_HH:MM:SS_inputstring
I know this is a very common question , but I couldn't find one specific to my scenario .
If you know all the possible incoming date formats, you could create a SimpleDateFormat instance for each of them. Then for every incoming date string you just run it through the list. If a format won't parse this string it will throw an exception, catch it and move on to the next format, rinse and repeat until you get to one that parses the string.
Using java.time
No magic way to decipher any random format. But in your case you have easy ways to identify each of the particular formats.
DateTimeFormatter f ;
if ( input.contains( "_" ) ) { // 20170112_125645
f = DateTimeFormatter.ofPattern( "uuuuMMdd'_'HH:mm:ss" );
} else if ( input.contains( " " ) ) { // 20170915 137546
f = DateTimeFormatter.ofPattern( "uuuuMMdd' 'HH:mm:ss" );
} else if ( input.contains( ":" ) ) { // 09122017:135292
f = DateTimeFormatter.ofPattern( "ddMMuuuu':'HH:mm:ss" );
} else if ( input.length() == 16 ) { // 2014012014132390
f = DateTimeFormatter.ofPattern( "uuuuMMddHHmmssSS" );
} else {
… // Handle error condition
System.out.println( "ERROR - Unexpected input: " + input ) ;
}
LocalDateTime ldt = LocalDateTime.parse( input , f );
Of course in real code being called many times often, I would cache those DateTimeFormatter instances rather than instantiate each time. Perhaps define an Enum if used in various other places in your code base.
Usually I recommend always specifying a Locale in the formatter rather than rely implicitly on JVM’s current default. But here I don't think the locale has any effects.
Avoid legacy date-time classes
You mentioned SimpleDateFormat. That class is one of the troublesome old date-time classes that should be avoided. Now legacy, supplanted by the java.time classes.
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
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.

Unexpected exception while parsing date

I am trying to parse the date according to the following code but getting exception. Below is the code -
public class DateTest {
public static void main(String args []) {
String start = "23-Jan-2017";
DateFormat dateFormatTripStartDate = new SimpleDateFormat("dd-MMM-yyyy hh:mm a");
try {
Date parsedDate = dateFormatTripStartDate.parse(start);
System.out.println(parsedDate);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Exception :
java.text.ParseException: Unparseable date: "23-Jan-2017"
at java.text.DateFormat.parse(DateFormat.java:357)
at DateTest.main(DateTest.java:18)
Kindly help me identify the problem. Thanks.
Remove the time part in your pattern:
DateFormat dateFormatTripStartDate = new SimpleDateFormat("dd-MMM-yyyy");
tl;dr
LocalDate.parse(
"23-Jan-2017" ,
DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US )
)
Using java.time
Other Answers are correct about formatting pattern mismatching input data. But both the Question and other Answers are outdated.
The modern way is with java.time classes that supplant the troublesome old date-time classes.
The LocalDate class represents a date-only value without time-of-day and without time zone.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US );
LocalDate ld = LocalDate.parse( "23-Jan-2017" , f );
ld.toString(): 2017-01-23
Specify the Locale as that determines the human language used to translate the name of the month. If omitted the JVM’s current default Locale is used implicitly. That default can be changed at any moment by any code in any thread of any app within the JVM, so do not rely upon it.
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.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
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, andfz more.
First of all, the answer from kamehl23 is correct. Your parsed string may not be missing any parst that are specified in format and thus you will need to modify your format to DateFormat dateFormatTripStartDate = new SimpleDateFormat("dd-MMM-yyyy"); However just to add few more interesting options: Remember that SimpleDateFormat is not thread safe and in general not recommended. Sensible pre Java 8 options are Apache FastDateFormat and joda-time package. Both have some problems but certainly by far better then SimpleDateFormat (Joda-time package is very popular). In Java 8 a new date and time hanling was introduced with package java.time.format It takes time to adjust to it but it works wonderful and resolves many problems that existed in that area. See class DateTimeFormatter.And finally, I once had to write a utility that can take a String in any format and attempt to parse it to Date if possible. I wrote an article that describes how I implemented that Utility. I wrote it in Java 8, but the idea could be implemented in any version. See Java 8 java.time package: parsing any string to date
You are using pattern "dd-MMM-yyyy hh:mm a". But in actual "hh:mm a" part is not present in the "23-Jan-2017" value. Because of this parse function is not able to parse the String date.
So change your pattern to "dd-MMM-yyyy" which matches your date string. This will remove the exception you are getting.

Java parse date from TextField with a different format [duplicate]

This question already has answers here:
Parsing String into mysql Date [duplicate]
(4 answers)
Closed 5 years ago.
I'm facing some problems in Eclipse with dates. I'm showing a date in a TextField with the format
dd/MM/yyyy
and I need to get the text from this textfield and parse it as a date to insert it in my database into a column of type DATE I'm using MySQL and it accepts dates as
yyyy-MM-dd
I tried really many options, both with LocalDate or the older Date, but didn't find a solution. Can someone please help? Thank you!
Prior Java 8 approach
Firstly, after retrieving your string from your TextField, you should parse it to java.util.Date:
String text = textField.getText();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
java.util.Date textFieldAsDate = null;
try {
textFieldAsDate = sdf.parse(text);
} catch (ParseException pe) {
// deal with ParseException
}
Afterwards, you can convert your java.util.Date into a java.sql.Date, to store it into your MySQL database, like this:
sdf = new SimpleDateFormat("yyyy-MM-dd");
java.sql.Date date = java.sql.Date.valueOf(sdf.format(textFieldAsDate));
Java 8 approach
As mentioned by #BasilBourque, the Java date and time mechanism was provided by java.util.Date, java.util.Calendar, and java.util.TimeZone classes which are now legacy.
Therefore, in order to accomplish using Java 8 what was previously mentioned, one can do the following:
String text = textField.getText();
java.time.format.DateTimeFormatter formatter = java.time.format.DateTimeFormatter.ofPattern("dd/MM/yyyy");
java.time.LocalDate textFieldAsDate = java.time.LocalDate.parse(text, formatter);
Afterwards, in order to convert the LocalDate into a java.sql.Date, to store it into your MySQL database, it's possible to do the following:
java.sql.Date sqlDate = java.sql.Date.valueOf(textFieldAsDate);
You want to use the SimpleDateFormat class
Once you have extracted it from the TextField, you can use this:
String extractedDate = "dd/MM/yyyy" // Whatever date you've extracted
Date date = new SimpleDateFormat("dd/MM/yyyy").parse(extractedDate);
String correctDate = new SimpleDateFormat("yyyy-MM-dd").format(date);
System.out.println(correctDate); // "yyyy-MM-dd" for whatever date was extracted
Try this:
SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd");
Date date = df.parse("2016-03-05");
java.time
The other Answers are correct but use outdated classes. The old date-time classes such as java.util.Date/.Calendar have proven to be poorly designed, confusing, and troublesome. Avoid them. They have been supplanted by the java.time framework built into Java 8 and later.
Define a pattern by which to parse your input string.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd/MM/yyyy" );
Parse the input string as a LocalDate object, representing a date-only value without time-of-day nor time zone.
LocalDate localDate = LocalDate.parse( "23/01/2016" , formatter );
Someday the JDBC drivers will be updated to work directly with the java.time types. But until then we must convert to the java.sql types for transferring data to/from the database.
java.sql.Date sqlDate = java.sql.Date.valueOf( localDate );
Then use a PreparedStatement, calling setDate and passing your sqlDate to write the value into the database.
To retrieve from the database, call getDate. Immediately convert to java.time by calling java.sql.Date::toLocalDate. Minimize your use of the java.sql types. Do your business logic in java.time.
If your JDBC driver complies with JDBC 4.2 and later, you can skip the java.sql types and use the java.time types directly.
PreparedStatement::setObjectmyPrepStmt.setObject( … , myLocalDate )
ResultSet::getObjectLocalDate ld = myResultSet.getObject( … , LocalDate.class );
This Question is really a duplicate. Search Stack Overflow for many more examples.
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
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.

Convert date or calendar type into string format

So, basically I am trying to achieve the following format in a String:
2012-06-17T08:00:00.000+01:00
I get the original date in a string format which I then parse into different formats.
When I use SimpleDateFormat with the format as (yyyy-MM-dd'T'HH:mm:ss.sssZ), I get the following output:
2013-06-17T07:00:00.000+0530
Here +0530 should be +05:30
When I set the above date into a Calendar type and then convert it to a string I get the following format:
2013-06-17T07:00:00+05:30
Here I don't get the .000 after the seconds.
Any ideas how this can be achieved, without using JodaTime. Need manipulations in Date, String and Calendar type only
Firstly to get the extra : use XXX in your formatter like so and use Uppercase S to get the milliseconds
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
UPDATE: Above doesn't work on 1.6
Yo could try the following however
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
{
public StringBuffer format(Date date, StringBuffer toAppendTo, java.text.FieldPosition pos)
{
StringBuffer toFix = super.format(date, toAppendTo, pos);
return toFix.insert(toFix.length()-2, ':');
};
See this post for more
SimpleDateFormat pattern
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
tl;dr
OffsetDateTime.parse( "2012-06-17T08:00:00.000+01:00" ) // Parse string in standard ISO 8601 format to an object.
.format( // Generate a String representing the value of that `OffsetDateTime` object.
DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSXXXXX" ) // Specify a formatting pattern to force the seconds and fractional second even if zero.
) // Return a `String` object.
2012-06-17T08:00:00.000+01:00
java.time
The modern approach uses the java.time classes rather than the troublesome old legacy date-time classes. Avoid Date, Calendar, and SimpleDateFormat.
ISO 8601
Your desired format happens to be standard ISO 8601 format. The java.time classes use the standard format by default when parsing/generating strings. So no need to specify a formatting pattern.
OffsetDateTime
Your input string includes an offset-from-offset but not a time zone. So we parse as a OffsetDateTime object.
OffsetDateTime odt = OffsetDateTime.parse( "2012-06-17T08:00:00.000+01:00" ) ;
To generate a string in the same standard ISO 8601 format, simply call toString. By default, the least significant parts are omitted if zero. So no seconds or fractional second appear using your example data.
String output = odt.toString() ;
2012-06-17T08:00+01:00
If you want to force the seconds and fractional second even when zero, specify a formatting pattern.
OffsetDateTime odt = OffsetDateTime.parse( "2012-06-17T08:00:00.000+01:00" );
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSXXXXX" );
String output = odt.format( f );
2012-06-17T08:00:00.000+01:00
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?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.

puzzled with how to convert ddmmyy string to dd-MMM-yy date

I am puzzled with how to convert ddmmyy string to dd-MMM-yy date in java code.Example--
041110 as a string will be 04-NOV-10 as date.
Any suggestion will be greatly appreciated.
Thanks.
Using SimpleDateFormat
Something like
DateFormat input = new SimpleDateFormat("ddMMyy");
DateFormat output = new SimpleDateFormat("dd-MMM-yy");
String result = output.format(input.parse(inputString));
Why not use SimpleDateFormat?
tl;dr
The other Answers using SimpleDateFormat are outmoded now. Use DateTimeFormatter instead.
LocalDate.parse(
"041110" ,
DateTimeFormatter.ofPattern( "ddMMuu" , Locale.US )
)
.format(
DateTimeFormatter.ofPattern( "dd-MMM-uu" , Locale.US )
)
04-Nov-10
java.time
The modern approach uses the java.time classes.
String input = "041110" ;
Define a formatting pattern to match your desired output. Note that we specify the Locale to determine the human language and cultural norms in generating the name of the month.
DateTimeFormatter fParse = DateTimeFormatter.ofPattern( "ddMMuu" , Locale.US ) ;
Parse the input to get a LocalDate object. The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate ld = LocalDate.parse( input , fParse ) ;
Generate a String in standard ISO 8601 format.
ld.toString(): 2010-11-04
We have a LocalDate object in hand. We want to generate a String to represent that same value in another format.
DateTimeFormatter fGenerate = DateTimeFormatter.ofPattern( "dd-MMM-uu" , Locale.US ) ;
Generate the String object.
String output = ld.format( fGenerate ) ;
04-Nov-10
Tips
Generally best to let java.time automatically localize rather than hard-code a formatting pattern as seen here. Instead, use DateTimeFormatter.ofLocalized… methods.
Avoid the legacy date-time classes such as SimpleDateFormat. They are an awful mess of poor design. They were supplanted years ago by the java.time classes for many good reasons.
When exchanging data, never use custom formats such as that seen in the Question. Use the standard formats. They are designed to be unambiguous, easy to read by humans, and easy to parse by machine.
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?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.
use SimpleDateFormat("dd-MMM-yy")
formatter = new SimpleDateFormat("dd-MMM-yy");
String s = formatter.format(date);
Use SimpleDateFormat or have a map that translates numbers 1-12 to month name abbreviations.

Categories

Resources