在Joda的波兰语区域解析日期?(Parsing date in polish locale in Joda?)

我有以下日期:

例如。 String rawDate = "pon, 17 lis 2014, 15:51:12";

我想解析它。

我打电话:

DateTime time = new DateTimeFormatterBuilder() .append(DateTimeFormat.forPattern("EEE, dd MMM yyyy, HH:mm:ss") .getParser()) .toFormatter().withLocale(new Locale("pl")).parseDateTime(rawDate);

但我得到:

java.lang.IllegalArgumentException: Invalid format: "pon, 17 lis 2014, 15:51:12"

I have following date:

eg. String rawDate = "pon, 17 lis 2014, 15:51:12";

and I would like to parse it.

I call:

DateTime time = new DateTimeFormatterBuilder() .append(DateTimeFormat.forPattern("EEE, dd MMM yyyy, HH:mm:ss") .getParser()) .toFormatter().withLocale(new Locale("pl")).parseDateTime(rawDate);

But I get:

java.lang.IllegalArgumentException: Invalid format: "pon, 17 lis 2014, 15:51:12"

最满意答案

好问题!

JDK使用自己的文本资源。 因此,遵循Java-8代码会产生异常:

String input = "pon, 17 lis 2014, 15:51:12"; DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy, HH:mm:ss", new Locale("pl")); LocalDateTime ldt1 = LocalDateTime.parse(input, dtf1); System.out.print(ldt1); // error message: // java.time.format.DateTimeParseException: // Text 'pon, 17 lis 2014, 15:51:12' could not be parsed at index 0

如果我们试图找出问题所在,那么我们发现JDK使用“Pn”:

DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy, HH:mm:ss", new Locale("pl")); String output = LocalDateTime.of(2014, 11, 17, 15, 51, 12).format(dtf1); System.out.println(output); // "Pn, 17 lis 2014, 15:51:12" LocalDateTime ldt1 = LocalDateTime.parse(output, dtf1);

通常人们无法改变输入。 幸运的是,有一种解决方法可以定义您自己的文本资源:

String input = "pon, 17 lis 2014, 15:51:12"; TemporalField field = ChronoField.DAY_OF_WEEK; Map<Long,String> textLookup = new HashMap<>(); textLookup.put(1L, "pon"); textLookup.put(2L, "wt"); textLookup.put(3L, "\u0347r"); // śr textLookup.put(4L, "czw"); textLookup.put(5L, "pt"); textLookup.put(6L, "sob"); textLookup.put(7L, "niedz"); DateTimeFormatter dtf2 = new DateTimeFormatterBuilder() .appendText(field, textLookup) .appendPattern(", dd MMM yyyy, HH:mm:ss") .toFormatter() .withLocale(new Locale("pl")); LocalDateTime ldt2 = LocalDateTime.parse(input, dtf2); System.out.print(ldt2); // output: 2014-11-17T15:51:12

好的,现在关于(旧) Joda-Time 。 它缺少像appendText(field, lookupMap)这样的方法。 但是我们可以为DateTimeParser编写一个实现:

final Map<String, Integer> textLookup = new HashMap<String, Integer>(); textLookup.put("pon", 1); textLookup.put("wt", 2); textLookup.put("\u0347r", 3); // śr textLookup.put("czw", 4); textLookup.put("pt", 5); textLookup.put("sob", 6); textLookup.put("niedz", 7); DateTimeParser parser = new DateTimeParser() { @Override public int estimateParsedLength() { return 5; } @Override public int parseInto(DateTimeParserBucket bucket, String text, int position) { for (String key : textLookup.keySet()) { if (text.startsWith(key, position)) { int val = textLookup.get(key); bucket.saveField(DateTimeFieldType.dayOfWeek(), val); return position + key.length(); } } return ~position; } }; DateTimeFormatter dtf = new DateTimeFormatterBuilder().append(parser) .appendPattern(", dd MMM yyyy, HH:mm:ss").toFormatter() .withLocale(new Locale("pl")); String input = "pon, 17 lis 2014, 15:51:12"; LocalDateTime ldt = LocalDateTime.parse(input, dtf); System.out.println(ldt); // 2014-11-17T15:51:12.000

最后一个问题:在Unicode-CLDR数据中,在缩写的工作日名称后面使用一个点,例如“pon”。 而不是“pon”(我自己的库也使用CLDR内容)。 根据您的语言知识和对抛光的感觉,更常见的是什么? 是否使用点?

Good question!

The JDK uses its own text resources. So following Java-8-code produces an exception:

String input = "pon, 17 lis 2014, 15:51:12"; DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy, HH:mm:ss", new Locale("pl")); LocalDateTime ldt1 = LocalDateTime.parse(input, dtf1); System.out.print(ldt1); // error message: // java.time.format.DateTimeParseException: // Text 'pon, 17 lis 2014, 15:51:12' could not be parsed at index 0

If we try to find out what is the problem then we find out that JDK uses "Pn":

DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy, HH:mm:ss", new Locale("pl")); String output = LocalDateTime.of(2014, 11, 17, 15, 51, 12).format(dtf1); System.out.println(output); // "Pn, 17 lis 2014, 15:51:12" LocalDateTime ldt1 = LocalDateTime.parse(output, dtf1);

Normally people cannot change the input. Fortunately, there is a workaround defining your own text resources:

String input = "pon, 17 lis 2014, 15:51:12"; TemporalField field = ChronoField.DAY_OF_WEEK; Map<Long,String> textLookup = new HashMap<>(); textLookup.put(1L, "pon"); textLookup.put(2L, "wt"); textLookup.put(3L, "\u0347r"); // śr textLookup.put(4L, "czw"); textLookup.put(5L, "pt"); textLookup.put(6L, "sob"); textLookup.put(7L, "niedz"); DateTimeFormatter dtf2 = new DateTimeFormatterBuilder() .appendText(field, textLookup) .appendPattern(", dd MMM yyyy, HH:mm:ss") .toFormatter() .withLocale(new Locale("pl")); LocalDateTime ldt2 = LocalDateTime.parse(input, dtf2); System.out.print(ldt2); // output: 2014-11-17T15:51:12

Okay, now about (old) Joda-Time. It is missing such a method like appendText(field, lookupMap). But we can write an implementation for a DateTimeParser:

final Map<String, Integer> textLookup = new HashMap<String, Integer>(); textLookup.put("pon", 1); textLookup.put("wt", 2); textLookup.put("\u0347r", 3); // śr textLookup.put("czw", 4); textLookup.put("pt", 5); textLookup.put("sob", 6); textLookup.put("niedz", 7); DateTimeParser parser = new DateTimeParser() { @Override public int estimateParsedLength() { return 5; } @Override public int parseInto(DateTimeParserBucket bucket, String text, int position) { for (String key : textLookup.keySet()) { if (text.startsWith(key, position)) { int val = textLookup.get(key); bucket.saveField(DateTimeFieldType.dayOfWeek(), val); return position + key.length(); } } return ~position; } }; DateTimeFormatter dtf = new DateTimeFormatterBuilder().append(parser) .appendPattern(", dd MMM yyyy, HH:mm:ss").toFormatter() .withLocale(new Locale("pl")); String input = "pon, 17 lis 2014, 15:51:12"; LocalDateTime ldt = LocalDateTime.parse(input, dtf); System.out.println(ldt); // 2014-11-17T15:51:12.000

Finally a question to you: In Unicode-CLDR-data a dot is used behind the abbreviated weekday names, for example "pon." instead of "pon" (my own library uses the CLDR-content, too). What is more common according to your language knowledge and feeling regarding polish? Using a dot or not?

更多推荐