如何在 Java 8 中使用 LocalDateTime 格式化/解析日期——示例教程

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(416)   2023-12-31 07:14:57

Java 项目中的一项常见任务是将日期格式化或解析为字符串,反之亦然。解析日期意味着你有一个代表日期的字符串,例如“2017-08-3”,你想把它转换成一个代表 Java 中日期的对象,例如Java 8 之前的世界中的 java.util.Date 和 Java 8 世界中的 LocalDate 或 LocalDatetime。同样,格式化日期意味着将日期实例转换为字符串,例如,您有一个 Date 对象或 LocalDatetime 对象,并且您想要一个 dd-MM-yyyy 格式的字符串。

Java 8 API 为格式化和解析日期提供了良好的支持。例如,如果您有一个日期作为字符串,例如“2017-08-3 12:30”,你想将它转换为 LocalDateTime 实例,这是 JDK 8 日期和时间 API 中的一个新类,包含日期和时间部分,你该怎么做?好吧,您可以使用 LocalDateTime 类中的 format() 和 parse() 方法来实现这一点,但您还需要一件事,即日期格式。

在 Java 8 之前,您可能知道我们使用 SimpleDateFormat 和 DateFormat 类来表示格式,这有很多问题,例如它们很重、可变且不是线程安全的,这意味着您不能共享它们,并且每次需要将 String 转换为 Date 时,您都必须创建一个新的 DateFormat 对象。尽管将 SimpleDateFormat 封装到线程局部变量中确实提供了一些喘息机会,但这还不够。

JDK 8 在新的 DateTimeFormatter 类中解决了这个问题,该类可用于定义日期和时间格式,例如“yyyy-MM-dd HH: mm”,指定格式的语法与我们之前在 SimpleDateFormat 类中使用的语法相同,但该类是线程安全且不可变的,这意味着您可以在线程之间共享其实例。理想情况下,您可以将 DateTimeFormatter 的引用存储到静态变量中以使其成为全局变量。

使用 DateTimeFormatter 的另一个优点是它提供了几个内置的格式化程序,例如java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME,可以将日期表示为“2017-08-03T10:15:30”。您可以在 Javadoc 中查看内置格式化程序的完整列表,或者您可以阅读 Java SE 8 for Really Impatient 以了解更多相关信息。

获得格式化程序后,解析或格式化日期就像调用方法一样简单。您只需要调用 LocalDateTime.parse() 方法将 String 转换为 Java 8 中的 LocalDateTime。parse() 获取一个 String 并根据 DateTimeFormatter 指定的格式解析为 LocalDateTime 实例。 parse() 方法也被重载,默认情况下它使用 ISO_LOCAL_DATE_TIME 格式,即“yyyy-MM-dd HH:mm”,即“2017-08-03T10:15:30”,但如果您的字符串采用不同的格式,则您可以指定一个单独的格式化程序。

所以,足够的理论,让我们开始真正的工作......

如何使用 LocalDateTime 格式化日期

假设您从数据库或 ISO 格式的文件中将日期作为字符串加载,例如“yyyy-MM-dd HH:mm” 并且您想将它们转换为 java.time.LocalDateTime。以下是在 Java 8 中将日期字符串解析为 LocalDateTime 的具体步骤:

1) 创建一个 DateTimeFormatter 对象

2) 使用 LocalDateTime.parse(string, formatter) 方法将 String 转换为 LocalDatetime 对象

顺便说一句,在我们的例子中日期是 ISO 格式,你不需要创建一个单独的格式化程序,你可以直接调用 parse 方法,如下例所示:

String date = "2017-03-08T12:30:54";
LocalDateTime localdatetime = LocalDateTime.parse(date);

System.out.println("origional date as string: " + date);
System.out.println("generated LocalDateTime: " + localdatetime);

Output
origional date as string: 2017-03-08T12:30:54
generated LocalDateTime: 2017-03-08T12:30:54

顺便说一句,如果您的日期字符串不是解析方法所期望的 ISO 格式,例如第二部分没有 T 或缺少分钟,然后它将抛出 DateTimeParseException。例如,如果要解析“2017-08-3 12:30”或“2017-03-08 12:30:54”,则会抛出以下异常:

线程“主”java.time.format.DateTimeParseException 中的异常:无法在 java.time.format.DateTimeFormatter.parseResolved0 的索引 10 处解析文本“2017-03-08T12:30:54” (DateTimeFormatter.java:1949) 在 java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851) 在 java.time.LocalDateTime.parse(LocalDateTime.java:492) 在 Demo.main(Demo.java:22)

