How to convert the date value "26th May 2017" to "26/05/2017"? [duplicate]
Asked Answered
C

4

-2

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?

Copeland answered 25/5, 2017 at 16:46 Comment(4)
In Java or Javascript? What do Spring and Hibernate have to do this? What research have you done on the many questions about date format conversion?Cabalist
I want to convert 26th May 2017 to 26/05/2017 in Java program.Copeland
Is there any better way to do this in java?Copeland
Fyi, "ordinal" is the technical term to use is searching on this topic of st, th, rd, and nd.Dimitrovo
H
3

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.

Hachmin answered 25/5, 2017 at 17:58 Comment(1)
More lenient, but also briefer: static final DateTimeFormatter FORMAT_DAY_MONTH_YEAR = DateTimeFormatter.ofPattern("d['st']['nd']['rd']['th'] MMMM uuuu", Locale.ENGLISH);. PS Consider specifying the locale.Amidst
A
2

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.

Amidst answered 25/5, 2017 at 19:36 Comment(0)
U
2

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);
Usually answered 25/5, 2017 at 21:59 Comment(5)
It's a good answer, and I am happy if I have contributed to it or inspired it one way or the other. If so, a mention would be nice. In any case your explanations are probably better than mine, or at least different and thus a good supplement.Amidst
In both code snippets you may use the two-arg DateTimeFormatter.ofPattern() for a bit terser code.Amidst
@OleV.V. To be honest, I saw your comment with this solution just after I posted my answer (I just had a very similar code here, with optional patterns and so on, and as soon as I read the question, posted the answer without looking at anything else). Sorry if I gave the impression that I copied your idea without giving any credit. Anyway, I'm gonna edit the answer to add this info. And I always forget about the 2-arg version of ofPattern - I usually don't need to set different locales. Thanks!Usually
I believe you. :-)Amidst
BTW I recommend making it a rule to use the two-arg ofPattern(). Even when you pass Locale.getDefault() as the second argument, you are telling the reader (and yourself!) that you have thought about the locale and made a conscious decision about which locale to use.Amidst
L
1

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.

Lodie answered 25/5, 2017 at 16:54 Comment(6)
i want to parse date value with 'th','nd' to standard Java Date format.Copeland
@Copeland Sorry, misread it! I just updated the answer to better answer your actual question. May not be the most efficient way (I'm at work so don't have a ton of time) but should work!Lodie
@Copeland you may even be able to leave the suffix in, but I'm not sure, I haven't tested this.Lodie
Thanks! @Chris Gilardi, Is there any java library available to parse above date format.Copeland
@Copeland not sure.Lodie
You replacement will turn August into Augu. Unless of course it was already just Aug from the start, this wasn’t very clear from the question.Amidst

© 2022 - 2024 — McMap. All rights reserved.