If input is 01-01-2015 it should change to 2015-01-01.
If input is 2015-01-01 it should change to 01-01-2015.
I used SimpleDateFormat but didn't get the correct output:
//Class to change date dd-MM-yyyy to yyyy-MM-dd and vice versa
public class ChangeDate {
static SimpleDateFormat formatY = new SimpleDateFormat("yyyy-MM-dd");
static SimpleDateFormat formatD = new SimpleDateFormat("dd-MM-yyyy");
//This function change dd-MM-yyyy to yyyy-MM-dd
public static String changeDtoY(String date) {
try {
return formatY.format(formatD.parse(date));
}
catch(Exception e) {
return null;
}
}
//This function change yyyy-MM-dd to dd-MM-yyyy
public static String changeYtoD(String date) {
try {
return formatD.format(formatY.parse(date));
}
catch(Exception e) {
return null;
}
}
}
I want some condition that automatically detects the date's pattern and change to the other format.
There are 2 options:
Try to check with regular expression sth. like:
if (dateString.matches("\\d{4}-\\d{2}-\\d{2}")) {
...
}
Try to convert to first pattern, if it throws exception, try to convert to another pattern (but it is bad practice to do so)
Regex Is Overkill
For date-time work, no need to bother with regex.
Simply attempt a parse with one format, trapping for the expected exception. If the exception is indeed thrown, attempt a parse with the other format. If an exception is thrown, then you know the input is unexpectedly in neither format.
java.time
You are using old troublesome date-time classes now supplanted by the java.time framework built into Java 8 and later. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Oracle Tutorial.
LocalDate
The new classes include one, LocalDate, for date-only values without time-of-day. Just what you need.
Formatters
Your first format may be the standard ISO 8601 format, YYYY-MM-DD. This format is used by default in java.time.
If this first parse attempt fails because the input does not match ISO 8601 format, a DateTimeParseException is thrown.
LocalDate localDate = null;
try {
localDate = LocalDate.parse( input ); // ISO 8601 formatter used implicitly.
} catch ( DateTimeParseException e ) {
// Exception means the input is not in ISO 8601 format.
}
The other format must be specified by a coded pattern similar to what you are doing with SimpleDateFormat. So if we catch the exception from the first attempt, make a second parse attempt.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MM-dd-yyyy" );
LocalDate localDate = null;
try {
localDate = LocalDate.parse( input );
} catch ( DateTimeParseException e ) {
// Exception means the input is not in ISO 8601 format.
// Try the other expected format.
try {
localDate = LocalDate.parse( input , formatter );
} catch ( DateTimeParseException e ) {
// FIXME: Unexpected input fit neither of our expected patterns.
}
}
Read up about Pattern, Matcher, and Regular Expressions.
Java code (based on OP):
if (date.matches("\\d{2}-\\d{2}-\\d{4}")){
//convert D format to Y format...
} else if(date.matches("\\d{4}-\\d{2}-\\d{2}")){
//convert Y to D...
} else {
throw new IllegalArgumentException("Received date format is not recognized.");
}
Note: This Match-Pattern can be improved with capture groups.
Ex: "\\d{4}(-\\d{2}){2}" or "(-?\\d{2}){2}\\d{4}"
See: https://docs.oracle.com/javase/tutorial/displayCode.html?code=https://docs.oracle.com/javase/tutorial/datetime/iso/examples/StringConverter.java
Non-ISO Date Conversion
https://docs.oracle.com/javase/tutorial/datetime/iso/nonIso.html
Adding a new Chronology that identifies the ISO Date either way is another compatible (breakproof) means to input the Date Data and store it in correct Structures (where other Functions can easily operate upon the Data). See: https://docs.oracle.com/javase/8/docs/api/java/time/chrono/Chronology.html
The 'regex method' can be broken by erroneous input and leaves no means to return a standard error in response to whatever was input (to get a standard identical result everywhere).
See the answer provided by User "Tardate" in this Thread: How to sanity check a date in java .
You want bulletproof input and to store it in correctly identified Structures in order to easily manipulate it with other Functions.
Just compare the position of first '-' character in date string.
Related
This question already has answers here:
SimpleDateFormat parsing date with 'Z' literal [duplicate]
(12 answers)
Closed 4 years ago.
I am using the below code to format millisecond resolution date strings. It works for 2018-09-14T13:05:21.329Z but not 2018-09-14T13:05:21.3Z. Can anybody suggest the reason and how to correct it?
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
SimpleDateFormat sdfDestination = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date parsedDate = formatter.parse(date);
String destDate = sdfDestination.format(parsedDate);
return destDate;
} catch (java.text.ParseException parseException) {
logger.error("Parse Exception occured while converting publication time to date "
+ "format 'yyyy-MM-dd HH:mm:ss'", parseException);
}
I get below exception:
java.text.ParseException: Unparseable date: "2018-09-14T13:05:21.3Z"
at java.text.DateFormat.parse(Unknown Source) ~[na:1.8.0_181]
at com.noordpool.api.implementation.utility.Utility.parseDate(Utility.java:136) [classes/:na]
at com.noordpool.api.implementation.utility.Utility.parseMessage(Utility.java:77) [classes/:na]
Your only problem is that you are using a wrong pattern for SimpleDateFormat, you need to change:
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
To:
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Because the Z used in the date string means "zero hour offset" so you just need to pass it as 'Z' in your pattern.
This is a working demo with the right pattern.
Edit:
And to make things work with different Locales and Timezones, you need to use the appropriate Locale when you are creating the SimpleDateFormat instance, this is how should be the code:
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
The only possible issue I can see is that you're passing in milliseconds incorrectly and the program doesn't know what to do about it.
So the last part of the formatter indicates with milliseconds and a timezone as .SSSX
But how does it evaluate 3Z for the input into this? I mean, do you say it's 300 timezone Z, or say it's 003 timezone Z, or worse, try and parse it as 3Z, which hopefully you see that you cannot turn '3Z' into a number.
To remedy this, I'd validate your input 'date' and ensure the milliseconds part is always 3 digits long, this removes the ambiguity and the program always knows that you mean '300 milliseconds, timezone Z'.
There is a problem in java 8 where the number of characters that you specified with the formatter should be an exact match (which is not specified in the documentation).
You can use three different Formatters and use nested exception as follows:
DateFormat format1 = new SimpleDateFormat("y-M-d'T'H:m:s.SX");
DateFormat format2 = new SimpleDateFormat("y-M-d'T'H:m:s.SSX");
DateFormat format3 = new SimpleDateFormat("y-M-d'T'H:m:s.SSSX");
Date parsedDate;
try {
// Parsing for the case - 2018-09-14T13:05:21.3Z
parsedDate = format1.parse(date);
} catch (ParseException e1) {
try {
// Parsing for the case - 2018-09-14T13:05:21.32Z
parsedDate = format2.parse(date);
} catch (ParseException e2) {
try {
// Parsing for the case - 2018-09-14T13:05:21.329Z
parsedDate = format3.parse(date);
} catch (ParseException e2) {
//The input date format is wrong
logger.error("Wrong format for date - " + date);
}
}
}
java.time
DateTimeFormatter dtfDestination
= DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
String date = "2018-09-14T13:05:21.3Z";
String destDate = Instant.parse(date)
.atZone(ZoneId.of("Indian/Comoro"))
.format(dtfDestination);
System.out.println(destDate);
Output from this snippet is:
2018-09-14 16:05:21
Please substitute your correct time zone if it didn’t happen to be Indian/Comoro, since correct output depends on using the correct time zone. If you want to use your JVM’s default time zone, specify ZoneId.systemDefault(), but be aware that the default can be changed at any time from other parts of your program or other programs running in the same JVM.
I am exploiting the fact that your string, "2018-09-14T13:05:21.3Z", is in ISO 8601 format, the format that the classes of java.time parse as their default, that is, without any explicit formatter. Instant.parse accepts anything from 0 through 9 decimals on the seconds, so there is no problem giving it a string with just 1 decimal, as you did. In comparison there is no way that an old-fashioned SimpleDateFormat can parse 1 decimal on the seconds with full precision since it takes pattern letter (uppercase) S to mean milliseconds, so .3 will be parsed as 3 milliseconds, not 3 tenths of a second, as it means.
Jahnavi Paliwal has already correctly diagnosed and explained the reason for the exception you got.
The date-time classes that you used, DateFormat, SimpleDateFormat and Date, are all long outdated and SimpleDateFormat in particular is notoriously troublesome. Since you seem to be using Java 8 (and even if you didn’t), I suggest you avoid those classes completely and use java.time instead.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Wikipedia article: ISO 8601
This question already has answers here:
Java Date Error
(8 answers)
Closed 4 years ago.
I want to convert String values in the format of mm/dd/yy to YYYY-MM-DD Date. how to do this conversion?
The input parameter is: 03/01/18
Code to convert String to Date is given below
public static Date stringToDateLinen(String dateVlaue) {
Date date = null;
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
try {
date = formatter.parse(dateVlaue);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
When tried to convert using this method it shows the following error
java.text.ParseException: Unparseable date: "03/01/18"
As you say the input is in a different format, first convert the String to a valid Date object. Once you have the Date object you can format it into different types , as you want, check.
To Convert as Date,
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yy");
date = formatter.parse(dateVlaue);
To Print it out in the other format,
SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd");
dateString = formatter1.format(date)
You are writing it the wrong way. In fact, for the date you want to convert, you need to write
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yy");
The format you are passing to SimpleDateFormat is ("yyyy-MM-dd") which expects date to be in form 2013-03-01 and hence the error.
You need to supply the correct format that you are passing your input as something like below
public static Date stringToDateLinen(String dateVlaue) {
Date date = null;
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yy");
try {
date = formatter.parse(dateVlaue);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
The solution for the above problem
Convert the String date value in the Format of "dd/mm/yy" to Date.
By using the converted Date can able to frame the required date format.
The method has given below
public static String stringToDateLinen(String dateVlaue) {
Date date = null;
SimpleDateFormat formatter = new SimpleDateFormat("dd/mm/yy");
String dateString = null;
try {
// convert to Date Format From "dd/mm/yy" to Date
date = formatter.parse(dateVlaue);
// from the Converted date to the required format eg : "yyyy-MM-dd"
SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd");
dateString = formatter1.format(date);
} catch (ParseException e) {
e.printStackTrace();
}
return dateString;
}
EDIT: Your question said “String values in the format of mm/dd/yy”, but I understand from your comments that you meant “my input format is dd/mm/yy as string”, so I have changed the format pattern string in the below code accordingly. Otherwise the code is the same in both cases.
public static Optional<LocalDate> stringToDateLinen(String dateValue) {
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/yy");
try {
return Optional.of(LocalDate.parse(dateValue, dateFormatter));
} catch (DateTimeParseException dtpe) {
return Optional.empty();
}
}
Try it:
stringToDateLinen("03/01/18")
.ifPresentOrElse(System.out::println,
() -> System.out.println("Could not parse"));
Output:
2018-01-03
I recommend you stay away from SimpleDateFormat. It is long outdated and notoriously troublesome too. And Date is just as outdated. Instead use LocalDate and DateTimeFormatter from java.time, the modern Java date and time API. It is so much nicer to work with. A LocalDate is a date without time of day, so this suites your requirements much more nicely than a Date, which despite its name is a point in time. LocalDate.toString() produces exactly the format you said you desired (though the LocalDate doesn’t have a format in it).
My method interprets your 2-digit year as 2000-based, that is, from 2000 through 2099. Please think twice before deciding that this is what you want.
What would you want to happen if the string cannot be parsed into a valid date? I’m afraid that returning null is a NullPointerException waiting to happen and a subsequent debugging session to track down the root cause. You may consider letting the DateTimeParseException be thrown out of your method (just declare that in Javadoc) so the root cause is in the stack trace. Or even throw an AssertionError if the situation is not supposed to happen. In my code I am returning an Optional, which clearly signals to the caller that there may not be a result, which (I hope) prevents any NullPointerException. In the code calling the method I am using the ifPresentOrElse method introduced in Java 9. If not using Java 9 yet, use ifPresent and/or read more about using Optional elsewhere.
What went wrong in your code?
The other answers are correct: Your format pattern string used for parsing needs to match the input (not your output). The ParseException was thrown because the format pattern contained hyphens and the input slashes. It was good that you got the exception because another problem is that the order of year, month and day doesn’t match, neither does the number of digits in the year.
Link
Oracle tutorial: Date Time explaining how to use java.time.
I will be direct with my question. I am wondering why I can't parse a fromat MMM-dd-yyyy into yyyy-MM-dd (java.sql.Date format)? Any suggestion on how I am going to convert a String into a format of (yyyy-MM-dd)?
Here is the code:
public DeadlineAction(String deadline){
putValue(NAME, deadline);
deadLine = deadline;
SimpleDateFormat formatter = new SimpleDateFormat("yyyy MM dd");
try {
finalDate = (Date) formatter.parse(deadLine);
}catch(ParseException e) {
JOptionPane.showMessageDialog(null, e.getMessage(),"Error",JOptionPane.ERROR_MESSAGE);
}
}
Thank you
Basically, you can't parse a String in the format of MMM-dd-yyyy using the format of yyyy MM dd, it just doesn't make sense, you need one formatter to parse the value and another to format itm for example
SimpleDateFormat to = new SimpleDateFormat("yyyy MM dd");
SimpleDateFormat from = new SimpleDateFormat("MMM-dd-yyyy");
Date date = from.parse(deadLine);
String result = to.format(date)
The question that needs to be asked is, why you would bother. If your intention is to put this value into the database, you should be creating an instance of java.sql.Date (from the java.util.Date) and using PreparedStatement#setDate to apply it to your query, then letting the JDBC driver deal with it
The answer by MadProgrammer is correct. You must define a formatting pattern to fit the format of your input data string.
You could avoid the problem in the first place by using the java.time framework.
java.time
The java.time framework is built into Java 8 and later (also back-ported to Java 6 & 7 and to Android). These classes supplant the old troublesome legacy date-time classes (java.util.Date/.Calendar).
ISO 8601
Your input strings are apparent is standard ISO 8601 format, YYYY-MM-DD such as 2016-01-23.
The java.time classes use ISO 8601 formats by default when parsing/generating strings that represent date-time values. So no need to specify a formatting pattern.
Parsing string
For a date-only value without time-of-day and without time zone, use LocalDate class.
LocalDate localDate = LocalDate.parse( "2016-01-23" );
Generating string
To generate a string representing that LocalDate object’s value, just call toString to get a string in ISO 8601 format.
String output = localDate.toString(); // 2016-01-23
For other formats, use the java.time.format package. Usually best to let java.time automatically localize to the user’s human language and cultural norms defined by a Locale.
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM );
Locale locale = Locale.CANADA_FRENCH;
formatter = formatter.withLocale( locale );
String output = localDate.format( formatter );
Or you can specify your own particular pattern. Note that you should still specify a Locale to determine aspects such as the name-of-month or name-of-day. Here is a demo of the pattern that seems to be asked in the Question (not sure as Question is unclear).
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MMM-dd-yyyy" );
Locale locale = Locale.US;
formatter = formatter.withLocale( locale );
String output = localDate.format( formatter );
Try something like:
try {
final String deadLine = "Oct-12-2006";
SimpleDateFormat formatter = new SimpleDateFormat("MMM-dd-yyyy");//define formatter for yout date time
Date finalDate = formatter.parse(deadLine);//parse your string as Date
SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd");// define your desired format
System.out.println(formatter2.format(finalDate));//format the string to your desired date format
} catch (Exception e) {
//handle
}
Your example is not unparseable. I removed the dashes from MMM-dd-yyyy to MMM dd yyyy. You can put them back if needed. I also removed the any extra code to make the solution clear.
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public DeadlineAction(String deadline){
//if deadline has format similar to "December 19 2011"
try {
finalDate = new java.sql.Date(
((java.util.Date) new SimpleDateFormat("MMM dd yyyy").parse(deadline)).getTime());
}catch(ParseException e) {
//Your exception code
e.printStackTrace();
}
}
This works for almost every conversion to sqlDate. Just change SimpleDateFormat("MMM dd yyyy") to what you need it to be.
Example: new SimpleDateFormat("MMM-yyyy-dd").parse("NOVEMBER-2012-30")
I am reading an excel value that is it is of date which is of string type and i am converting it in date type to store the date in format of dd/MM/YYYY so below is the way i am doing it
private static final SimpleDateFormat outputDate = new SimpleDateFormat("dd/MM/yyyy");
String dealDateString = cell.getStringCellValue(); // inside this deal date is stored as 05/07/13
if (dealDateString != null) {
java.util.Date dealDate = convertStringToDate(dealDateString);
String dd = outputDate.format(dealDate); // ----> now the date is stored inside dd string as DD/MM/YYYY as 05/07/2013
DateFormat format = new SimpleDateFormat("dd/MM/yyyy", Locale.UK);
java.util.Date date = format.parse(dd); //--> but inside date object the year is stored as 13 that is year is stored as YY
}
below is the custom method i have designed that will take string and convert it into date object
public java.util.Date convertStringToDate(String stringValue) {
String[] formatStrings = { "dd/MM/yyyy", "dd-MMM-yyyy" ,"dd/MM/YY" , "dd-MM-YY"};
for (String formatString : formatStrings) {
try {
return new SimpleDateFormat(formatString).parse(stringValue);
} catch (ParseException e) {
logger.warn("##$$$$$### Error in invoice inside convertStringToDate method : ##$$$$$$#### "
+ ErrorUtility.getStackTraceForException(e));
}
}
return null;
}
now the date is converted into java date object but the year is deducted lets say if the year is 2014 then
year is stored as 14 , please advise how can i store the year as 2014 the main concern is that year is stored as two digits only i want to store it as YYYY
folks please advise
Try to write this line:
String[] formatStrings = { "dd/MM/yyyy", "dd-MMM-yyyy" ,"dd/MM/YY" , "dd-MM-YY"};
Like this:
String[] formatStrings = { "dd/MM/yyyy", "dd-MMM-yyyy" ,"dd/MM/yy" , "dd-MM-yy"};
The issue is the format.....
When you use "dd/MM/yyyy" as fomat, 05/07/13 is traeted as 05/07/0013 and not 05/07/2013 .
Reference from Java doc
For parsing with the abbreviated year pattern ("y" or "yy"), SimpleDateFormat must interpret the abbreviated year relative to some century. It does this by adjusting dates to be within 80 years before and 20 years after the time the SimpleDateFormat instance is created. For example, using a pattern of "MM/dd/yy" and a SimpleDateFormat instance created on Jan 1, 1997, the string "01/11/12" would be interpreted as Jan 11, 2012 while the string "05/04/64" would be interpreted as May 4, 1964. During parsing, only strings consisting of exactly two digits, as defined by Character.isDigit(char), will be parsed into the default century. Any other numeric string, such as a one digit string, a three or more digit string, or a two digit string that isn't all digits (for example, "-1"), is interpreted literally. So "01/02/3" or "01/02/003" are parsed, using the same pattern, as Jan 2, 3 AD. Likewise, "01/02/-3" is parsed as Jan 2, 4 BC.
Use
dd/MM/yy as format instead of dd/MM/yyyy.It will solve your issue.
String[] formatStrings = { "dd/MM/yy", "dd-MMM-yy" ,"dd/MM/yy" , "dd-MM-yy"};
Incorrect Parsing Pattern
The Answer by Abdelhak is correct: You are defining incorrect formatting pattern. The uppercase Y has a different meaning than lowercase y.
java.time
You are using the old date-time classes from the early years of Java. These classes have proven to be troublesome, flawed in design and implementation. Avoid them (java.util.Date/.Calendar & java.text.SimpleTextFormat).
Instead use the java.time framework built into Java 8 and later.
The java.time classes include LocalDate to represent a date-only value with no time-of-day.
// If used repeatedly many times, keep this List around for re-use rather instantiating over and over.
List<DateTimeFormatter> formatters = new ArrayList<>(4);
formatters.add( DateTimeFormatter.ofPattern("dd/MM/yy") );
formatters.add( DateTimeFormatter.ofPattern("dd-MM-yy") );
formatters.add( DateTimeFormatter.ofPattern("dd/MM/yyyy") );
formatters.add( DateTimeFormatter.ofPattern("dd-MM-yyyy") );
LocalDate localDate = null; // Using null as a flag for success/failure.
for( DateTimeFormatter formatter : formatters ) {
try {
localDate = LocalDate.parse( input , formatter );
} catch ( DateTimeParseException e ) {
// Ignore this exception, as we expect some.
}
}
if( null == localDate ) {
// … handle failure to parse. Must be unexpected input.
} else {
// … handle success. You now have a LocalDate object.
String output = localDate.toString(); // Generates a String in ISO 8601 format.
String outputInFormatNotRecommended = localDate.format( formatters.get( 0 ) );
}
If your goal is to serialize the date value as a String, I strongly suggest you use the standard ISO 8601 format (YYYY-MM-DD). This format is easily recognizable by most any culture, is easy to read, and sorts alphabetically as chronologically.
I am parsing date strings from user input with MM-dd-yyyy HH:mm:ss format, and I found 12-20-2012 10:10:10 abcdexxxx could be pasred as well. How can this happen? Here is my code:
SimpleDateFormat df = new SimpleDateFormat( "MM-dd-yyyy HH:mm:ss" );
String currColValue = "12-20-2012 10:10:10 abcdexxxx";
try{
d=df.parse( currColValue );
}catch( ParseException e ){
System.out.println("Error parsing date: "+e.getMessage());
}
But there is no exception, the String value is parsed to be a Date. Why?
Per the Javadoc of the parse method:
Parses text from the beginning of the given string to produce a date. The method may not use the entire text of the given string.
(emphases mine).
Contrary to the implication of comments above, this has nothing to do with lenient parsing; rather, it's just that this method is not intended to consume the whole string. If you wish to validate that it consumed the whole string, I suppose you could set up a ParsePosition object and use the two-arg overload, and then examine the ParsePosition afterward to see if it parsed to the end of the string.
java.time
I should like to contribute the modern answer. This question was asked just the month before java.time, the modern Java date and time API, came out, which we all should be using now.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm:ss");
String currColValue = "12-20-2012 10:10:10 abcdexxxx";
try {
LocalDateTime ldt = LocalDateTime.parse(currColValue, formatter);
// Do something with ldt
} catch (DateTimeParseException e) {
System.out.println("Error parsing date and time: " + e.getMessage());
}
Output:
Error parsing date and time: Text '12-20-2012 10:10:10 abcdexxxx' could not be parsed, unparsed text found at index 19
Contrary to the old SimpleDateFormat class the parse methods of the modern classes do insist on parsing the entire string (there is a way to parse only part of the string if that is what you require). Also please note the precision and clarity of the exception message. By the way, SimpleDateFormat is not only long outdated, it is also notoriously troublesome. You found just one of many surprising problems it has. I recommend that you no longer use SimpleDateFormat and Date.
Link: Oracle tutorial: Date Time explaining how to use java.time.
Check SimpleDateFormat.parse(String) doc. It clearly says it.
Parses text from the beginning of the given string to produce a date. The method may not use the entire text of the given string.
http://docs.oracle.com/javase/7/docs/api/java/text/DateFormat.html#parse(java.lang.String)
I want to contibute to the above correct answers with examples, using the method overload
public Date parse(String text, ParsePosition pos);
To parse the exact whole string just create a new ParsePosition object (with index 0, indicating that parse needs to start from begin), pass it to the method, and inspect its index property after parse.
Index is where the parse did end. If matches with string length then the string matches exactly form start to end.
Here is a unit test demonstrating it
public class DateParseUnitTest {
#Test
public void testParse(){
Date goodDate = parseExact("2019-11-05");
Date badDate1 = parseExact("foo 2019-11-05");
Date badDate2 = parseExact("2019-11-05 foo");
assert(goodDate != null);
assert(badDate1 == null);
assert(badDate2 == null);
}
#Nullable
private Date parseExact(#NonNull String text){
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
ParsePosition pos = new ParsePosition(0);
Date date = formatter.parse(text, pos);
if (pos.getIndex() != text.length())
return null;
return date;
}
}