为避免此错误,您可以创建一个与日期字符串匹配的 DateTimeFormatter 实例。例如,如果您的日期类似于“2017-08-3 12:30”,那么您可以创建一个 DateTimeFormatter,如下所示:

DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");

在此之后,您可以使用此格式化程序实例将 String 解析为 LocalDateTime,如以下示例所示:

String date = "2017-03-08 12:30:54";
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.parse(date, format);

System.out.println("origional date as string: " + date);
System.out.println("generated LocalDateTime: " + dateTime);

Output:
origional date as string: 2017-03-08 12:30
generated LocalDateTime: 2017-03-08T12:30

您可以看到没有更多异常,但您必须确保 date as String 必须与您在 DateTimeFormatter 实例中定义的模式匹配。由于它也是线程安全和不可变的,您甚至可以将其存储在静态变量中并在程序的另一部分之间共享。您可以在 Java SE 8 for the Really Impatient 一书中阅读有关线程安全和不变性的更多信息。

如何使用 LocalDateTime 格式化日期

在上一节中,您学习了如何解析日期,例如将日期的字符串表示形式转换为相应的对象,即 Java 8 中的 LocalDateTime。现在,让我们做相反的事情,从现有的 LocalDateTime 对象创建一个格式化的字符串,例如“dd-MM-yyyy”格式的日期。

同样,我们需要一个 DateTimeFormatter 实例来保存我们的日期模式,然后我们可以使用 LocalDateTime 类的 format() 方法来实现这一点。但是,您应该记住 format() 是一个非静态方法,您需要一个 LocalDateTime 类的实例来调用此方法。以下是在 Java 8 中使用 LocalDatetime 格式化日期的示例:

DateTimeFormatter aFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
LocalDateTime localDateTime = LocalDateTime.of(2017, Month.AUGUST, 3, 12, 30);
String foramttedString = localDateTime.format(aFormatter); // "2017-03-08 12:30"

System.out.println("origional LocalDatetime object: " + localDateTime);
System.out.println("generated string : " + foramttedString);

Output:
origional LocalDatetime object: 2017-08-03T12:30
generated string : 03-08-2017 12:30

你应该注意到我们是在对象上调用格式化方法而不是类,因为它是一个非静态方法,与静态方法 parse() 相反。您还可以看到生成的字符串确认了您的模式,即“03-08-2017 12:30”采用“dd-MM-yyyy HH:mm”格式。

在 JDK 8 中使用 LocalDateTime 格式化/解析日期的 Java 程序

这是我们的示例 Java 程序,它封装了在 Java 8 中使用 LocalDateTime 解析和格式化日期的示例。

import java.time.LocalDateTime;
import java.time.Month;
import java.time.format.DateTimeFormatter;

/*
* Java Program to parse to LocalDateTime in JDK 8. 
* We'll convert a String "2017-03-08 12:30" into LocalDateTime.
* we'll also see how to format a LocalDateTime instance to String format. 
*/
public class Demo {

public static void main(String[] args) throws Exception {

// parsing a string date to LocalDateTime
String date = "2017-03-08 12:30";
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.parse(date, format);

System.out.println("origional date as string: " + date);
System.out.println("generated LocalDateTime: " + dateTime);


//formatting a LocalDateTime to string instance
DateTimeFormatter aFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime localDateTime = LocalDateTime.of(2017, Month.AUGUST, 3, 12, 30);
String foramttedString = localDateTime.format(aFormatter); // "2017-03-08 12:30"

System.out.println("origional LocalDatetime object: " + localDateTime);
System.out.println("generated string : " + foramttedString);

// be careful, string must contain date and time portion
// if you are converting to LocalDateTime, or else, your
// code will break

LocalDateTime dateWithoutTime = LocalDateTime.parse("2017-08-03", format);
}

}

Output
origional date as string: 2017-03-08 12:30
generated LocalDateTime: 2017-03-08T12:30
origional LocalDatetime object: 2017-08-03T12:30
generated string : 2017-08-03 12:30
Exception in thread "main" java.time.format.DateTimeParseException: 
Text '2017-08-03' could not be parsed at index 10
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
at Demo.main(Demo.java:35)

要点

1) LocalDateTime.parse() 方法用于解析,它是一个静态方法,但 format() 方法不是静态的,它需要一个 LocalDateTime 实例来调用。这是 parse() 和 format() 方法之间需要注意的重要区别。例如 LocalDateTime.format(DateTimeFromatter) 在 Java 中是非法的,并给出编译时错误。

2) 您必须确保您的 String 确认您用于解析和格式化的格式,否则 parse() 和 format() 方法都会抛出 DateTimeParseException,例如“线程“main”java.time.format.DateTimeParseException 中的异常:文本‘2017-08-03’ 无法在索引 10 处解析”。

