Дата составления в польском языке в Йоде?

У меня есть следующая дата:

например. 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"

2 ответа

Хороший вопрос!

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
</long,string>

Хорошо, теперь о (старой) Йоде-Времени. Отсутствует такой метод, как 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
</string,></string,>

Наконец, вопрос для вас: в Unicode-CLDR-данных точка используется за сокращенными названиями дней недели, например "pon". вместо "pon" (моя собственная библиотека также использует CLDR-контент). Что более распространено в соответствии с вашими языковыми знаниями и чувствами относительно польского языка? Использование точки или нет?


По-видимому, Joda Time (или Java) рассматривает сокращенную форму poniedziałek - pn, а не pon - поэтому этот код работает (и немного проще, чем ваш):

import org.joda.time.*;
import org.joda.time.format.*;
import java.util.*;

public class Test {
 public static void main(String[] args) throws Exception {
 String rawDate = "pn, 17 lis 2014, 15:51:12";
 DateTimeFormatter parser = DateTimeFormat
 .forPattern("EEEE, dd MMM yyyy, HH:mm:ss")
 .withLocale(new Locale("pl"));
 DateTime time = parser.parseDateTime(rawDate);
 System.out.println(time);
 }
}

Если вы не можете изменить свой вход, возможно, вы можете изменить символы, связанные с языковой версией?

licensed under cc by-sa 3.0 with attribution.