如何获取具有特定模式的区域设置格式的日期?

How to get Date formatted in locale with specific pattern?

经过搜索,我无法找到解决此问题的方法。

我有这个:

Long parseDt = Long.valueOf(arrayJson.getJSONObject(i-j).getInt("dt")); // dt is a timestamp
Locale locale = ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
String date = new SimpleDateFormat("EEE d MMM", locale).format(new java.util.Date(parseDt * 1000));

所以,该模式有效,但是当我更改 phone 语言时,它没有交换显示方式,我想说如果 phone 语言是法语,它会显示日期像这样,它对大多数欧洲语言都有好处:

lun 2 juil

如果我将语言切换为英语,它会像这样显示日期:

mon 2 july

而不是:

mon july 2

知道我想要最多 3 个字符的日期名称,你有什么线索可以解决这个关于我的模式的问题吗?

现有的预定义格式(如 FULL)可以工作,但日期的名称会完整显示,例如它是 "monday",我只想要 "mon",而不是 "monday",所以,有什么想法吗?

您可以根据您获得的语言环境切换格式。

Locale locale = ConfigurationCompat.getLocales(
                   Resources.getSystem().getConfiguration()).get(0);

String fmt = (locale == Locale.ENGLISH) ? "EEE MMM d" : "EEE d MMM";
String date = new SimpleDateFormat(fmt, locale)
                   .format(new java.util.Date(parseDt * 1000));

Java 已经“知道”在哪个语言环境中月份日期在月份名称之前以及在哪个语言环境之后。这就是完整的预定义格式为您提供的。因此,对于可能适用于所有或大多数区域设置的通用解决方案,我建议您依赖它。我们可以修改预定义的完整模式以使用星期几和月份的缩写:

    int parseDt = arrayJson.getJSONObject(i-j).getInt("dt"); // dt is a timestamp
    Locale locale = ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
    String formatPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
            FormatStyle.FULL, null, IsoChronology.INSTANCE, locale);
    formatPattern = formatPattern.replaceAll("E{3,}", "EEE").replaceAll("M{3,}", "MMM");
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(formatPattern, locale);
    ZoneId zone = ZoneId.of("America/Whitehorse");
    ZonedDateTime dateTime = Instant.ofEpochSecond(parseDt).atZone(zone);
    String date = dateTime.format(dateFormatter);
    System.out.println(date);

示例输出:

  • 在英国地区:Mon, 2 Jul 2018
  • 美国地区:Mon, Jul 2, 2018
  • 在法语区域:lun. 2 juil. 2018

我正在使用正则表达式来确保如果星期几 and/or 月在格式模式字符串中(例如 EEEEMMMM),它被修改为它的缩写。由于星期几也可以用小写字母 ec 表示,月份由 L 表示,您可能想对这些字母做同样的技巧。

我正在使用 java.time,现代 Java 日期和时间 API。要在非全新 Android 上使用它,请获取 ThreeTenABP 库:使用底部的链接。如果您反对使用高质量的面向未来的外部库,您可以使用 SimpleDateFormat.

玩类似的把戏

如果您也想省略年份(如您的示例中所示),则稍微复杂一些,但可行。这是一个简单的尝试,可以删除最后出现的年份:

    formatPattern = formatPattern.replaceFirst("^(.*[\w'])([^\w']*y+)$", "");

插入此行后,法语语言环境中的输出就是 lun. 2 juil.,例如。年份也可以用字母 u 给出,您可能也要考虑到这一点。

将您的 Unix 时间转换为日期是对时区敏感的操作,因此我在代码中给出了时区。请把你想要的放在我放的地方America/Whitehorse。如果您相信 JVM 的时区设置反映了用户的需求,您可以使用 ZoneId.systemDefault()(您自己代码中的 SimpleDateFormat 也使用 VM 设置)。

链接

按国家日期格式:

https://en.wikipedia.org/wiki/Date_format_by_country

根据我的应用需要,我选择了最简单的显示方式:

int parseDt = arrayJson.getJSONObject(i-j).getInt("dt"); // dt is a timestamp
Locale locale = ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
String dateFormat = ((locale.equals(Locale.US) || locale.equals(Locale.CHINA) || locale.equals(Locale.CANADA) || locale.equals(Locale.JAPAN)) ? "EEE, MMM d" : "EEE d MMM";
String date = new SimpleDateFormat(dateFormat, locale).format(new java.util.Date(parseDt * 1000));