使用SimpleDateFormat(字符串,语言环境)解析法语语言环境的错误

时间:2017-11-24 06:59:39

标签: java simpledateformat french

我的java端有一段这样的代码:

private static DateFormat getHourFormatter(){

        //DateFormatSymbols dateFormatSymbols = new DateFormatSymbols(_locale);
        Locale locale = Locale.FRENCH; //locale : "fr"
        DateFormat hourFormatter = new SimpleDateFormat( "hh:mm a",locale); //hourFormatter: simpleDateFormat@103068 locale: "fr"
        hourFormatter.setTimeZone( TimeZone.getTimeZone("GMT") );
        return hourFormatter; //hourFormatter: SimpleDateFormat@103068
    }



protected static boolean isHoursTimeStringValid( String hourDisplay ) {
         try {
            getHourFormatter().parse( hourDisplay ); //hourDisplay: "01:01 Matin"
            return true;
         } catch (ParseException e) { //e: "java.text.ParseException: Upparseable date "01:01 Matin"
            return false; 
         }
    }

如果我将语言环境值更改为US,则可以正常使用英语语言环境。

但对于法语语言环境,它会抛出解析错误。

  

java.text.ParseException:Upparseable date" 01:01 Matin"

我已将调试信息添加为注释行以便更好地理解

2 个答案:

答案 0 :(得分:1)

在不重写现有代码库的情况下,您仍然可以为此特定目的引入java.time,即现代Java日期和时间API。它确实为法语提供了解决方案:

    Map<Long, String> amPmText = new HashMap<>(4);
    amPmText.put(0L, "Matin");
    amPmText.put(1L, "Soir");
    DateTimeFormatter timeFormatter = new DateTimeFormatterBuilder().appendPattern("hh:mm ")
            .appendText(ChronoField.AMPM_OF_DAY, amPmText)
            .toFormatter(Locale.FRENCH);

    System.out.println(LocalTime.parse("01:01 Matin", timeFormatter));
    System.out.println(LocalTime.parse("10:59 Soir", timeFormatter));

打印

01:01
22:59

混合java.time和过时的课程

到目前为止,我们的代码库(旧的)是新旧日期和时间API使用的有趣组合。坦率地说,我们很少重写任何旧代码和工作代码,但我们总是使用现代API来创建新代码。

我热烈建议您尽可能使用java.time。通常这么好用。一旦你开始使用它,我相信你不会想要回去。

对于纯SimpleDateFormat解决方案,请参阅Meno Hochschild’s comment below

答案 1 :(得分:1)

当且仅当您只有两个可能的值(此处为AM / PM)时,您可以通过SimpleDateFormat这样做:

DateFormatSymbols dfs = DateFormatSymbols.getInstance(Locale.FRENCH);
dfs.setAmPmStrings(new String[] { "Matin", "Soir" });
SimpleDateFormat input = new SimpleDateFormat("hh:mm a", Locale.FRENCH);
input.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
input.setDateFormatSymbols(dfs);

Date parsed = input.parse("01:01 Matin");

// control of parsing
SimpleDateFormat output = new SimpleDateFormat("HH:mm");
output.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
System.out.println(output.format(parsed)); // 01:01 (24-hour-clock)

我在这里将时区设置为GMT以防止任何区域效应。如果需要,你可以偏离它(但需要小心)。

正如一些评论中所提到的,我仍然认为使用AM / PM字段并不适合其他语言而不是英语。例如,法语至少知道两个或更多的值,如“nuit”(=夜晚)或“après-midi”(=下午)。但是使用旧的API或新的java.time - 包(需要外部库,如ICU4J或Time4J),这种方式是不可能的。