【问题标题】:SimpleDateFormat pattern based on locale, but forcing a 4-digit yearSimpleDateFormat 模式基于区域设置,但强制使用 4 位数年份
【发布时间】:2011-10-17 15:55:51
【问题描述】:

我需要建立一个日期格式,如dd/MM/yyyy。它几乎像DateFormat.SHORT,但包含 4 年数字。

我尝试用

来实现它
new SimpleDateFormat("dd//MM/yyyy", locale).format(date);

但是对于美国语言环境,格式是错误的。

是否有一种通用的方法来格式化根据区域设置改变模式的日期?

谢谢

【问题讨论】:

  • 您究竟想在这里做什么:为不同的语言环境设置不同的日期格式,或者使用不受语言环境影响的格式?
  • 我正在尝试为不同的语言环境设置不同的日期格式。例如,欧洲语言环境为 dd/MM/yyyy,美国语言环境为 MM/dd/yyyy
  • 请注意,并非所有欧洲国家都遵循dd/mm/yyyy 模式,不少国家使用dd.mm.yyyy,有些甚至使用dd-mm-yyyy。
  • 谢谢,我只是举了一个例子

标签: java locale simpledateformat


【解决方案1】:

我会这样做:

    StringBuffer buffer = new StringBuffer();

    Calendar date = Calendar.getInstance();
    DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
    FieldPosition yearPosition = new FieldPosition(DateFormat.YEAR_FIELD);

    StringBuffer format = dateFormat.format(date.getTime(), buffer, yearPosition);
    format.replace(yearPosition.getBeginIndex(), yearPosition.getEndIndex(), String.valueOf(date.get(Calendar.YEAR)));

    System.out.println(format);

使用 FieldPosition,您不必真正关心日期的格式是包括年份为“yy”还是“yyyy”,年份在哪里结束,甚至使用哪种分隔符。

您只需使用年份字段的开始和结束索引,并始终将其替换为 4 位数年份值,仅此而已。

【讨论】:

    【解决方案2】:

    java.time

    这是现代答案。恕我直言,这些天没有人应该与早已过时的DateFormat 和SimpleDateFormat 课程作斗争。它们的替代品于 2014 年初在现代 Java 日期和时间 API 中出现,java.time classes。

    我只是将Happier’s answer 的想法应用到现代课程中。

    DateTimeFormatterBuilder.getLocalizedDateTimePattern 方法为Locale 生成日期和时间样式的格式模式。我们操纵生成的模式字符串来强制使用 4 位数年份。

    LocalDate date = LocalDate.of( 2017, Month.JULY, 18 );
    
    String formatPattern =
        DateTimeFormatterBuilder.getLocalizedDateTimePattern(
            FormatStyle.SHORT, 
            null, 
            IsoChronology.INSTANCE, 
            userLocale);
    formatPattern = formatPattern.replaceAll("\\byy\\b", "yyyy");
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern, userLocale);
    
    String output = date.format(formatter);
    

    示例输出:

    • 对于Locale.US:7/18/2017。
    • 对于UK、FRANCE、GERMANY 和ITALY 中的每一个:18/07/2017。

    DateTimeFormatterBuilder 允许我们直接获取本地化的格式模式字符串,而无需先获取格式化程序,这在这里很方便。 getLocalizedDateTimePattern() 的第一个参数是日期格式样式。 null 作为第二个参数表示我们不希望包含任何时间格式。在我的测试中,我将LocalDate 用于date,但该代码也适用于其他现代日期类型(LocalDateTime、OffsetDateTime 和ZonedDateTime)。

    【讨论】:

      【解决方案3】:

      我有类似的方法,但我需要获取 ui 控制器的语言环境模式。

      这是代码

                  // date format, always using yyyy as year display
              DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale);
              SimpleDateFormat simple = (SimpleDateFormat) dateFormat;
              String pattern = simple.toPattern().replaceAll("\\byy\\b", "yyyy");
              System.out.println(pattern);
      

      【讨论】:

        【解决方案4】:

        你不能只使用 java.text.DateFormat 类吗?

        DateFormat uk = DateFormat.getDateInstance(DateFormat.LONG, Locale.UK);
        DateFormat us = DateFormat.getDateInstance(DateFormat.LONG, Locale.US);
        
        Date now = new Date();
        String usFormat = us.format(now);
        String ukFormat = uk.format(now);
        

        这应该做你想做的事。

        【讨论】:

        • 不,他想要一个带有四位数年份的本地化 DateFormat.SHORT 模式。
        • 对,我误读了我的一些代码。在这种情况下...执行上述操作(在将 LONG 替换为 SHORT 之后)...然后在将 DateFormat 转换为 SimpleDateFormat 之后调用 toPattern(),然后搜索并将 yy 替换为 yyyy。然后使用新的字符串模式创建一个新的 SimpleDateFormat。
        • 还是错了。您不能期望 DateFormat.getDateInstance 返回的实例是 SimpleDateFormat 类型。
        • 这很奇怪......因为 javadoc 声明“如果你愿意,你也可以在格式上设置时区。如果你想更多地控制格式或解析,(或者想给你的用户更多控制),您可以尝试将您从工厂方法获得的 DateFormat 转换为 SimpleDateFormat。这适用于大多数国家/地区;只需记住将其放在 try 块中,以防遇到一个不寻常的。”
        • “你可以尝试……”和“为大多数人工作……”你有什么不明白的?
        猜你喜欢
        • 1970-01-01
        • 2012-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多