【问题标题】:How to parse three numbers to a LocalDate using a Locale?如何使用语言环境将三个数字解析为 LocalDate?
【发布时间】:2014-10-02 13:15:36
【问题描述】:

我正在尝试使用新的 Java 8 日期和时间 API 解析三个数字,例如 [2, 10, 2014]LocalDate

听起来都比较容易,对吧?好吧,也许不是。
额外的限制是我需要考虑语言环境,例如荷兰语和美国语使用不同的日期格式。

我唯一的输入是三个数字和语言环境,输出应该是格式正确的日期,格式为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 作为数字的语言.

【问题讨论】:

  • 肮脏的解决方案:也许是一个将区域设置映射到特定日期格式的实用程序? Date Format by Country 从日期格式可以推断出数字的顺序(即日、月、年)
  • @gtgaxiola 我希望有人已经做了这样的事情,或者它是 API 的一部分,但我找不到它,但我可能错了。
  • @skiwi 绝对没有在API中看到过,我不知道社区中是否存在这样的项目。如果没有找到,创建它并开源它!或者放一个赏金,有人会的!
  • @assylias 我假设输入将是 [2,10,2014] Locale.nl_NL (例如荷兰语),它将给出 2014 年 10 月 2 日...同时 [2,10,2014 ] Locale.en_US(美国)将于 2014 年 2 月 10 日发布
  • @assylias 刚刚添加了示例。

标签: java java-8 java-time


【解决方案1】:

首先从数字创建一个字符串,然后你可以使用类似的东西

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

输出

语言环境:en,Str 日期:10/02/14,解析日期:2014-10-02 语言环境:fr,Str 日期:02/10/14,解析日期:2014-10-02 语言环境:ja,Str 日期:14/10/02,解析日期:2014-10-02

【讨论】:

  • 我认为 OP 意味着所有语言环境的输入都是相同的:[2, 10, 2014]
  • @A4L if input is same 真的很简单,我相信这就是他想要的。
  • 对不起,他的例子中的输入不同
  • @A4L 不,它们不是...实际上这里的输入是完全相同相同的,除了“nl”替换为“fr”并添加了日语区域设置..
  • 您实际上是在通过将 2014 转换为 14 来作弊,因为显然这很重要...我想要一个更强大的解决方案,可以处理有和没有的天/月前导零和 2 位或 4 位格式的年份。
【解决方案2】:

您可以先检索与特定语言环境相关的模式,然后根据它访问元素。您可以使用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;
    }

}

【讨论】:

  • 您不只是使用 Java8 日期时间 api:DateFormat 不是它的一部分
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-21
  • 1970-01-01
  • 1970-01-01
  • 2012-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多