Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to parse three numbers to a LocalDate using a Locale?

I am trying to parse three numbers, like [2, 10, 2014] to a LocalDate using the new Java 8 Date and Time API.

All sounds relatively easy, right? Well, perhaps not.
The additional constraint is that I need to take into account the locale, as for example Dutch and American use different date formatting.

The only input I have are the three numbers and the locale, and the output should be a well-formed date, in the form of a LocalDate.

I have figuring that I will be needing the following steps:

  1. Obtain a converter from a Locale that can read in three numbers.
  2. Using the converter, transform the three numbers into a LocalDate.

I have looked around a bit, especially in the DateTimeFormatter class, but it seems to want to have the day, month and year formats explicitely passed in, which is not an option for me.

How would I convert three numbers (representing the day, month and year in any order) in a LocalDate?

Examples:

Dutch format:

Locale locale = new Locale("nl");
List<String> inputs = Arrays.asList("2", "10", "2014");
//output should equal
LocalDate.of(2014, 10, 2);

American format:

Locale locale = Locale.ENGLISH;
List<String> inputs = Arrays.asList("10", "2", "2014");
//output should equal
LocalDate.of(2014, 10, 2);

Also keep in mind that I am talking about the concept of numbers, but they need to be represented as Strings to also accommodate languages that use other Unicode characters than the digits 0-9 for their numbers.

like image 639
skiwi Avatar asked Oct 02 '14 13:10

skiwi


People also ask

How do you convert mm/dd/yyyy to LocalDate?

out. println(today); //Custom pattern is yyyy/MM/dd DateTimeFormatter formatter = DateTimeFormatter. ofPattern("dd-MMM-yyyy"); LocalDate date = LocalDate. parse("29-Mar-2019", formatter); System.

How do I parse LocalDateTime?

Parsing date and time To create a LocalDateTime object from a string you can use the static LocalDateTime. parse() method. It takes a string and a DateTimeFormatter as parameter. The DateTimeFormatter is used to specify the date/time pattern.

How do I LocalDate in a specific format?

To format the localdate in any other custom pattern, we must use LocalDate. format(DateTimeFormatter) method. LocalDate today = LocalDate. now(); String formattedDate = today.


2 Answers

First create a strings from numbers and then you can use something like

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.FormatStyle;
import java.util.Locale;

public class IntegerDateTest {

    public static void main(String args[]) {
        int[][] dates = {{10, 02, 2014}, {02, 10, 2014}, {2014, 10, 02}};
        Locale[] locales = {Locale.ENGLISH, Locale.FRENCH, Locale.JAPANESE};

        for (int i = 0; i < 3; i++) {
            int[] dateParts = dates[i];
            Locale locale = locales[i];
            String date = String.format("%02d/%02d/%02d", dateParts[0] % 100,
                    dateParts[1] % 100, dateParts[2] % 100);
            System.out.printf("Locale : %s, Str Date : %s,", locale, date);
            DateTimeFormatter df = new DateTimeFormatterBuilder().append(
                    DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT))
                    .toFormatter(locale);
            System.out.printf(" Parsed Date : %s\n",LocalDate.from(df.parse(date)));
        }
    }
}

Output

Locale : en, Str Date : 10/02/14, Parsed Date : 2014-10-02
Locale : fr, Str Date : 02/10/14, Parsed Date : 2014-10-02
Locale : ja, Str Date : 14/10/02, Parsed Date : 2014-10-02
like image 149
bhathiya-perera Avatar answered Nov 04 '22 17:11

bhathiya-perera


You can first retrieve the pattern relate with particular locale and then access the elements according to it. You can retrieve the pattern associated with particular locale using simpleDateFormat.toPattern()Here is a sample code

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

public class T {

    public static void main(String[] args) throws ParseException {
        Locale enLocale = Locale.ENGLISH;
        Locale nlLocale = new Locale("nl");         

        List<String> enInput = Arrays.asList("10", "2", "2014");
        List<String> nlInput = Arrays.asList("2", "10", "2014");
        Map<String, Integer> enPositionMap = getPositionMap(enLocale, enInput);
        Map<String, Integer> nlPositionMap = getPositionMap(nlLocale, nlInput);
        System.out.println("EN date " + LocalDate.of(enPositionMap.get("y"), enPositionMap.get("m"), enPositionMap.get("d")));
        System.out.println("NL date " + LocalDate.of(nlPositionMap.get("y"), nlPositionMap.get("m"), nlPositionMap.get("d")));

    }

    public static Map<String, Integer> getPositionMap(Locale locale, List<String> input) {
        final DateFormat dateInstance = DateFormat.getDateInstance(DateFormat.SHORT, locale);

        Map<String, Integer> map = new HashMap<>();

        if (dateInstance instanceof SimpleDateFormat) {
            String pattern = ((SimpleDateFormat) dateInstance).toPattern();
            String separator = String.valueOf(pattern.charAt(1));

            String[] chunks = pattern.split(separator);

            for (int i = 0; i < chunks.length; i++) {
                switch (chunks[i]) {
                    case "M":
                        map.put("m", Integer.parseInt(input.get(i)));
                        break;
                    case "d":
                        map.put("d", Integer.parseInt(input.get(i)));
                        break;
                    case "yy":
                        map.put("y", Integer.parseInt(input.get(i)));
                        break;
                }
            }

        }

        return map;
    }

}
like image 33
sol4me Avatar answered Nov 04 '22 17:11

sol4me