java.time
With the release of Java SE 8 in March 2014, the outdated and error-prone legacy date-time API (java.util
date-time types and their formatting type, SimpleDateFormat
etc.) was supplanted by java.time
, the modern date-time API* and it is strongly recommended to switch to this new API.
With the modern API, you would not have faced this problem e.g.
With valid date:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String s = "08/01/20";
DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).localizedBy(Locale.ENGLISH);
System.out.println(LocalDate.parse(s, dtf));
}
}
Output:
2020-08-01
With invalid date:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String s = "08/01/20&&";
DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).localizedBy(Locale.ENGLISH);
System.out.println(LocalDate.parse(s, dtf));
}
}
Output:
Exception in thread "main" java.time.format.DateTimeParseException:
Text '08/01/20&&' could not be parsed, unparsed text found at index 8
What if I want the modern API to behave in the way SimpleDateFormat
behaves by default w.r.t. the following rule:
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.
If you need it, DateTimeFormatter#parse(CharSequence, ParsePosition)
is at your disposal:
import java.text.ParsePosition;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String s = "08/01/20&&";
DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).localizedBy(Locale.ENGLISH);
LocalDate date = LocalDate.from(dtf.parse(s, new ParsePosition(0)));
System.out.println(date);
}
}
Output:
2020-08-01
Learn more about java.time
, the modern date-time API* from Trail: Date Time.
Just for the sake of completeness:
Here is what you could have done using the legacy API.
import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
String s = "08/01/20&&";
ParsePosition pp = new ParsePosition(0);
Date value = DateFormat.getDateInstance(DateFormat.SHORT, Locale.ENGLISH).parse(s, pp);
if (value == null || pp.getIndex() != s.length()) {
System.out.println("The input must be a valid date in the form MM/dd/yyyy");
} else {
System.out.println("Value: " + value);
}
}
}
Output:
The input must be a valid date in the form MM/dd/yyyy
ParsePosition#getIndex
returns the index of the character following the last character parsed, which is the index of the first &
in the string, 08/01/20&&
.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.