我有以下日期:

例如。 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"

最佳答案

好问题!

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


好的,现在(约)乔达时代。它缺少像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内容)。根据您的语言知识和对波兰的感觉,更常见的是什么?是否使用点?

09-03 19:56