如何在 Java 中解析包含 Μαϊ(希腊五月)的日期字符串

How to parse a date string including Μαϊ (greek May) in Java

我无法解析包含日期的字符串,其中包括希腊语五月的缩写版本(Μαϊ,它是 Μαΐου - 关于 ψ-ΐ 差异的注释)。

例如:

25 Μαϊ 1989
24 Μαΐ 1967

如果我使用以下格式,将无法解析:

"d MMM yyyy"
"dd MMM yyyy"

通过以下代码:

String dateString = "24 Μαΐ 1967"; // just an example of an input String
SimpleDateFormat format = new SimpleDateFormat(someFormat);
format.parse(dateString);

编辑:我试图解析的值是存储在 Android 中的 sqlite3 数据库中的字符串。特别是 Contact Birthdays 。虽然 Android 依赖,但我会分享代码以获得任何见解:

Cursor cur = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,null,null,null,null);
while(cur.moveToNext()){
   String birthdayString = cur.getString(INDEX_OF_BIRTHDAY);
}

这里(在 Java 8 上)工作正常 if

  • 您将希腊语言环境传递给 SimpleDateFormat 构造函数:Locale.forLanguageTag("el")
  • 您使用 Μαϊ 而不是 Μαΐ

    String dateString = "24 Μαϊ 1967"; // just an example of an input String
    SimpleDateFormat format = new SimpleDateFormat("dd MMM yyyy", Locale.forLanguageTag("el"));
    Date parsed = format.parse(dateString);
    System.out.println("parsed = " + parsed); // parsed = Wed May 24 00:00:00 CET 1967
    

这适用于我的机器 (Java 8):

String dateString = "24 Μαϊ 1967"; // just an example of an input String
SimpleDateFormat format = new SimpleDateFormat("dd MMM yyyy", new Locale("el", "GR"));
format.parse(dateString);

您可以像这样打印出可用的短月份:

Locale locale = new Locale("el", "GR");
DateFormatSymbols dfs = DateFormatSymbols.getInstance(locale);
for (String m : dfs.getShortMonths()) {
    System.out.println(m);
}

其他答案是正确的,例如 Franz Becker 的 。但是他们使用旧的 java.util.Date & java.text.SimpleDateFormat 类。

java.time

这是类似的代码,但使用 Java 8 及更高版本中的新 java.time and java.time.format 包。

正在解析字符串

问题提供了两个示例输入字符串。注意不同的 diacritical signs。第一个有效,但第二个失败。我没有解释,因为我不懂那种语言……"It's all Greek to me"。 ;-)

String input1 = "25 Μαϊ 1989";
String input2 = "24 Μαΐ 1967"; // Different diacritical over the "i".

获取 Locale instance using the static method Locale.forLanguageTag, new in Java 7. Specify an ISO 639 language code (via IETF BCP 47) for Modern Greek 语言。

Locale locale = Locale.forLanguageTag("el");

指定我们期望的确切模式。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd MMM yyyy" ).withLocale( locale );

在新的 Java 8 Lambda 语法中使用推荐的 parse method that takes a method reference (Tutorial)、LocalDate :: from 进行解析。

LocalDate localDate1 = formatter.parse( input1, LocalDate :: from );
LocalDate localDate2 = formatter.parse( input2, LocalDate :: from );  // Fails… Exception in thread "main" java.time.format.DateTimeParseException: Text '24 Μαΐ 1967' could not be parsed at index 3.

转储到控制台。

System.out.println( "localDate1 = " + localDate1 );

当运行.

localDate1 = 1989-05-25

正在生成字符串

反过来,要生成 LocalDate 的字符串表示形式,让 java.time 完成确定本地化格式的工作。使用自动本地化可能比硬编码特定格式更容易、更灵活。

DateTimeFormatter formatterOutput =  DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM ).withLocale( locale );
String output = formatterOutput.format( localDate1 );

System.out.println( "output = " + output );  // output = 25 Μαϊ 1989

完整月份名称

具有不同变音符号的第二个输入字符串似乎是完整月份名称的不恰当缩写 Μαΐου。将完整的月份名称与另一个格式化程序(四个 M 模式字符)一起使用可以成功解析。同样,我不懂现代希腊语,所以这个解释只是我和对此答案发表评论的人的猜测。

此示例代码演示了 input3.

的成功解析
String input1 = "25 Μαϊ 1989";
String input2 = "24 Μαΐ 1967";  // Different diacritical over the "i". Incorrect abbreviation of full month name?
String input3 = "23 Μαΐου 1978";  // Full month name with different diacritical.

Locale locale = Locale.forLanguageTag( "el" );
DateTimeFormatter formatterShort = DateTimeFormatter.ofPattern( "dd MMM yyyy" ).withLocale( locale );
DateTimeFormatter formatterFull = DateTimeFormatter.ofPattern( "dd MMMM yyyy" ).withLocale( locale );

LocalDate localDate1 = formatterShort.parse( input1, LocalDate :: from );
// LocalDate localDate2 = formatter.parse( input2, LocalDate :: from );  // Fails… Exception in thread "main" java.time.format.DateTimeParseException: Text '24 Μαΐ 1967' could not be parsed at index 3.
LocalDate localDate3 = formatterFull.parse( input3, LocalDate :: from );

System.out.println( "localDate1 = " + localDate1 );
System.out.println( "localDate3 = " + localDate3 );