java.lang.IllegalArgumentException:格式无效

时间:2015-05-08 17:37:38

标签: java jodatime

此代码:

DateTimeParser[] parsers = { DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss zzz").getParser(),
DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss").getParser(), DateTimeFormat.forPattern("dd/MM/yyyy HH:mm").getParser(),
DateTimeFormat.forPattern("HH:mm").getParser() };
DateTimeFormatter formatter = new DateTimeFormatterBuilder().append(null, parsers).toFormatter();

Session session;
DateTime dTime = null;
Calendar calendar;

try{
    if (completedTime != null && !completedTime.equalsIgnoreCase("")){
        LocalDateTime jt = LocalDateTime.parse(completedTime, formatter);
        LocalDateTime dt;
        LocalDateTime retDate;

产生错误:

  

java.lang.IllegalArgumentException:格式无效:“09/05/2015 04:00:00 GDT”在“GDT”格式不正确   在LocalDateTime jt = LocalDateTime.parse(completedTime,formatter);线

我不能为我的生活找出原因,为什么它失败了。我很确定它很简单,但我没有发现它。

3 个答案:

答案 0 :(得分:1)

您可能想要引用this线程(或许多其他类似线程之一)。我最好的建议是尝试切割到只有一个" z"在你的解析器中。

答案 1 :(得分:0)

首先要注意的是:

什么是" GDT"?网站http://www.timeanddate.com/time/zones/没有回答。 因此,如果它确实存在并且不是拼写错误,那么您的语言环境是什么?请记住,时区名称和缩写是高度本地化的。

第二:模式符号的数量" z"没关系 - 适用于SimpleDateFormat等类 - 请参阅documentation。全名的四个字母或缩写的小于四个字母:

  

常规时区:时区被解释为文本(如果有)   名。文本:对于格式设置,如果模式字母的数量为4或   更多,使用完整的表格;否则简短或缩写形式   如果可用的话。对于解析,两个表单都是可接受的,独立的   模式字母的数量。

但你使用 Joda-Time 。其文件明确指出:

  

区域名称:无法解析时区名称(' z')。

我已使用最新的Joda-Time版本2.7通过以下代码验证了此不支持:

    DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss z").withLocale(Locale.GERMANY);
    DateTime dt = formatter.parseDateTime("09/05/2015 04:00:00 MESZ");
    System.out.println("Joda-Time: " + dt);
    // Exception in thread "main" java.lang.IllegalArgumentException: Invalid format: "09/05/2015 04:00:00 MESZ" is malformed at "MESZ"

当然," MESZ"是正确的,必须在给定的德语区域设置的上下文中解释为Europe/Berlin

但是,自版本更新(2.2)以来,设置为Locale.US的相同代码适用于某些时区名称,例如" EDT"," PST"等,另见commit。所以我们终于可以说,Joda-Time对时区名称和缩写的解析支持最好说非常有限。再一次,你的Locale是什么?如果它不是美国,那么我可以理解为什么你会得到例外。而且你也会得到一个例外的输入" GDT"即使我们认为它是有效的,因为Joda-Time-parser的功能有限。

答案 2 :(得分:0)

您需要手动指定从时区缩写到时区的映射。例如:

    return new DateTimeFormatterBuilder()
                .appendPattern("dd/MM/yyyy HH:mm:ss ")
                .appendTimeZoneShortName(UK_TIMEZONE_SYMBOLS)
                .toFormatter();

此处UK_TIMEZONE_SYMBOLS是Map<String,DateTimeZone>,其中包含我们对时区名称的看法(因此BST是英国夏令时,而非孟加拉国标准时间)

以下是我们建立自己的方式:

public static Map<String, String> buildTimeZoneSymbolMap(Locale locale) {
    Map<String, String> timeZoneSymbols = Maps.newLinkedHashMap();
    for (String[] zoneInfo : DateFormatSymbols.getInstance(locale).getZoneStrings()) {
        String timeZone = zoneInfo[0];
        if (!timeZoneSymbols.containsKey(zoneInfo[2])) {
            timeZoneSymbols.put(zoneInfo[2], timeZone);
        }
        if (zoneInfo[4] != null && !timeZoneSymbols.containsKey(zoneInfo[4])) {
            timeZoneSymbols.put(zoneInfo[4], timeZone);
        }
    }
    timeZoneSymbols.put("UTC", "GMT");
    return timeZoneSymbols;
}

public static Map<String, DateTimeZone> buildDateTimeZoneSymbolMap(Locale locale) {
    return Maps.transformValues(buildTimeZoneSymbolMap(locale), input -> DateTimeZone.forTimeZone(TimeZone.getTimeZone(input)));
}

public static final Map<String, DateTimeZone> UK_TIMEZONE_SYMBOLS = ImmutableMap.copyOf(buildDateTimeZoneSymbolMap(Locale.UK));