Java 主要使用两个包java.time
和java.util
支持日期和时间特性。 包java.time
是在 Java 8 中添加的( JSR-310 ),新添加的类旨在解决传统java.util.Date
和java.util.Calendar
类的缺点。
1. 旧版日期时间 API
1.1 类
Java 8 发行之前的主要类是:
System.currentTimeMillis()
):表示自 1970 年 1 月 1 日起的当前日期和时间(以毫秒为单位)。java.util.Date
:表示特定的时间瞬间,精度为毫秒。java.util.Calendar
:一个抽象类,提供用于在实例之间进行转换并以不同的方式操纵日历字段的方法。java.text.SimpleDateFormat
:一个具体的类,用于以对语言环境敏感的方式以及任何预定义以及任何用户定义的模式来格式化和解析日期。java.util.TimeZone
:代表时区偏移量,并且还计算出夏令时。
1.2 挑战
尽管这些 API 非常适合简单的用例,但 Java 社区仍在不断抱怨有效使用这些类的问题。 因此,其他许多第三方库(例如 Joda-Time 或 Apache Commons 中的类)也更加受欢迎。
很少有挑战:
Date
类应表示日期,但也表示具有小时,分钟和秒的实例。- 但是
Date
没有任何关联的时区。 它会自动选择默认时区。 您不能将日期表示为其他时区。 - 类是可变的。 因此,这给开发人员在传递可以更改日期的函数之前克隆日期增加了负担。
- 日期格式化类也不是线程安全的。 如果没有其他同步,则无法使用格式化器实例,否则代码可能会中断。
- 出于某种原因,还有另一种
java.sql.Date
,其中包含时区信息。 - 使用其他时区创建日期非常棘手,通常会导致错误的结果。
- 它的类使用零索引数月,这是多年来应用程序中许多错误的原因。
2. Java 8 中的新日期时间 API
新的日期 api 尝试解决旧类的上述问题。 它主要包含以下类:
java.time.LocalDate
:表示 ISO 日历中的年-月-日,对于表示没有时间的日期很有用。 它可用于表示仅日期的信息,例如出生日期或结婚日期。java.time.LocalTime
:仅及时处理。 这对于表示基于人的时间(例如电影时间或本映射书馆的开放和关闭时间)很有用。java.time.LocalDateTime
:处理日期和时间,没有时区。 它是LocalDate
与LocalTime
的组合。java.time.ZonedDateTime
:将LocalDateTime
类与ZoneId
类中给出的区域信息组合在一起。 它代表完整的日期时间戳以及时区信息。java.time.OffsetTime
:处理时间与格林威治/ UTC 有相应时区偏移的时间,没有时区 ID。java.time.OffsetDateTime
:处理具有与格林威治/ UTC 相对应的时区偏移的日期和时间,没有时区 ID。java.time.Clock
:提供对任何给定时区中的当前时刻,日期和时间的访问。 尽管使用Clock
类是可选的,但是此特性使我们可以测试其他时区的代码,也可以使用时间不可变的固定时钟来测试您的代码。java.time.Instant
:表示时间轴上的纳秒的开始(自纪元开始),对于生成表示机器时间的时间戳很有用。 在纪元之前发生的瞬间具有负值,在纪元之后发生的瞬间具有正值。java.time.Duration
:两个瞬间之间的差异,以秒或纳秒为单位,并且不使用基于日期的构造,例如年,月和日,尽管该类提供了转换为天,小时和分钟的方法。java.time.Period
:以基于日期的值(年,月,日)定义日期之间的差异。java.time.ZoneId
:指定时区标识符,并提供用于在Instant
和LocalDateTime
之间进行转换的规则。java.time.ZoneOffset
:指定与格林威治/ UTC 时间的时区偏移。java.time.format.DateTimeFormatter
:提供许多预定义的格式化器,或者我们可以定义自己的格式化器。 它提供parse()
或format()
方法来解析和格式化日期时间值。
3. 常见用例
这些示例使用 Java 8 日期时间 API 中引入的新类。
3.1 获取当前日期和时间
所有日期时间类都有一个工厂方法now()
,这是在 Java 8 中获取当前日期和时间的首选方法。
LocalTime currentTime = LocalTime.now(); //13:33:43.557
LocalDate currentDate = LocalDate.now(); //2020-05-03
LocalDateTime currentDateTime = LocalDateTime.now(); //2020-05-03T13:33:43.557
3.2 解析日期和时间
日期时间类中的DateTimeFormatter
类和parse()
方法帮助完成日期解析。
String dateString = "2020-04-08 12:30";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime parsedDateTime = LocalDateTime.parse(dateString, formatter);
System.out.println(parsedDateTime); //2020-04-08T12:30
3.3 格式化日期和时间
日期格式通过日期时间类中的DateTimeFormatter
类和format()
方法来完成。
//Format a date
LocalDateTime myDateObj = LocalDateTime.now();
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
String formattedDate = myDateObj.format(myFormatObj);
System.out.println(formattedDate); // 03-05-2020 13:46
4. 更多例子
Java – 将XMLGregorianCalendar
格式设置为MM/dd/yyyy hh:mm:ss
模式
Java – 将XMLGregorianCalendar
格式化为字符串
学习愉快!