ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
# Java – 日期格式 > 原文: [https://howtodoinjava.com/java/date-time/java-date-formatting/](https://howtodoinjava.com/java/date-time/java-date-formatting/) 学习在 Java 8 中将**日期格式化为字符串**。我们将学习 Java 7 中的[`DateTimeFormatter`](https://howtodoinjava.com/java/date-time/java8-datetimeformatter-example/)的*自定义模式*和`SimpleDateFormat`的*内置模式*。 ## 1\. `DateTimeFormatter` – Java 8 在 Java 8 中,我们可以将`DateTimeFormatter`用于所有类型的日期和时间相关的格式化任务。 它是[**线程安全的**](https://howtodoinjava.com/java/multi-threading/what-is-thread-safety/)或[不可变的](https://howtodoinjava.com/java/basics/how-to-make-a-java-class-immutable/) ,因此可以在并发环境中使用而没有风险。 #### 1.1 日期格式示例 Java 8 示例,以所需的字符串模式格式化`LocalDateTime`和`LocalDate`实例。 ```java import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class DateFormatting { public static void main(String[] args) { String dateTimeString = formatLocalDateTime(LocalDateTime.now()); System.out.println(dateTimeString); //2020-05-08 23:17:22 PM String dateString = formatLocalDate(LocalDate.now()); System.out.println(dateString); //2020-05-08 } //Format LocalDateTime to String public static final String TIMESTAMP_PATTERN = "yyyy-MM-dd HH:mm:ss a"; public static final DateTimeFormatter LDT_FOMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_PATTERN); private static String formatLocalDateTime(LocalDateTime ldt) { return LDT_FOMATTER.format(ldt); } //Format LocalDate to String public static final String DATE_PATTERN = "yyyy-MM-dd"; public static final DateTimeFormatter LD_FOMATTER = DateTimeFormatter.ofPattern(DATE_PATTERN); private static String formatLocalDate(LocalDate ld) { return LD_FOMATTER.format(ld); } } ``` #### 1.2 模式串 `DateTimeFormatter`提供了两种方法来定义模式: * 将近 15 种内置的**预定义模式**,例如 `ISO_LOCAL_DATE`(`2011-12-03`)或`ISO_OFFSET_DATE_TIME`(`2011-12-03T10:15:30+01:00`) * 使用`DateTimeFormatter.ofPattern(pattern)`的任何**自定义样式** 定制模式串可以具有任意数量的具有自己含义的预定义字母和符号。 最常用的符号是:`Y, M, D, h, m, s`。 另请注意,模式中字母的重复次数也具有不同的含义。 例如,`MMM`给出`Jan`,而`MMMM`给出`January`。 让我们看看这些符号以供快速参考。 | 符号 | 含义 | 类型 | 示例 | | --- | --- | --- | --- | | `G` | 时代 | `String` | `AD`;`Anno Domini` | | `y` | 时代中的一年 | `Year` | 2004 或 04 | | `u` | 时代中的一年 | `Year` | 与`y`类似,但返回年份。 | | `D` | 一年中的一天 | `Number` | 235 | | `M / L` | 一年中的一月 | `Number`/`String` | 7 或 07; `J`或`Jul`或`July` | | `d` | 一月中的一天 | `Number` | 21 | | `Q / q` | 一年中的季度 | `Number` / String | 3 或 03;`Q3`或`3rd quarter` | | `Y` | 基于周的年份 | `Year` | 1996 或 96 | | `w` | 一年中的一周 | `Number` | 32 | | `W` | 一月中的一周 | `Number` | 3 | | `e / c` | 本地化一周中的一天 | `Number`/`String` | 2 或 02;`T`或`Tue`或`Tuesday` | | `E` | 一周中的一天 | `String` | `T`或`Tue`或`Tuesday` | | `F` | 一月中的一周 | `Number` | 3 | | `a` | 一天的上午/下午 | `String` | `PM` | | `h` | 上午/下午的小时(1-12) | `Number` | 12 | | `K` | 上午/下午的小时(0-11) | `Number` | 0 | | `k` | 一天中的小时(1-24) | `Number` | 15 | | `H` | 一天中的小时(0-23) | `Number` | 15 | | `m` | 小时中的分钟 | `Number` | 30 | | `s` | 分钟中的秒钟 | `Number` | 55 | | `S` | 秒钟的小数 | `Fraction` | 978 | | `A` | 一天中的毫秒 | `Number` | 1234 | | `n` | 秒钟中的纳秒 | `Number` | 987654321 | | `N` | 一天中的纳秒 | `Number` | 1234560000 | | `V` | 时区编号 | `Zone-id` | `America/Los_Angeles` 或`Z`或`–08:30` | | `z` | 时区名称 | `Zone-name` | `Pacific Standard Time`或`PST` | | `X` | 区域偏移(`Z`代表零) | `Offset-X` | `Z`或`–08`或`–0830`或`–08:30`或`–083015`或`–08:30:15` | | `x` | 区域偏移 | `Offset-x` | `+0000`或`–08`或`–0830`或`–08:30`或`–083015`或`–08:30:15` | | `Z` | 区域偏移 | `Offset-Z` | `+0000`或`–0800`或`–08:00` | | `O` | 本地区域偏移 | `Offset-O` | `GMT+8`或`GMT+08:00`或`UTC–08:00` | | `p` | 填充 | 填充修饰符 | 1 | #### 1.3 `UnsupportedTemporalTypeException` 如果我们尝试将`DateTimeFormatter`与日期时间实例不支持的模式一起使用,则其`format()`将引发此异常。 例如,如果我们尝试使用包含小时和分钟的模式格式化`LocalDate`,则将引发此异常,因为`LocalDate`不支持任何时间信息。 ```java public static final String TIMESTAMP_PATTERN = "yyyy-MM-dd HH:mm:ss a"; public static final DateTimeFormatter FOMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_PATTERN); String formmatedString = FOMATTER.format( LocalDate.now() ); ``` ```java Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: HourOfDay at java.base/java.time.LocalDate.get0(LocalDate.java:709) at java.base/java.time.LocalDate.getLong(LocalDate.java:688) at java.base/java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:308) at java.base/java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2704) at java.base/java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2343) at java.base/java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1847) at java.base/java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1821) at com.howtodoinjava.core.datetime.DateFormatting.formatLocalDate(DateFormatting.java:33) at com.howtodoinjava.core.datetime.DateFormatting.main(DateFormatting.java:21) ``` ## 2\. `SimpleDateFormat` – Java 7 如果您仍然停留在 Java 7 上并且由于某些旧版应用程序的依赖性而无法升级,则可以使用`SimpleDateFormat`进行日期格式化。 尽管`SimpleDateFormat`不是线程安全的或不可变的,但它仍然可以很好地达到目的。 不要在具有同步功能的多线程环境中使用此类。 ```java import java.text.SimpleDateFormat; import java.util.Date; public class JavaDateValidations { public static final String TIMESTAMP_PATTERN = "yyyy-MM-dd HH:mm:ss a"; public static void main(String[] args) { SimpleDateFormat sdf = new SimpleDateFormat(TIMESTAMP_PATTERN); Date date = new Date(); String formattedDate = sdf.format(date); System.out.println(formattedDate); //2020-05-09 00:32:28 AM } } ``` ## 3\. 总结 如果您有将 Java 7 应用程序升级到 Java 8 的自由,请优先执行。 就性能而言,`DateTimeFormatter`的线程安全性和不变性是对`SimpleDateFormat`的巨大胜利。 这两个类都提供了`format()`示例,用于将日期对象格式化为字符串。 在评论中给我您有关 Java 日期格式化器示例的问题和建议。 学习愉快! [下载源码](https://github.com/lokeshgupta1981/Core-Java/tree/master/src/com/howtodoinjava/core/datetime)