我需要根据国家代码获取本地化的日期格式。但是美国 returns dd/MM/yyyy

I need to get the localised DateFormat based on the countryCode. But US returns dd/MM/yyyy

这是我的代码:

   try {
        Locale loc = new Locale("", countryCode);
        DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT, loc);
        String pattern = ((SimpleDateFormat) formatter).toPattern();
        format = pattern;
        if (!format.contains("yyyy"))
            format = format.replace("y", "yyyy");
    } catch (Exception e) {
        Log.e("date", "Error trying to get date from Locale:" + e.getMessage());
    }

现在我根据国家代码设置语言环境。 它确实让我返回 "us" displayCountryName as "United Stated" 所以我知道语言环境是正确的。 但是语言环境 returns "dd/MM/y" 为什么?

编辑

我需要将我的最小 API 设置为 22。所以我不能使用 Java8 函数: DateTimeFormatter.ofLocalizedDate(dateStyle); 因为它要求最少 26

此外,我需要根据我发送的国家/地区代码 本地化日期格式。 我有一个国家列表,用户 select 是一个国家,我需要显示它的时间和日期格式

为了提供更多上下文,我加载了一个列表:

  private void createCountriesHashmap() {
    for (String iso : Locale.getISOCountries()) {
        Locale l = new Locale("", iso);
        map.put(l.getDisplayCountry(), iso);
        if (l.getDisplayCountry().trim().length() > 0 && !countries.contains(l.getDisplayCountry())) {
            countries.add(l.getDisplayCountry());
        }
    }
    Collections.sort(countries);
}

当我从那里 select 一个对象时,我得到它的国家代码。我使用国家代码创建语言环境:Locale loc = new Locale("", countryCode); 我需要那个国家的日期格式。不是我的国家

我有同样的问题,我用这个解决了(是 kotlin 但你可以很容易地将它转换为 java):

private val calendario: Calendar = Calendar.getInstance()
private val sdf: DateFormat = SimpleDateFormat.getDateInstance(DateFormat.SHORT)

fechaPagoBT.text = sdf.format(calendario.time)

它returnsdd/MM/yyyy或MM/dd/yyyy基于设备区域。

感谢@MenoHochschild 的评论。我确实设法让它像这样工作:

   Locale loc = new Locale("", countryCode);
        Locale[] locales = java.text.DateFormat.getAvailableLocales();
        for (Locale locale : locales) {
            if (locale.getCountry().contains(countryCode)) {
                loc = locale;
                break;
            }
        }
        DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT, loc);
        String pattern = ((SimpleDateFormat) formatter).toPattern();

目前还不清楚本地化日期格式是与语言相关还是与国家/地区相关。在我看来,它最常与语言或两者的结合联系在一起。因此,当您为没有语言的区域设置(仅国家/地区)请求短日期格式时,您通常会得到 y-MM-dd,这是全球默认的短日期格式。

我的 Java 11 有 6(六)种适用于美国的语言环境,它们倾向于提供不同的短日期格式:

  • lkt_USLakota,一种苏族语言)给出 y-MM-dd(全球默认值)
  • es_US(西班牙语)和 haw_USHawaiian)给出 d/M/yy
  • en_US_POSIXen_USchr_US (Cherokee) 给出 M/d/yy

所以我想以上所有内容都是美国短日期格式的正确答案。而且我相信您自己的答案中的代码会给您其中之一。真正的问题是您想要其中的哪一个。或者你的用户。

java.time 和 ThreeTenABP

既然我正在写答案,我想提一下 DateFormatSimpleDateFormat 是出了名的麻烦和过时的。相反,请考虑使用 java.time 中的 DateTimeFormatter and/or DateTimeFormatterBuilder,现代 Java 日期和时间 API.

    Locale usSpanish = Locale.forLanguageTag("es-US");
    String dateFormatPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
            FormatStyle.SHORT, null, IsoChronology.INSTANCE, usSpanish);
    System.out.println("Format pattern: " + dateFormatPattern);

Format pattern: M/d/yy

我在 Java 7 上 运行 使用 ThreeTen Backport,java.time 的 backport 上的这个片段。并且格式模式与我从上面的 Java 11 中获得的格式模式不同。 Java 7 使用 Java 的 built-in 语言环境数据,而 Java 11 使用 CLDR,Unicode 通用语言环境数据存储库。两者之间存在差异。我不知道Android用的是什么,但我相信这是明智的。

问题:我可以在 Android 上使用 java.time 吗?

是的,java.time 在新旧 Android 设备上都能很好地工作。它只需要至少 Java 6.

  • 在 Java 8 和更新的 Android 设备上(从 API 级别 26)现代 API 出现 built-in.
  • 在 Java 6 和 7 中获取现代 类 的 ThreeTen Backport(ThreeTen 用于 JSR 310;请参阅底部的链接)。
  • 在(较旧的)Android 使用 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。并确保使用子包从 org.threeten.bp 导入日期和时间 类。

链接