Java 解析与格式化

Java 解析与格式化,用户希望解析或格式化 Date-Time API 中的类,DateTimeFormatter 类用于创建日期 / 时间格式,可以在解析和格式化中使用。DateTimeFormatter 类提供大量预定义格式化器(predefined formatter),包括常量(如 ISO_LOCAL_DATE)、模式字母(如 uuuu-MMM-dd)以及本地化样式(如 ofLocalizedDate(dateStyle))。

Java 解析与格式化 问题描述

用户希望解析或格式化 Date-Time API 中的类。

Java 解析与格式化 解决方案

DateTimeFormatter 类用于创建日期 / 时间格式,可以在解析和格式化中使用。

Java 解析与格式化 具体实例

DateTimeFormatter 类提供大量预定义格式化器(predefined formatter),包括常量(如 ISO_LOCAL_DATE)、模式字母(如 uuuu-MMM-dd)以及本地化样式(如 ofLocalizedDate(dateStyle))。
好在解析和格式化的过程并不复杂。在 Date-Time API 中,所有主要的类均提供 parseformat 方法。以 LocalDate 类为例,其 parseformat 方法的签名如例 8-28 所示。

例 8-28 LocalDate 类定义的 parseformat 方法

static LocalDate parse(CharSequence text)  ➊
static LocalDate parse(CharSequence text, DateTimeFormatter formatter)
       String    format(DateTimeFormatter formatter)

➊ 使用 ISO_LOCAL_DATE
解析和格式化的应用如例 8-29 所示。

例 8-29 对 LocalDateTime 解析和格式化

LocalDateTime now = LocalDateTime.now();
String text = now.format(DateTimeFormatter.ISO_DATE_TIME);  ➊
LocalDateTime dateTime = LocalDateTime.parse(text);         ➋

❶ 将 LocalDateTime 格式化为字符串
❷ 将字符串解析为 LocalDateTime
因此,我们可以调整日期 / 时间格式、区域设置等各种参数。部分应用如例 8-30 所示。

例 8-30 对日期进行格式化

LocalDate date = LocalDate.of(2017, Month.MARCH, 13);

System.out.println("Full : " +
    date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)));
System.out.println("Long : " +
    date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)));
System.out.println("Medium : " +
    date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)));
System.out.println("Short : " +
    date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)));

System.out.println("France : " +
    date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
        .withLocale(Locale.FRANCE)));
System.out.println("India : " +
    date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
        .withLocale(new Locale("hin", "IN"))));
System.out.println("Brazil : " +
    date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
        .withLocale(new Locale("pt", "BR"))));
System.out.println("Japan : " +
    date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
        .withLocale(Locale.JAPAN)));

Locale loc = new Locale.Builder()
        .setLanguage("sr")
        .setScript("Latn")
        .setRegion("RS")
        .build();
System.out.println("Serbian: " +
    date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
        .withLocale(loc)));

执行上述程序,输出类似于:10
10有传言说,作者有意选择稀有语种和输出格式,只是为了测试 O’Reilly Media 能否正确打印出相应的结果。不过至少就读者所知,这并非事实。

Full   : Monday, March 13, 2017
Long   : March 13, 2017
Medium : Mar 13, 2017
Short  : 3/13/17

France : lundi 13 mars 2017
India  : Monday, March 13, 2017
Brazil : Segunda-feira, 13 de Março de 2017
Japan  : 2017 年3 月13 日
Serbian: ponedeljak, 13. mart 2017

由于 parseformat 方法分别抛出 DateTimeParseExceptionDateTimeException,用户可能希望在自己的代码中捕获它们。
我们也可以通过 DateTimeFormatter 类提供的 ofPattern 方法创建自定义格式化器,Javadoc 详细描述了所有可以使用的合法值。ofPattern 方法的应用如例 8-31 所示。

例 8-31 自定义格式化模式

ZonedDateTime moonLanding = ZonedDateTime.of(
        LocalDate.of(1969, Month.JULY, 20),
        LocalTime.of(20, 18),
        ZoneId.of("UTC")
);
System.out.println(moonLanding.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));

DateTimeFormatter formatter =
    DateTimeFormatter.ofPattern("uuuu/MMMM/dd hh:mm:ss a zzz GG");
System.out.println(moonLanding.format(formatter));

formatter = DateTimeFormatter.ofPattern("uuuu/MMMM/dd hh:mm:ss a VV xxxxx");
System.out.println(moonLanding.format(formatter));

输出如下:

1969-07-20T20:18:00Z[UTC]
1969/July/20 08:18:00 PM UTC AD
1969/July/20 08:18:00 PM UTC +00:00

有关 DateTimeFormatter 类的用途以及各种模式字母的含义,请参见 Javadoc。不过读者无须担心,格式化的过程并不复杂。
接下来,我们通过夏时制(daylight savings time)问题来展示本地化日期 / 时间格式化器的应用。北美东部时区(EST)从 2018 年 3 月 11 日凌晨 2 时起实行夏时制,将时钟调快一小时。那么在 3 月 11 日凌晨 2 时 30 分时,某个地区的日期和时间是多少呢?相关示例如例 8-32 所示。

例 8-32 将时钟调快一小时

ZonedDateTime zdt = ZonedDateTime.of(2018, 3, 11, 2, 30, 0, 0,
    ZoneId.of("America/New_York"));
System.out.println(
    zdt.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL)));

在本例中,ZonedDateTime.of 方法传入年、月、日、小时、分、秒、纳秒以及时区作为参数。除时区(ZoneId)外,其他字段均为 int 类型,即无法使用 Month 枚举。
输出如下:

Sunday, March 11, 2018 3:30:00 AM EDT

可以看到,程序将时间从凌晨 2 时 30 分调整为凌晨 3 时 30 分。

赞(0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

Java 实例