3) Java 8 中有几种内置格式可用,如果它破坏了目的,我们也应该利用它而不是创建一个新格式。

4) 由于 DateTimeFormatter 既是不可变的又是线程安全的,因此建议将其存储在静态变量中并在任何想要使用的人之间共享,但要确保该变量既是静态变量又是最终变量,以便线程可以读取它但不能分配新的对它的引用或 null,这可能会导致微妙的问题。有关更多详细信息,请参阅我关于在多线程环境中使用静态变量的危险的帖子。

以下是在 Java 8 中将日期格式化或解析为 LocalDateTime 的代码摘要:

这就是关于如何在 Java 8 中使用 LocalDateTime 格式化和解析日期。正如我所说,每个新课程,例如LocalDate、LocalTime 和 LocalDateTime 具有解析和格式化方法,可用于将字符串转换为日期,反之亦然。请记住,您需要一个 DateTimeFormatter,其模式必须与您的日期字符串匹配,否则两个 parse() 方法都会抛出 java.time.format.DateTimeParseException 错误。

您还应该记住 parse() 和 format() 方法之间的区别,前者是静态的,而后者是非静态的。您可以记住的另一件事是以静态变量的形式重用 DateTimeFormatter 实例,或者利用 JDK 中可用的几个内置格式化程序。您可以进一步阅读 Java SE 8 for Really Impatient 以了解有关 Java 8 新功能的更多信息,包括新的日期和时间 API。

您可能想探索的其他Java 8 日期和时间教程

如何比较Java中的两个日期? (教程) 如何在 Java 中获取当前时间戳值? (教程) 如何在 Java 8 中将 String 转换为 LocalDateTime? (example) 如何在JDBC中将java.util.Date转换为java.sql.Timestamp? (教程) 如何在 Java 8 中将 Date 转换为 LocalDateTime? (教程) 如何在 Java 6 中获取当前日期和时间? (教程) 如何使用 JodaTime 库将字符串解析为日期? (example) 如何在JDBC中将java.util.Date转换为java.sql.Date? (教程) 如何在 Java 8 中将字符串转换为 LocalDateTime (教程)

感谢您到目前为止阅读本文。如果您喜欢这个 Java 8 日期和时间教程以及我的技巧,请与您的朋友和同事分享。如果您有任何问题或反馈,请发表评论。

标签2: Java教程
地址:https://www.cundage.com/article/jcg-formatparse-dates-localdatetime-java-8-example-tutorial.html

相关阅读

Java HashSet 教程展示了如何使用 Java HashSet 集合。 Java哈希集 HashSet 是一个不包含重复元素的集合。此类为基本操作(添加、删除、包含和大小)提供恒定时间性...
SpringApplicationBuilder 教程展示了如何使用 SpringApplicationBuilder 创建一个简单的 Spring Boot 应用程序。 春天 是用于创建企业应...
通道是继 buffers 之后 java.nio 的第二个主要新增内容,我们在之前的教程中已经详细了解了这一点。通道提供与 I/O 服务的直接连接。 通道是一种在字节缓冲区和通道另一端的实体(通...
课程大纲 Elasticsearch 是一个基于 Lucene 的搜索引擎。它提供了一个分布式的、支持多租户的全文搜索引擎,带有 HTTP Web 界面和无模式的 JSON 文档。 Elasti...
解析器是强大的工具,使用 ANTLR 可以编写可用于多种不同语言的各种解析器。 在这个完整的教程中,我们将: 解释基础:什么是解析器,它可以用来做什么 查看如何设置 ANTLR 以便在 Java...
Java 是用于开发各种桌面应用程序、Web 应用程序和移动应用程序的最流行的编程语言之一。以下文章将帮助您快速熟悉 Java 语言,并迈向 API 和云开发等更复杂的概念。 1. Java语言...
Java中的继承是指子类继承或获取父类的所有非私有属性和行为的能力。继承是面向对象编程的四大支柱之一,用于提高层次结构中类之间的代码可重用性。 在本教程中,我们将了解 Java 支持的继承类型,...
Java Message Service 是一种支持正式通信的 API,称为 网络上计算机之间的消息传递。 JMS 为支持 Java 程序的标准消息协议和消息服务提供了一个通用接口。 JMS 提...
之前,我介绍了spring 3 + hibernate 集成 示例和struts 2 hello world 示例。在本教程中,我将讨论在将 spring 框架与 struts 与 hibern...
Java 项目中的一项常见任务是将日期格式化或解析为字符串,反之亦然。解析日期意味着你有一个代表日期的字符串,例如“2017-08-3”,你想把它转换成一个代表 Java 中日期的对象,例如Ja...