2014-11-03 34 views
1

我有以下日期:在乔达的波兰语言环境中解析日期?

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

回答

1

好问题!

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内容)。根据你的语言知识和关于波兰语的感觉,什么更为常见?使用点还是不点?

+0

更常见的是点用法。我的情况很不典型;) – pixel 2014-11-04 21:55:46

+0

@ pixel谢谢你的回答。那么,用我的库Time4J将提供一个非常简单的解决方案;-)否则似乎你必须定义自己的文本资源 - 无论如何 - 等于你使用的库。每个库都可以使用这种解决方法,即使是使用'DateFormatSymbols'的旧'java.text.SimpleDateFormat'也是如此。 – 2014-11-05 08:53:58

3

显然乔达时间(或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); 
    } 
} 

如果你不能改变你的输入,也许你可以改变与语言环境相关的符号?

+0

如何更改与区域设置关联的符号? – pixel 2014-11-03 22:18:26

+1

@pixel:令人烦恼的是,目前还不清楚,即使'Locale.Builder'在这方面也没有帮助。您可以使用'SimpleDateFormat'来替代,并为构造函数指定一个DateFormatSymbols,但我无法看到如何在Joda Time中使用它们。如果您在为特定语言环境提取的'DateFormatSymbols'中设置了新值,那么这可能会粘住 - 但我没有检查它。 – 2014-11-03 22:45:56

相关问题