微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Java 8 time/LocalDate:将日期从一种格式转换为本地特定格式 输出

如何解决Java 8 time/LocalDate:将日期从一种格式转换为本地特定格式 输出

我从服务器调用中获得了 2 条信息、一个日期字符串和一个用户区域设置

String originalDateStr = serverCallToGetADate().getDate();
String localeString = serverCallToGetADate().getLocaleString();

无论区域如何,日期都保证采用以下格式

yyyy-MM-dd

locale 是 IETF 语言代码,如

en-US fr-FR es-ES de-DE etc 

我可以使用

为日期创建一个 LocalDate 对象
DateTimeFormatter originalFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

LocalDate originalDate = LocalDate.parse(originalDateStr,originalFormatter);

我现在想使用值之间的“-”并使用我也从服务器收到的语言环境字符串将日期打印为 4 个数字,月份为 2 个数字,日期为 2 个数字。例如,如果日期是 2021 年 7 月 31 日,我想将日期呈现为

  • 英国:31-07-2021
  • 美国:07-31-2021
  • 日本:2021-07-31

我不知道如何做到这一点。这是我试过的

@Test
public void testFormatting() {
    String SERVER_FORMAT = "yyyy-MM-dd";
    String SERVER_TEST_DATE = "2021-07-31";

    DateTimeFormatter serverFormatter = DateTimeFormatter.ofPattern(SERVER_FORMAT);
    // can only create a LocalDate from the server value as there is no time part in the string
    LocalDate testDate = LocalDate.parse(SERVER_TEST_DATE,serverFormatter);

    System.out.println("Original Server Date Value = " + testDate.format(serverFormatter));

    System.out.println("\nUsing : testDate.format(serverFormatter.withLocale(locale) - Doesn't work");
    Locale localeUS = Locale.forLanguageTag("en-US");
    Locale localeUK = Locale.forLanguageTag("en-GB");
    System.out.println("Attempting US (should be 07-31-2021) = " + testDate.format(serverFormatter.withLocale(localeUS)));
    System.out.println("Attempting UK (should be 31-07-2021) = " + testDate.format(serverFormatter.withLocale(localeUK)));


    // in order to use the following coed these we need a time part for the date,so put to start of day
    System.out.println("\nUsing DateTimeFormatterBuilder - wrong as it includes / or,and has time displayed");
    LocalDateTime testDateTime = testDate.atStartOfDay();
    String datePattern_short = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
            FormatStyle.SHORT,FormatStyle.MEDIUM,Chronology.ofLocale(localeUS),localeUS);
    DateTimeFormatter dateFormatterShort = DateTimeFormatter.ofPattern(datePattern_short);
    System.out.println("datePattern SHORT US (should be 07-31-2021)  = " + testDateTime.format(dateFormatterShort));

    String datePattern_medium = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
            FormatStyle.MEDIUM,localeUS);
    DateTimeFormatter dateFormatterMedium = DateTimeFormatter.ofPattern(datePattern_medium);
    System.out.println("datePattern MEDIUM US (should be 07-31-2021)  = " + testDateTime.format(dateFormatterMedium));

    String datePattern_long = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
            FormatStyle.LONG,localeUS);
    DateTimeFormatter dateFormatterLong = DateTimeFormatter.ofPattern(datePattern_long);
    System.out.println("datePattern LONG US (should be 07-31-2021)  = " + testDateTime.format(dateFormatterLong));
}

输出

Original Server Date Value = 2021-07-31

Using : testDate.format(serverFormatter.withLocale(locale) - Doesn't work
Attempting US (should be 07-31-2021) = 2021-07-31
Attempting UK (should be 31-07-2021) = 2021-07-31

Using DateTimeFormatterBuilder - wrong as it includes / or,and has time displayed
datePattern SHORT US (should be 07-31-2021)  = 7/31/21,12:00:00 am
datePattern MEDIUM US (should be 07-31-2021)  = Jul 31,2021,12:00:00 am
datePattern LONG US (should be 07-31-2021)  = July 31,12:00:00 am

解决方法

Sweeper 在他们的评论中给出了答案。

我试图做的事情是无效的。我应该始终使用语言环境时区的标准格式。

,

我不确定为什么你认为你想要这个并且倾向于接受 Sweeper 的建议:你应该相信 Java 从 CLDR(Unicode 通用语言环境数据存储库)和/或其他来源获得的本地化格式模式。我不认为世界各地的用户会因为您在任何地方强制使用连字符格式而感到高兴。

但是,如果您坚持,您可以通过一些更简单的正则表达式将您从 DateTimeFormatterBuilder 获得的格式模式字符串修改为您的要求。

    String[] tags = { "en-US","fr-FR","es-ES","de-DE","jp-JP" };
    LocalDate sampleDate = LocalDate.of(2021,Month.JULY,31);
    for (String langTag : tags) {
        Locale loc = Locale.forLanguageTag(langTag);
        String pattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
                FormatStyle.SHORT,null,IsoChronology.INSTANCE,loc);
        // Ensure full year and 2-digit month and day
        pattern = pattern.replaceAll("y+","y")
                         .replaceAll("M+","MM")
                         .replaceAll("d+","dd");
        // Change punctuation to hyphens
        pattern = pattern.replaceFirst("^\\W+","")
                         .replaceFirst("\\W+$","")
                         .replaceAll("\\W+","-");
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(pattern);
        System.out.format("%-5s -> %s%n",langTag,sampleDate.format(dateFormatter));
    }

这个片段的输出是:

en-US -> 07-31-2021
fr-FR -> 31-07-2021
es-ES -> 31-07-2021
de-DE -> 31-07-2021
jp-JP -> 2021-07-31

我相信,如果模式中的两个或多个字段相邻,我的代码将无法插入连字符,例如 yyMM。我不知道这是否发生在任何语言环境中。此外,它不会删除作为某些语言环境格式一部分的任何文字字母。因此,将其作为起点并根据您的需求进行改进。您可能希望使用 JVM 中的所有可用语言环境进行测试。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?