Java DateTimeFormatterBuilder 类
最后修改时间:2025 年 4 月 16 日
java.time.format.DateTimeFormatterBuilder 类提供了一种灵活的方式来创建自定义日期和时间格式化程序。它允许精确控制格式化模式、文本样式和可选部分。
当预定义的格式化程序不满足需求时,可以使用 DateTimeFormatterBuilder。它支持区域设置敏感的格式化、填充和附加文字。构建器模式支持逐步构建格式化程序。
DateTimeFormatterBuilder 概述
构建器类提供了附加各种日期/时间组件的方法。它可以组合模式、文本样式和文字值。最终的格式化程序通过调用 toFormatter() 创建。
public final class DateTimeFormatterBuilder {
public DateTimeFormatterBuilder appendPattern(String pattern);
public DateTimeFormatterBuilder appendValue(TemporalField field);
public DateTimeFormatterBuilder appendText(TemporalField field, TextStyle style);
public DateTimeFormatterBuilder appendLiteral(String literal);
public DateTimeFormatterBuilder appendFraction(TemporalField field,
int minWidth, int maxWidth, boolean decimalPoint);
public DateTimeFormatterBuilder optionalStart();
public DateTimeFormatterBuilder optionalEnd();
public DateTimeFormatter toFormatter();
}
该代码展示了 DateTimeFormatterBuilder 的关键方法。这些方法允许从简单的组件构建复杂的格式化程序。构建器可以处理日期/时间字段的数字和文本表示形式。
基本格式化程序构建
此示例演示了使用构建器创建简单格式化程序。我们将组合不同的日期组件和文字文本来创建自定义格式。格式化程序将以“日、月 年”格式显示日期。
package com.zetcode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
public class Main {
public static void main(String[] args) {
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendText(java.time.temporal.ChronoField.DAY_OF_WEEK, TextStyle.FULL)
.appendLiteral(", ")
.appendText(java.time.temporal.ChronoField.MONTH_OF_YEAR, TextStyle.FULL)
.appendLiteral(' ')
.appendValue(java.time.temporal.ChronoField.YEAR)
.toFormatter();
LocalDate date = LocalDate.of(2025, 4, 16);
String formatted = date.format(formatter);
System.out.println("Formatted date: " + formatted);
}
}
此代码创建一个格式化程序,生成类似“Wednesday, April 2025”的输出。构建器附加了日期和月份的完整文本,以及文字逗号和空格。年份作为数值附加。
基于模式的格式化
构建器可以包含类似于 SimpleDateFormat 的模式字符串。此示例展示了如何将基于模式的格式化与构建器方法相结合。我们将创建一个带有可选毫秒的格式。
package com.zetcode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
public class Main {
public static void main(String[] args) {
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd HH:mm:ss")
.optionalStart()
.appendLiteral('.')
.appendFraction(java.time.temporal.ChronoField.MILLI_OF_SECOND, 3, 3, false)
.optionalEnd()
.toFormatter();
LocalDateTime dateTime1 = LocalDateTime.of(2025, 4, 16, 14, 30, 45);
LocalDateTime dateTime2 = LocalDateTime.of(2025, 4, 16, 14, 30, 45, 500_000_000);
System.out.println("Without milliseconds: " + dateTime1.format(formatter));
System.out.println("With milliseconds: " + dateTime2.format(formatter));
}
}
此格式化程序处理带有和不带有毫秒的时间戳。optionalStart() 和 optionalEnd() 方法使毫秒部分成为可选的。小数部分格式化为精确的 3 位数字。
区域设置敏感的格式化
此示例演示了创建特定于区域设置的格式化程序。我们将构建一个格式化程序,根据指定的区域设置显示月份名称。相同的格式化程序将为不同的区域设置生成不同的输出。
package com.zetcode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendValue(java.time.temporal.ChronoField.DAY_OF_MONTH)
.appendLiteral(' ')
.appendText(java.time.temporal.ChronoField.MONTH_OF_YEAR, TextStyle.FULL)
.appendLiteral(' ')
.appendValue(java.time.temporal.ChronoField.YEAR)
.toFormatter();
LocalDate date = LocalDate.of(2025, 4, 16);
System.out.println("US format: " +
date.format(formatter.withLocale(Locale.US)));
System.out.println("French format: " +
date.format(formatter.withLocale(Locale.FRENCH)));
System.out.println("Japanese format: " +
date.format(formatter.withLocale(Locale.JAPANESE)));
}
}
输出将显示不同语言的月份名称。对于美国区域设置,它是“16 April 2025”,对于法语是“16 avril 2025”,对于日语是“16 4月 2025”。格式化程序自动适应指定的区域设置。
填充和对齐
构建器允许精确控制字段填充和对齐。此示例展示了如何创建带有填充的固定宽度数字字段。我们将使用填充到 2 位数字的时和分来格式化时间。
package com.zetcode;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
public class Main {
public static void main(String[] args) {
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendValue(java.time.temporal.ChronoField.HOUR_OF_DAY, 2)
.appendLiteral(':')
.appendValue(java.time.temporal.ChronoField.MINUTE_OF_HOUR, 2)
.toFormatter();
LocalTime time1 = LocalTime.of(9, 5);
LocalTime time2 = LocalTime.of(14, 30);
System.out.println("Time 1: " + time1.format(formatter));
System.out.println("Time 2: " + time2.format(formatter));
}
}
输出将显示诸如“09:05”和“14:30”的时间,具有一致的 2 位数字格式。appendValue 的第二个参数指定最小字段宽度,并根据需要添加填充。
复合格式化程序
此示例演示了将多个格式化程序组合成一个。我们将创建单独的日期和时间格式化程序,然后使用文字分隔符将它们组合在一起。这种方法提高了格式化程序组件的可重用性。
package com.zetcode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
.appendPattern("MMM dd, yyyy")
.toFormatter();
DateTimeFormatter timeFormatter = new DateTimeFormatterBuilder()
.appendPattern("hh:mm a")
.toFormatter();
DateTimeFormatter combinedFormatter = new DateTimeFormatterBuilder()
.append(dateFormatter)
.appendLiteral(" at ")
.append(timeFormatter)
.toFormatter();
LocalDateTime dateTime = LocalDateTime.of(2025, 4, 16, 14, 30);
System.out.println("Combined format: " + dateTime.format(combinedFormatter));
}
}
输出格式将类似于“Apr 16, 2025 at 02:30 PM”。该示例展示了如何从更简单的组件构建复杂的格式化程序。每个子格式化程序可以独立使用或与其他格式化程序组合使用。
处理不同的日历
此高级示例展示了如何为非 ISO 日历创建格式化程序。我们将为日本帝国日历系统构建一个格式化程序。该格式化程序将显示带有日本年号名称的日期。
package com.zetcode;
import java.time.LocalDate;
import java.time.chrono.JapaneseDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendText(java.time.temporal.ChronoField.ERA, TextStyle.FULL)
.appendLiteral(' ')
.appendValue(java.time.temporal.ChronoField.YEAR_OF_ERA)
.appendLiteral('年 ')
.appendText(java.time.temporal.ChronoField.MONTH_OF_YEAR, TextStyle.FULL)
.appendLiteral(' ')
.appendValue(java.time.temporal.ChronoField.DAY_OF_MONTH)
.appendLiteral('日')
.toFormatter()
.withLocale(Locale.JAPANESE);
JapaneseDate japaneseDate = JapaneseDate.from(LocalDate.of(2025, 4, 16));
System.out.println("Japanese date: " + japaneseDate.format(formatter));
}
}
输出将以带有年号名称的日语格式显示日期。对于 2025 年,这将是“令和 7年 4月 16日”。格式化程序正确处理日本日历系统,包括正确的年号命名和组件排序。
来源
Java DateTimeFormatterBuilder 文档
本教程介绍了 DateTimeFormatterBuilder 的基本功能。借助这些技术,您可以创建定制的复杂日期/时间格式化程序,以满足您的特定要求。构建器模式提供了超越标准格式化模式的灵活性。
作者
列出所有Java教程。