【问题标题】:How to get Date formatted in locale with specific pattern?如何使用特定模式在语言环境中格式化日期?
【发布时间】:2018-07-02 06:49:11
【问题描述】:

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

我有这个:

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));

因此,该模式有效,但是当我更改手机语言时,它并没有交换它的显示方式,我想说如果手机语言是法语,它会显示这样的日期,这对大多数人来说都很好欧洲语言:

七月 2 日

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

7 月 2 日星期一

代替:

7 月 2 日星期一

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

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

【问题讨论】:

  • 您为什么希望 EEE d MMM 后面的日期?
  • 要以mon july 2 格式显示日期,您应该更改SimpleDateFormat 的给定格式。从EEE d MMMEEE MMMM d
  • 您确定您的用户更喜欢“星期一”吗?一方面是怀疑在定义预定义格式方面投入了大量工作,另一方面是尊重您最了解自己的用户(至少我希望您这样做)。
  • @SuganthanMadhavanPillai,理想情况下我不想交换模式。我想要它根据国家自动。我将很快回答我的问题以解释我的选择。
  • @OleV.V.,同意,也许用户更喜欢全天名称,但在这种情况下,我的问题是我没有足够的空间来显示全天名称。理想情况下,日期名称为 3 个字符,月份中的日期为 2 个字符,月份为 3 或 4 个字符,仅此而已,没有更多空间了。

标签: java android datetime simpledateformat


【解决方案1】:

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

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));

【讨论】:

  • 感谢 cricket_007 的想法。我正在考虑做这样的事情,这很棘手。我更喜欢自动的方式来做,但我喜欢它。如果我找不到更多解决方案,我会将此答案作为已接受的答案。谢谢你的帮助。
  • 如果你使用Android View binding,你应该可以在XML中做到这一点,我认为
  • 我接受的答案是针对 cricket_007,但我自己的答案(基于 cricket 答案)非常适合我的问题,并且没有错误(“==”而不是“.equals”)跨度>
【解决方案2】:

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

我正在使用正则表达式来确保如果星期几和/或月份在格式模式字符串中(例如EEEEMMMM),则将其修改为其缩写。由于星期几也可以用小写ec 表示,月份用L 表示,因此您可能希望对这些字母执行相同的操作。

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

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

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

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

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

链接

【讨论】:

  • 非常感谢 Ole V.V.对于您有趣的答案和所花费的时间。我会考虑什么是最简单的方法。我将根据我的要求自行回答这个帖子并解释我的选择。干杯,谢谢。
【解决方案3】:

根据国家的日期格式:

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));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    • 2015-02-06
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多