包java.util.time
日期,时间,瞬间和持续时间的主要API。
请参阅: 说明
-
类摘要 类 描述 Clock时钟 一个时钟,使用时区提供对当前时刻,日期和时间的访问。
Duration持续时间 基于时间的时间量,例如'34.5秒'。
Instant瞬间 时间线上的瞬时点。
LocalDate ISO-8601日历系统中没有时区的日期,例如
2007-12-03
。LocalDateTime ISO-8601日历系统中没有时区的日期时间,例如
2007-12-03T10:15:30
。LocalTime ISO-8601日历系统中没有时区的时间,例如
10:15:30
。MonthDay ISO-8601日历系统中的一个月日,例如
--12-03
。OffsetDateTime ISO-8601日历系统中与UTC / Greenwich偏移的日期时间,例如
2007-12-03T10:15:30+01:00
。OffsetTime 在ISO-8601日历系统中与UTC / Greenwich偏移的时间,例如
10:15:30+01:00
。Period ISO-8601日历系统中基于日期的时间量,例如“2年,3个月和4天”。
Year ISO-8601日历系统中的一年,如
2007
。YearMonth ISO-8601日历系统中的一年中,例如
2007-12
。ZonedDateTime ISO-8601日历系统中带有时区的日期时间,例如
2007-12-03T10:15:30+01:00 Europe/Paris
。ZoneId 时区ID,例如
Europe/Paris
。ZoneOffset 与格林威治/ UTC相关的时区偏移,例如
+02:00
。 -
枚举摘要 枚举 描述 DayOfWeek 一周中的某一天,例如“星期二”。
Month 一个月,例如Month.January。
-
异常摘要 异常 描述 DateTimeException 用于表示计算日期时间问题的异常。
包java.time描述
日期,时间,瞬间和持续时间的主要API。
这里定义的类表示主要的日期 - 时间概念,包括时刻,持续时间,日期,时间,时区和时段。它们基于ISO日历系统,这是遵循公理格里高利规则的事实上的世界日历。所有类都是不可变的和线程安全的。
每个日期时间实例由API方便地提供的字段组成。对于较低级别的字段访问,请参阅java.time.temporal
包。每个类都包括对打印和解析各种日期和时间的支持。请参阅java.time.format
包以获取自定义选项。
该java.time.chrono
软件包包含日历中立API ChronoLocalDate
, ChronoLocalDateTime
, ChronoZonedDateTime
和 Era
。这适用于需要使用本地化日历的应用程序。建议应用程序使用此程序包中的ISO-8601日期和时间类跨系统边界,例如数据库或网络。应保留日历中立API以与用户进行交互。
日期和时间
Instant
本质上是一个数字时间戳。可以从a中检索当前的Instant Clock
。这对于某个时间点的日志记录和持久性非常有用,并且过去与存储结果有关System.currentTimeMillis()
。
LocalDate
只存储日期,不存储时间。这会存储类似“2010-12-03”的日期,可用于存储生日。
LocalTime
只存储时间,不存储日期。这会存储像'11:30'这样的时间,可用于存储开盘或收盘时间。
LocalDateTime
存储日期和时间。这会存储类似'2010-12-03T11:30'的日期时间。
ZonedDateTime
使用时区存储日期和时间。如果您想要考虑到日期和时间的准确计算ZoneId
,例如“欧洲/巴黎”,这非常有用。在可能的情况下,建议使用没有时区的更简单的类。时区的广泛使用往往会给应用程序增加相当大的复杂性。
持续时间和期限
除日期和时间外,API还允许存储时间段和持续时间。A Duration
是沿着时间线的简单时间度量,以纳秒为单位。A Period
表示以对人类有意义的单位的时间量,例如年或日。
其他值类型
Month
自己存储一个月。这样可以隔离单个月份,例如“DECEMBER”。
DayOfWeek
自己存储一个星期的日子。这样可以隔离存储一个星期几,例如“星期二”。
Year
自己存储一年。这样可以隔离一年,例如'2010'。
YearMonth
存储一年零一个月没有一天或一个时间。这会存储一年和一个月,例如“2010-12”,并可用于信用卡到期。
MonthDay
存储一个月和一天没有一年或一个时间。它存储月份和日期,例如“ - 12-03”,可用于存储年度活动,如生日,而不存储年份。
OffsetTime
在没有日期的情况下存储UTC的时间和偏移量。这会存储类似'11:30 + 01:00'的日期。将ZoneOffset
采用形式“+01:00”。
OffsetDateTime
存储日期和时间以及与UTC的偏移量。这将存储日期时间,如“2010-12-03T11:30 + 01:00”。有时可以在XML消息和其他形式的持久性中找到它,但包含的信息少于完整时区。
包装规格
除非另有说明,否则将null参数传递给此包中任何类或接口中的构造函数或方法将导致NullPointerException
抛出a。Javadoc“@param”定义用于概括null行为。NullPointerException
每个方法都没有明确记录“@throws ”。
所有计算都应检查数字溢出并抛出a ArithmeticException
或a DateTimeException
。
设计说明(非规范性)
API旨在尽早拒绝null,并清楚这种行为。一个关键的例外是任何获取对象并返回布尔值的方法,为了检查或验证,通常会返回false为null。
在主要的高级API中,API被设计为类型安全的。因此,对于日期,时间和日期时间的不同概念,以及偏移和时区的变体,存在单独的类。这看起来像很多类,但大多数应用程序只能以五种日期/时间类型开始。
Instant
- 时间戳LocalDate
- 没有时间的日期,或对偏移或时区的任何引用LocalTime
- 没有日期的时间,或对偏移或时区的任何引用LocalDateTime
- 结合日期和时间,但仍然没有任何偏移或时区ZonedDateTime
- “完整”日期时间,带有时区和已解决的UTC /格林威治偏移量
Instant
是最接近的等价类java.util.Date
。 ZonedDateTime
是最接近的等价类java.util.GregorianCalendar
。
应用程序应尽可能使用LocalDate
,LocalTime
并LocalDateTime
更好地建模域。例如,生日应该存储在代码中LocalDate
。请记住,任何时区的使用,例如“欧洲/巴黎”,都会给计算增加相当大的复杂性。许多应用程序只能使用LocalDate
,LocalTime
并且Instant
在用户界面(UI)层添加时区。
该基于偏移量的日期时间类型OffsetTime
和OffsetDateTime
,主要面向具有网络协议和数据库访问使用。例如,大多数数据库不能自动存储像“Europe / Paris”这样的时区,但它们可以存储像'+02:00'这样的偏移量。
还提供了一个迄今为止最重要的子部分,包括类Month
, DayOfWeek
,Year
,YearMonth
和MonthDay
。这些可用于建模更复杂的日期时间概念。例如,YearMonth
对于表示信用卡到期非常有用。
请注意,尽管有大量类表示日期的不同方面,但处理时间的不同方面的相对较少。遵循类型安全性的逻辑结论将产生小时 - 分钟,小时 - 分钟 - 秒和小时 - 分 - 秒 - 纳秒的等级。虽然逻辑上是纯粹的,但这不是一个实用的选择,因为由于日期和时间的组合,它几乎会使类的数量增加三倍。因此,LocalTime
用于所有时间精度,零用于暗示较低的精度。
遵循完全类型安全性的最终结论也可能争论在日期时间中每个字段的单独类,例如HourOfDay的类和DayOfMonth的另一个类。尝试了这种方法,但在Java语言中过于复杂,缺乏可用性。句点出现类似的问题。每个句点单元都有一个单独的类,例如“年”类型和“分钟”类型。但是,这会产生很多类和类型转换问题。因此,所提供的日期 - 时间类型集合是纯度和实用性之间的折衷。
就方法数量而言,API具有相对大的表面积。这可以通过使用一致的方法前缀来管理。
of
- 静态工厂方法,用于获取实例parse
- 静态工厂方法专注于解析get
- 获取日期中的字段is
- 用于判断:如isEqual、isBefore、isAfterwith
- 用于改变日期,设置日期plus
- 用于添加日期minus
- 用于减去日期at
- 用于添加时间,注意这里指的是时间,如:- LocalDateTime atTime = LocalDate.now().atTime(10, 25,55);
多个日历系统是设计挑战的尴尬补充。第一个原则是大多数用户想要标准的ISO日历系统。因此,主要类仅限ISO。第二个原则是大多数想要非ISO日历系统的人希望它用于用户交互,因此它是一个UI本地化问题。因此,日期和时间对象应作为ISO对象保存在数据模型和持久存储中,仅转换为本地日历以及从本地日历转换以供显示。日历系统将分别存储在用户首选项中。
但是,有一些有限的用例,用户认为他们需要在整个应用程序中的任意日历系统中存储和使用日期。这得到了支持ChronoLocalDate
,但在使用它之前阅读该接口的Javadoc中的所有相关警告至关重要。总之,需要在多个日历系统之间进行通用互操作的应用程序通常需要以与使用ISO日历的方式非常不同的方式编写,因此大多数应用程序应该只使用ISO并避免使用ChronoLocalDate
。
API也是为用户可扩展性而设计的,因为有许多计算时间的方法。该字段和单元 API,通过访问TemporalAccessor
和 Temporal
向应用程序提供相当大的灵活性。此外,这些TemporalQuery
和TemporalAdjuster
接口提供日常功能,允许代码读取接近业务需求:
LocalDate customerBirthday = customer.loadBirthdayFromDatabase();
LocalDate today = LocalDate.now();
if(customerBirthday.equals(today)){
LocalDate specialOfferExpiryDate = today.plusWeeks(2).with(next(FRIDAY));
customer.sendBirthdaySpecialOffer(specialOfferExpiryDate);
}
从java8开始:
JDK1.8