java.time and optional parts of the format pattern
Consider using java.time, the modern Java date and time API, for your date work. The following method does it. Since with java.time there is no reason to create the formatters anew for each call, I have placed them outside the method.
private static final DateTimeFormatter inputParser
= DateTimeFormatter.ofPattern("uuuu-MM-dd[ HH:mm[:ss]]");
private static final DateTimeFormatter outputFormatter
= DateTimeFormatter.ofPattern("uuuu, MMM d, EEE", Locale.UK);
public static String dateFormatter(String dateToFormat){
LocalDate date = LocalDate.parse(dateToFormat, inputParser);
return date.format(outputFormatter);
}
Try it out:
System.out.println("2021-03-02 -> " + dateFormatter("2021-03-02"));
System.out.println("2021-03-02 20:16 -> " + dateFormatter("2021-03-02 20:16"));
System.out.println("2021-03-02 20:16:28 -> " + dateFormatter("2021-03-02 20:16:28"));
Output is:
2021-03-02 -> 2021, Mar 2, Tue
2021-03-02 20:16 -> 2021, Mar 2, Tue
2021-03-02 20:16:28 -> 2021, Mar 2, Tue
The square brackets in the format pattern string for the input parser denote optional parts. So the time of day is allowed to be there or not. And if it’s there, the seconds are allowed to be present or absent.
This said, you should not want to process your date and time as strings in your app. Process a LocalDate
, or if there’s any possibility that you will need the time of day, then for example a ZonedDateTime
. When you get string input, parse it first thing. And only format back into a string when you must give string output.
With if statements
can your find a way that i can use SimpleDateFormat
I would not want to do that. The SimpleDateFormat
class is a notorious troublemaker of a class and fortunately long outdated
I there a way i can only use if statements so that i don't get to use
many SimpleDateFormats
It doesn’t get you fewer formatters, but you may use if
statements. Just select by the length of the string;
public static String dateFormatter(String dateToFormat){
LocalDate date;
if (dateToFormat.length() == 10) { // uuuu-MM-dd
date = LocalDate.parse(dateToFormat, dateParser);
} else if (dateToFormat.length() == 16) { // uuuu-MM-dd HH:mm
date = LocalDate.parse(dateToFormat, dateTimeNoSecsParser);
} else if (dateToFormat.length() == 19) { // uuuu-MM-dd HH:mm:ss
date = LocalDate.parse(dateToFormat, dateTimeWithSecsParser);
} else {
throw new IllegalArgumentException("Unsupported length " + dateToFormat.length());
}
return date.format(outputFormatter);
}
Only now we need to declare four formatters, three for parsing and one for formatting. I am leaving constructing the parsers to yourself.
I guess that the same if-else strucure will work with SimpleDateFormat
too. You may even just select the format pattern string from the length of the input string and only construct one SimpleDateFormat
instance in each call of the method. I repeat: I would not myself use SimpleDateformat
.
Question: Doesn’t java.time require Android API level 26?
Call requires API level 26 (current min is 16):
java.time.format.DateTimeFormatter#ofPattern
Edit: Contrary to what you might think from this error message java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
- In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
- In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
- On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from
org.threeten.bp
with subpackages.
Links