【问题标题】:Unable to parse a date in the Finnish locale无法解析芬兰语言环境中的日期
【发布时间】:2012-09-25 06:57:59
【问题描述】:

我正在尝试使用我在 Stack Overflow 上找到的示例解析芬兰日期,但我不断收到解析异常。

这是我的 sn-p:

SimpleDateFormat dftFormat = new SimpleDateFormat("dd MMMM yyyy", new Locale("fi", "FI"));
Date datDate = dftFormat.parse("25 syyskuu 2012");

DateFormat 字符似乎与英文字符相同,所以我想知道为什么这不起作用。

这是information about the Finnish locale

谢谢。

【问题讨论】:

  • 该代码对我有用...您使用的是什么 JRE?
  • 没有得到任何异常。在 sysout 中打印 Tue Sep 25 00:00:00 IST 2012
  • 你试过反过来吗?要在芬兰语言环境中输出日期? Mybe这是区域设置不可用的问题吗? (胡乱猜测)
  • 好的,然后尝试@Fildor 建议的方法 - 尝试相反的方法并更新以质疑会发生什么。
  • @MridangAgarwalla 他,我自己实际上是芬兰人,但仍然没有想到那个。很高兴它奏效了。 “syyskuuta”字面意思是“九月”。在 java 世界之外,日期实际上写成“25. syyskuuta”,没有点它有不同的含义......哦,好吧。

标签: java android date locale


【解决方案1】:

似乎所有芬兰日期都以 ta 结尾,即 syyskuu 变为 syyskuuta

我提供的语言环境参考是错误的。如果您看到该链接,您会注意到 ta 丢失了,这是一些误导性信息。我在 Javadocs 中找不到芬兰语语言环境的准确语言环境信息。

感谢@Eis 和@Fildor,我吸取了教训,使用您的解析格式打印出日期以查看结果字符串是什么。然后您可以使用格式比较您的输入字符串是否可解析。

这是我测试代码的方法:

Date datDate = dftFormat.parse("25 syyskuuta 2012");
System.out.println(new SimpleDateFormat("dd MMMM yyyy").format(datDate));

【讨论】:

    【解决方案2】:

    tl;博士

    syyskuusyyskuuta 都是芬兰语中 September 的正确拼写。第一个用于独立使用,第二个用于上下文。

    java.time.Month 枚举可以提供任何一种拼写形式。

    java.time

    我尝试使用现代 java.time 类而不是旧的过时的 java.util.Datejava.text.SimpleDateFormat 类来编写相同类型的代码。

    Java 8 及更高版本中内置的java.time 框架。见Oracle Tutorial。大部分 java.time 功能在 ThreeTen-Backport 中向后移植到 Java 6 和 7,并在 ThreeTenABP 中进一步适应 Android。

    日期值的格式化字符串

    对于这个例子,我们根据问题实例化一个LocalDate 代表 2012 年 9 月 25 日。

    LocalDate ld = LocalDate.of ( 2012 , Month.SEPTEMBER , 25 );  // 2012-09-25
    

    我们得到一个DateTimeFormatter 在生成字符串时自动本地化。调用ofLocalizedDate 意味着我们的字符串将仅代表日期时间值的日期部分。 FormatStyle 控制字符串的长度(完整、长、中、短)。

    DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate ( FormatStyle.LONG );
    

    接下来,我们将 JVM’s current default Locale 的分配替换为 FinlandFinnish 语言环境。这个Locale 对象决定了两件事:(a) 用于翻译诸如日期名称或月份名称等片段的人类语言,以及 (b) 缩写、排序元素(例如月份或日期)的文化规范,使用逗号与句号,等等。

    Locale locale = new Locale ( "fi" , "FI" );
    formatter = formatter.withLocale ( locale );
    

    使用该格式化程序实际生成一个String 来表示我们的LocalDate 值。

    String output = ld.format ( formatter );  // 25. syyskuuta 2012
    

    转储到控制台。

    System.out.println ( "ld: " + ld + " with locale: " + locale + " | output: " + output );
    
    1. syyskuuta 2012

    accepted Answer 所示,java.time 同意syyskuuta 是九月的月份名称。

    显示月份名称

    java.time 类包括Month enum。这个方便的类具有生成字符串的功能,该字符串的月份名称本地化为Locale

    这种本地化类似于我们在上面的代码中看到的本地化的想法。但不同的是使用不同的枚举来控制文本的长度。这里的TextStyle 枚举(而不是FormatStyle)提供完整、窄和短……但也提供这三种长度的“独立”版本。在某些语言中,单独使用文本时使用的单词与完整的日期不同。只是为了好玩,让我们用芬兰语试试。

    Locale locale = new Locale ( "fi" , "FI" );
    EnumSet<TextStyle> styles = EnumSet.allOf ( TextStyle.class );
    
    for ( TextStyle style : styles ) {
        System.out.println ( style + " | " + Month.SEPTEMBER.getDisplayName ( style , locale ) );
    }
    

    谜团解开:独立月份名称

    果然,下面的输出解释了这个谜团。芬兰语:

    • 单独使用月份名称时,将ta 去掉,替换为syyskuu
    • 在特定日期时间值的上下文中使用时,包括 ta 用于 syyskuuta

    已满 |西斯库塔

    FULL_STANDALONE | syyskuu

    简短 |西斯库塔

    SHORT_STANDALONE |系统

    窄 | S

    NARROW_STANDALONE | S

    如果您无法控制应用程序中格式不正确的输入,您可以搜索并将任何独立值替换为其正确版本。或者也许你可以使用DateTimeFormatterBuilder 来期待独立版本(我不知道这是否可能,只是一个想法)。

    【讨论】:

      猜你喜欢
      • 2014-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多