Как разобрать три числа на LocalDate с помощью Locale?

Я пытаюсь разобрать три числа, например [2, 10, 2014] в LocalDate, используя новый API даты и времени Java 8.

Все звучит относительно просто, не так ли? Ну, возможно, нет.
Дополнительным ограничением является то, что мне нужно учитывать языковой стандарт, так как, например, в голландском и американском форматах даты используются разные форматы.

Единственный ввод, который у меня есть, это три числа и локаль, а вывод должен быть правильно сформированной датой в виде LocalDate.

Я полагаю, что мне понадобятся следующие шаги:

  1. Получите преобразователь от Locale, который может читать три числа.
  2. С помощью конвертера преобразуйте эти три числа в LocalDate.

Я немного огляделся, особенно в классе DateTimeFormatter, но, похоже, он хочет, чтобы форматы дня, месяца и года были явно переданы, что для меня не вариант.

Как преобразовать три числа (представляющие день, месяц и год в любом порядке) в LocalDate?

Примеры:

Голландский формат:

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

Американский формат:

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

Также имейте в виду, что я говорю о концепции чисел, но они должны быть представлены в виде строк, чтобы также приспособиться к языкам, которые используют другие символы Unicode, чем цифры 0–9 для своих чисел.


person skiwi    schedule 02.10.2014    source источник
comment
Грязное решение: возможно, утилита, которая сопоставляет локаль с определенными форматами даты? Формат даты по странам из формата даты вы можете вывести порядок чисел (какой из них день, месяц, год)   -  person gtgaxiola    schedule 02.10.2014
comment
@gtgaxiola Я ожидал, что кто-то уже сделал такую ​​​​вещь или что она является частью API, но я не смог ее найти, но я мог ошибаться.   -  person skiwi    schedule 02.10.2014
comment
@skiwi Определенно я не видел в API, я не знаю, существует ли такой проект в сообществе. Если не найдено, создайте его и откройте исходный код! Или поставьте баунти и кто-то будет!   -  person gtgaxiola    schedule 02.10.2014
comment
@assylias Я предполагаю, что ввод будет [2,10,2014] Locale.nl_NL (например, голландский), что даст 2 октября 2014 года ... Между тем [2,10,2014] Locale.en_US (США) будет дайте 10 февраля 2014   -  person gtgaxiola    schedule 02.10.2014
comment
@assylias Только что добавил примеры.   -  person skiwi    schedule 02.10.2014
comment
@skiwi, решение должно быть строго на Java 8?   -  person sol4me    schedule 02.10.2014
comment
@sol4me В каком-то смысле да, потому что я хочу использовать новый API даты и времени Java под java.time, теперь я не говорю, что его нельзя перенести на Java 7, но давайте оставим его на Java 8.   -  person skiwi    schedule 02.10.2014


Ответы (2)


Сначала создайте строки из чисел, а затем вы можете использовать что-то вроде

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)));
        }
    }
}

Выход

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
person bhathiya-perera    schedule 02.10.2014
comment
Я думаю, что OP означает, что ввод одинаков для всех локалей: [2, 10, 2014] - person A4L; 02.10.2014
comment
@ A4L, если ввод тот же, это очень просто, я уверен, что это то, что он хочет. - person bhathiya-perera; 02.10.2014
comment
извините, входные данные в его примерах разные - person A4L; 02.10.2014
comment
@ A4L нет, это не так ... На самом деле входные данные здесь точно такие же, за исключением того, что nl заменен на fr и добавлен японский язык .. - person Vogel612; 02.10.2014
comment
Я пытаюсь охватить все возможные сценарии :D - person bhathiya-perera; 02.10.2014
comment
@ Vogel612 хорошо, учитывая локаль, да, но я думаю, что строки разные [2, 10, 2014] против [10, 2, 2014] - person A4L; 02.10.2014
comment
Вы на самом деле обманываете здесь, превращая 2014 в 14, поскольку, по-видимому, это имеет значение... Мне нужно несколько более надежное решение, которое может обрабатывать дни/месяцы с ведущими нулями и без них, а также год в двузначном или двузначном формате. 4-значный формат. - person skiwi; 02.10.2014
comment
@skiwi Вам нужно взять это отсюда, удачи. - person bhathiya-perera; 03.10.2014

Вы можете сначала получить шаблон, связанный с определенной локалью, а затем получить доступ к элементам в соответствии с ним. Вы можете получить шаблон, связанный с определенной локалью, используя simpleDateFormat.toPattern()Вот пример кода

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;
    }

}
person sol4me    schedule 02.10.2014
comment
Вы не используете только Java8 Date Time API: DateFormat не является его частью - person bhathiya-perera; 02.10.2014