Java项目中的常见任务之一是将日期格式化或解析为String,反之亦然。 解析日期表示您有一个表示日期的字符串,例如“ 2017-08-3”,并且要将其转换为表示Java中日期的对象,例如Java 8之前版本中的java.util.Date以及LocalDate或LocalDatetime在Java 8世界中。 同样,格式化日期意味着将日期实例转换为String,例如,您有一个Date对象或LocalDatetime对象,并且您希望使用dd-MM-yyyy格式的String。

Java 8 API为格式化和解析日期提供了很好的支持。 例如,如果您有一个日期为String的日期,例如“ 2017-08-3 12:30”,并且想要将其转换为LocalDateTime实例,则该实例是JDK 8 Date and Time 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中看到内置格式化程序的完整列表,也可以阅读Really In耐心的Java SE 8以获得更多信息。

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

因此,足够的理论,让我们开始真正的工作……

如何使用LocalDateTime格式化日期

假设您要从数据库或文件中以ISO格式(例如“ yyyy-MM-dd HH:mm”)将日期作为String加载,并且要将其转换为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

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

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

为避免此错误,您可以创建一个与您的日期字符串匹配的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

您可以看到没有更多的例外,但是您必须确保日期(以字符串形式)必须与您在DateTimeFormatter实例中定义的模式匹配。 由于它也是线程安全且不可变的,因此您甚至可以将其存储在静态变量中,并在程序的另一部分之间共享。 您可以在上的新日期和时间API中阅读有关线程安全性和不变性的更多信息。
Java SE 8,用于“真正不耐烦”的书。

如何使用LocalDateTime格式化日期

在上一部分中,您学习了如何解析日期,例如,将日期的String表示形式转换为相应的对象,即Java 8中的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

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

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

这是我们的示例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:无法在索引10 ''处解析文本'2017-08-03'

3)Java 8提供了几种内置格式,如果它达到了目的,那么应该使用相同的格式,而不是创建一个新格式。

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

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

这就是Java 8中如何使用LocalDateTime格式化和解析日期的全部内容。 就像我说的那样,每个新类(例如LocalDate,LocalTime和LocalDateTime)都具有解析和格式化方法,该方法可用于将字符串转换为日期,反之亦然。 请记住,您需要一个DateTimeFormatter,其模式必须与您的日期字符串匹配,如果不匹配,则两个parse()方法都将引发java.time.format.DateTimeParseException错误。

您还应该记住parse()和format()方法之间的区别,前者是静态的,而后者是非静态的。 您要记住的另一件事是以静态变量的形式或利用JDK中提供的几种内置格式器来重用DateTimeFormatter实例。 您可以进一步阅读《真正不耐烦的Java SE 8》,以了解有关Java 8的新功能的更多信息,包括新的Date and Time API。

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

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

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

翻译自: https://www.javacodegeeks/2017/08/formatparse-dates-localdatetime-java-8-example-tutorial.html

更多推荐

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