Tiago Fernandez做过一次投票,选举最烂的JAVA API,排第一的EJB2.X,第二的就是日期API。
原本的java日期API槽点太多,列举有:
1.最开始的时候,Date既要承载日期信息,又要做日期之间的转换,还要做不同日期格式的显示,职责较繁杂,违背单一原则
2.年份是从 1900 开始计算的而月份则从 0 开始
3关键的问题是可变性。参
public class Employee { private final Date startDate; public Employee(Date date) { startDate = date; } public Date getDate() { return startDate; } } 即便将 startDate 标识为 final,但返回的 java.util.Date 实例依然是可变的,这样在外面就可以通过调用 setYear() 修改雇员的起始日期。
JSR 310实际上有两个日期概念。第一个是Instant,它大致对应于java.util.Date类,因为它代表了一个确定的时间点,即相对于标准Java纪元(1970年1月1日)的偏移量;但与java.util.Date类不同的是其精确到了纳秒级别。
第二个对应于人类自身的观念,比如LocalDate和LocalTime。他们代表了一般的时区概念,要么是日期(不包含时间),要么是时间(不包含日期),类似于java.sql的表示方式。此外,还有一个MonthDay,它可以存储某人的生日(不包含年份)。每个类都在内部存储正确的数据而不是像java.util.Date那样利用午夜12点来区分日期,利用1970-01-01来表示时间。
目前Java8已经实现了JSR310的全部内容。新增了java.time包定义的类表示了日期-时间概念的规则,包括instants, durations, dates, times, time-zones and periods。这些都是基于ISO日历系统,它又是遵循 Gregorian规则的。最重要的一点是值不可变,且线程安全,通过下面一张图,我们快速看下java.time包下的一些主要的类的值的格式,方便理解。