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.
Related
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.
I set Japanese date using Locale (e.g. 21 11月 2016) in my android app. But, I want to send that date into "dd-MM-yyyy" (e.g. 21-11-2016) format to my APIs.
When I try to do this I get below exception :
java.lang.IllegalArgumentException: Bad class: class java.lang.String
Below is my code :
public String convertDate(String date) {
System.out.println("......ORIGINAL DATE....... " + date); // ......ORIGINAL DATE....... 21 11月 2016
String myFormat = "dd-MM-yyyy"; //In which you need put here
SimpleDateFormat sdf = new SimpleDateFormat(myFormat, new Locale(getMyLocale())); //Japanese locale is set but tried english too
System.out.println("......CONVERTED DATE....... " + sdf.format(date)); //should be 21-11-2016 but getting above error
return sdf.format(new Date(date));
}
Moreover, for US/English Locale it works fine but for Japanese I am getting this error.
You need two formatters as below
String in = "2016年11月 21日"; // really a space here?
SimpleDateFormat sdf1 = new SimpleDateFormat ("yyyy年MM月 dd日");
Date d1 = sdf1.parse(in);
SimpleDateFormat sdf2 = new SimpleDateFormat ("dd-MM-yyyy");
System.out.println(sdf2.format(d1));
java.time
You are using the troublesome old legacy date-time classes supplanted by java.time classes.
Define a DateTimeFormatter object to match the pattern of your input strings and specify a Locale for Japan. Parse input string into a LocalDate object. Call LocalDate.parse.
Define a DateTimeFormatter object to match your desired output. Call LocalDate::format to generate a string you desire.
This has been documented many times already in StackOverflow. Please search to find example code and further discussion.
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 java.time.
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….
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!).
I have old code that uses new Date(dateString) to parse a date string. Compiling the code produces the deprecation warning Date(java.lang.String) in java.util.Date has been deprecated.
The javadoc unhelpfully advises me to use DateFormat.parse(), even though the DateFormat class does not have a static parse method.
Now, I know how to use SimpleDateFormat, but I want to make sure I'm getting the exact same behaviour of the deperecated Date constructor.
Here's my guess (I posted as community wiki so you can vote up if I'm right):
Date parsed;
try {
SimpleDateFormat format =
new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
parsed = format.parse(dateString);
}
catch(ParseException pe) {
throw new IllegalArgumentException(pe);
}
SimpleDateFormat is the way to go. Can I point out, however, that you may feel compelled to define one SimpleDateFormat instance and build Date objects using this. If you do, beware that SimpleDateFormat is not thread-safe and you may be exposing yourself to some potentially hard-to-debug issues!
I'd recommend taking this opportunity to look at Joda which is a much better thought-out (and thread-safe) API. It forms the basis of JSR-310, which is the new proposed Java Date API.
I understand this is a bit more work. However it's probably worthwhile given that you're having to refactor code at the moment.
If you take a look at source of the Date.parse(String s) method that Nicolas mentions, you'll see that it will be difficult or impossible to construct a date format that exactly reproduces the behavior.
If you just want to eliminate the warning, you could put #SuppressWarnings({“deprecation”}) outside the method calling the Date(String) constructor.
If you really want to ensure future access to this behavior with future JREs, you might be able to just extract the method from the JDK sources and put it into your own sources. This would require a careful read of the source code licenses and consideration of their application to your specific project, and might not be permissible at all.
DateFormat has static methods that return DateFormat instances. I don't know which one (if any) has the same behavior as Date(String s) but here you go:
DateFormat.getInstance()
DateFormat.getDateInstance()
DateFormat.getTimeInstance()
DateFormat.getDateTimeInstance()
Short answer (before further investigation) is: no, it is not equivalent. the Date(String toParse) constructor is equivalent to the parse method of the class Date (which is also deprecated)... And the javadoc of this method claims:
Note that this is slightly different from the interpretation of years less than 100 that is used in SimpleDateFormat.
If it is the only change, I guess you can go on this way.
To parse a date time string in ISO format you should use the DateFormat like this:
java.text.DateFormat.getDateInstance().parse(dt);
With SimpleDateFormat you need to know the format.
tl;dr
ZonedDateTime.format(
input ,
DateTimeFormatter.ofPattern(
"EEE MMM dd HH:mm:ss zzz uuuu" ,
Locale.ENGLISH
)
)
java.time
The terrible Date and DateFormat classes were supplanted years ago by the modern java.time classes with the adoption of JSR 310.
The constructor you reference is actually calls on the static method Date.parse. As that documentation explains, that method takes a variety of formats. There is single point for the same behavior in java.time. However, I would doubt your app is encountering all those various format syntaxes simultaneously.
I suggest you look at the specific formats used by your actual data. Then craft a collection of DateTimeFormatter objects to match. Note that unlike the legacy classes, the java.time classes are entirely thread-safe. So you can keep one set of formatters around for use repeatedly throughout your app and across threads.
For the formatting pattern shown in the accepted Answer, here is the equivalent in java.time using the DateTimeFormatter class. Note that you should explicitly state your desired/expected locale rather than rely implicitly on the JVM’s current default locale.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM dd HH:mm:ss zzz uuuu" , Locale.ENGLISH ) ;
ZonedDateTime zdt = ZonedDateTime.format( input , f ) ;
You should avoid using the legacy date-time classes such as java.util.Date wherever possible. But if you must have a Date to interoperate with old code not yet updated to java.time, you can convert. Look to new conversions methods added to the old classes.
The misnamed java.util.Date represents a moment in UTC. Its modern equivalent
is the java.time.Instant class. We can extract an Instant from our ZonedDateTime. Then convert to a Date.
Instant instant = zdt.toInstant() ; // Adjust from time zone to UTC.
java.util.Date d = Date.from( instant ) ; // Convert from modern class `Instant` to legacy class `Date`.
Going the other direction.
Instant instant = d.toInstant() ; // Convert from legacy class `Date` to modern class `Instant`.
ZonedDateTime zdt = instant.atZone( ZoneId.of( "Pacific/Auckland" ) ) ; // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone).
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
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.