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.
Related
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.
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());
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.
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.
I need to convert a timestamp string to java.util.Date. E.g.:
MMDDYYHHMMSS to MM-DD-YY HH-MM-SS
Where MM is month, DD is date, YY is year, HH is hours, MM is minutes and SS is seconds.
You can do it like this:
DateFormat format = new SimpleDateFormat("MMddyyHHmmss");
Date date = format.parse("022310141505");
but I would strongly recommend that you use Joda Time instead. It's a better date/time library by a long, long way. In particular, the formatters/parsers in Joda Time are thread-safe, so you can reuse them freely and statically; java.text.SimpleDateFormat isn't thread-safe, so you either need to create one per thread or serialize access to it with a synchronized block.
tl;dr
java.time.LocalDateTime.parse(
"012318123456" ,
DateTimeFormatter.ofPattern( "MMdduuHHmmss" )
).format(
DateTimeFormatter.ofPattern( "MM-dd-uu HH-mm-ss" )
)
01-23-18 12-34-56
java.time
The modern approach uses the java.time classes.
Define a formatting pattern to match your input string.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MMdduuHHmmss" ) ;
Your two-digit year will be interpreted as being 21st century ( 20xx ).
Parse as a LocalDateTime because your input string lacks any indicator of time zone or offset-from-UTC.
LocalDateTime ldt = LocalDateTime.parse( "012318123456" , f ) ;
ldt.toString(): 2018-01-23T12:34:56
Generate a string in your desired format.
DateTimeFormatter fOut = DateTimeFormatter.ofPattern( "MM-dd-uu HH-mm-ss" ) ;
String output = ldt.format( fOut );
01-23-18 12-34-56
ISO 8601
Both of your formats are terrible, for multiple reasons.
When serializing date-time values, use the standard ISO 8601 formats whenever possible. They are designed to be practical, easy to parse by machine, easy to read by humans across cultures.
For a date-time time such as yours, the T in the middle separates the date portion from the time-of-day portion.
2018-01-23T12:34:56
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
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, 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 a SimpleDateFormat with an appropriate format string (be careful to use the correct format letters, uppercase and lowercase have different meanings!).