Is there any java library available to parse language specific ordinal indicator/suffix?
I have a date value like the following: 26th May 2017
. I want to convert this to 26/05/2017
. Could anyone please guide me how to do?
Is there any java library available to parse language specific ordinal indicator/suffix?
I have a date value like the following: 26th May 2017
. I want to convert this to 26/05/2017
. Could anyone please guide me how to do?
You can parse this format directly to a Java 8 LocalDate
using a custom date format:
static final Map<Long, String> ORDINAL_DAYS = new HashMap<>();
static
{
ORDINAL_DAYS.put(1, "1st");
.... more ....
ORDINAL_DAYS.put(26, "26th");
.... more ....
ORDINAL_DAYS.put(31, "31st");
}
static final DateTimeFormatter FORMAT_DAY_MONTH_YEAR = new DateTimeFormatterBuilder()
.appendText(ChronoField.DAY_OF_MONTH, ORDINAL_DAYS)
.appendLiteral(' ')
.appendText(ChronoField.MONTH_OF_YEAR)
.appendLiteral(' ')
.appendText(ChronoField.YEAR)
.toFormatter();
String dateInString = "26th May 2017";
LocalDate date = LocalDate.parse(dateInString, FORMAT_DAY_MONTH_YEAR);
This is using the version of DateTimeFormatter.appendText
which accepts a map that is used to map the day string.
You will need to fill in all the missing entries in ORDINAL_DAYS
that I have left out for brevity.
Assuming you don’t need very strict input validation, since you are converting from the format with th
on the number (or st
or nd
in 31st
, 2nd
and more), I suggest you simply remove those two letters first. A regex may do that:
// remove st, nd, rd or th after day of month
dateInString
= dateInString.replaceFirst("^(\\d+)(st|nd|rd|th)( \\w+ \\d+)$", "$1$3");
String dateOutString = LocalDate.parse(dateInString,
DateTimeFormatter.ofPattern("d MMM uuuu", Locale.ENGLISH))
.format(DateTimeFormatter.ofPattern("dd/MM/uuuu"));
The result is
26/05/2017
This works if your input contains a three letter abbreviation for the month, like Apr, May or Jun. To accept a full month name instead (April, May, June), you need 4 Ms instead of 3 in the format pattern: d MMMM uuuu
.
As stated by @OleV.V. in this comment, you can use a pattern with optional sections (to parse the different suffixes st, nd, rd and th).
You must also use a java.util.Locale
to force month names to English. The code will be like this:
String input = "26th May 2017";
DateTimeFormatter parser = DateTimeFormatter
// parse the day followed by st, nd, rd or th (using optional patterns delimited by [])
.ofPattern("dd['st']['nd']['rd']['th'] MMM yyyy")
// force English locale to parse month names
.withLocale(Locale.ENGLISH);
// formatter for dd/MM/yyyy output
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy").withLocale(Locale.ENGLISH);
System.out.println(formatter.format(parser.parse(input))); // 26/05/2017
The code above will work for month names with 3 letters (like May or Aug). If you want to parse the full names (like August or March), just change MMM
to MMMM
:
DateTimeFormatter parser = DateTimeFormatter
// using MMMM to parse full month name (like "August")
.ofPattern("dd['st']['nd']['rd']['th'] MMMM yyyy")
.withLocale(Locale.ENGLISH);
PS: If you want to parse both cases (3-letter or full month names) using the same parser
, you can do this:
DateTimeFormatter parser = DateTimeFormatter
// can parse "March" or "Mar" (MMMM or MMM)
.ofPattern("dd['st']['nd']['rd']['th'][ MMMM][ MMM] yyyy")
.withLocale(Locale.ENGLISH);
Assuming you are asking about Java, this link: https://www.mkyong.com/java/how-to-convert-string-to-date-java/ May help you.
The overall gist is:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDateExample3 {
public static void main(String[] argv) {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
String dateInString = "26th May 2017"; // Remove your 'th', 'nd', etc. from the input string.
String withoutEnding = dateInString;
//Something like this
if(dateInString.contains("th") withoutEnding = dateInString.replace("th", "");
if(dateInString.contains("nd") withoutEnding = dateInString.replace("nd", "");
if(dateInString.contains("st") withoutEnding = dateInString.replace("st", "");
if(dateInString.contains("rd") withoutEnding = dateInString.replace("rd", "");
try {
Date date = formatter.parse(withoutEnding);
System.out.println(date);
System.out.println(formatter.format(date));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
Where dd/MM/yyyy
is a date formatter that would give you
26/05/2017
.
Hope this helps!
EDIT: Also see http://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html for a full list of the different pattern letters for SimpleDateFormat
.