【问题标题】:How to Modify DateFormatSymbols month values如何修改 DateFormatSymbols 月份值
【发布时间】:2011-10-12 16:36:28
【问题描述】:

我正在尝试为特定语言环境添加特定月份名称。 我遇到的问题是挪威博克马尔(nb)的语言环境,SimpleDateFormat返回的月份名称是英文而不是norweigan。但是似乎语言环境(否)工作正常

例如此代码结果为 1 月、2 月等。

String pattern = "MMMM";
DateFormat monthFormat = new SimpleDateFormat(pattern, new Locale("nb"));
Calendar cal = Calendar.getInstance();
for (int i = 0; i < 12; i++) {
  cal.set(Calendar.MONTH, i);
  System.out.println(monthFormat.format(cal.getTime()));
}

vs 此代码导致 Januar、Februar 等

String pattern = "MMMM";
DateFormat monthFormat = new SimpleDateFormat(pattern, new Locale("no"));
Calendar cal = Calendar.getInstance();
for (int i = 0; i < 12; i++) {
  cal.set(Calendar.MONTH, i);
  System.out.println(monthFormat.format(cal.getTime()));
}

我知道我可以使用特定的 DateFormatSymbols 配置 SimpleDateFormat,但这无助于让我的代码对任何未来的本地人都通用。我想知道是否有人知道如何修改受支持的 java 语言环境的默认月份值?我想会有一个可以添加的资源文件,但不知道如何添加。

【问题讨论】:

  • 我碰巧查看了Locale class 的详细信息,看来您需要遵循this iso 标准。可能是您有一个有效常量列表,具体取决于它。顺便说一句,“nb”不是有效的语言常量,这就是为什么它没有被识别并且英语被视为默认值的原因
  • 不太明白你想说什么,但你在谈论 i18n 和 ResourceBundle。如果是这样,那么这可能会有所帮助:stackoverflow.com/questions/4034661/…
  • @Bhesh:OP 希望为特定语言定义自定义月份名称。 Java 没有support 语言nb,因此它将默认为英文月份名称。这与ResourceBundle API 无关。
  • 现在很老的问题 - 你找到解决方案了吗?
  • 它可能会变得有点复杂,但从 Java 8 开始,您可能会看到 CalendarNameProvider 是否可以帮助您。

标签: java


【解决方案1】:

查看source code 中使用的构造函数,用于SimpleDateFormat

public SimpleDateFormat(String pattern, Locale locale) {
    super();
    calendar = new GregorianCalendar(locale);
    ...
    formatData = new DateFormatSymbols(locale);
    ...
    numberFormat = NumberFormat.getInstance(locale);
    ...
}

使用的语言环境的第一个和最后一个实例 (GregorianCalendar) 和 (NumberFormat) 看起来不太乐观,但中间的 (DateFormatSymbols) 可以。查看它的source code,我们在构造函数的第一行看到一个ResourceBundle

public DateFormatSymbols (Locale locale) throws MissingResourceException {
    ResourceBundle res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
        locale, ClassLoader.getSystemClassLoader()); // This line!
    ampms = getStringArray(res, "ampms");
    eras = getStringArray(res, "eras");
    localPatternChars = res.getString("localPatternChars");
    months = getStringArray(res, "months");
    shortMonths = getStringArray(res, "shortMonths");
    shortWeekdays = getStringArray(res, "shortWeekdays");
    weekdays = getStringArray(res, "weekdays");
    runtimeZoneStrings = getZoneStrings(res, locale);
    dateFormats = formatsForKey(res, "DateFormat");
    timeFormats = formatsForKey(res, "TimeFormat");
}

这是您必须编辑的资源包。有很多工具可以做到这一点:

编辑并保存 ResourceBundle 后,您必须扩展这两个类 - 扩展的 DateFormatSymbols 将需要使用新的 ResourceBundle,而扩展的 SimpleDateFormat 将需要使用新的扩展类。

如果您需要更多资源,请考虑查看this oracle article

【讨论】:

    【解决方案2】:

    较新的 Java 版本确实支持 nb (norsk bokmål) 语言环境:

        Locale bokmaal = Locale.forLanguageTag("nb");
        for (Month m : Month.values()) {
            System.out.println(m.getDisplayName(TextStyle.FULL, bokmaal));
        }
    

    我的 Java 9.0.4 上的输出:

    januar
    februar
    mars
    april
    mai
    juni
    juli
    august
    september
    oktober
    november
    desember
    

    在 Java 1.8.0_101 上,我得到相同的输出。

    现在是 2018 年,所以我当然使用 java.time,这是现代 Java 日期和时间 API(不再是设计不佳的 DateFormatSimpleDateFormatCalendar)。

    对于任何以此处结尾的人想要提供不同语言环境的名称(或对从 nb 语言环境获得的输出不满意),有几个选项:

    • 您可以提供自己的 CalendarNameProvider 实现。
    • 您可以使用DateTimeFormatterBuilder 及其appendText 方法的重载版本,该方法接受用于格式化和解析的名称映射。

    this questions: SimpleDateFormat with German Locale - Java 8 vs Java 10 中还有更多内容。

    链接

    【讨论】:

      猜你喜欢
      • 2023-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多