一、历史日期API包
java.util.Date 处理日期
java.util.Calendar 处理日历
java.util.GregoiranCalendar 日历表示
java.text.SimpleDateFormat 日期时间格式化
二、历史日期API 【坑】
1、 非线程安全:java.util.Date 并不是线程安全的。开发者在使用这个类时必须自己处理多线程并发问题。
2、设计不佳 :一方面日期和日期格式化分布在多个包中。另一方面,java.util.Date 的默认日期,年竟然是从 1900 开始,月从 1 开始,日从 0 开始,没有统一性。而且 Date 类也缺少直接操作日期的相关方法。
3、 时区处理困难:因为设计不佳,开发人员不得不编写大量代码来处理时区问题。
三、Java 8 (新)日期API
Java 8 终于重新设计了所有日期时间、日历及时区相关的 API。并把它们都统一放置在 java.time 包和子包下。同时 Java 8 还针对原来复杂的 API 进行重新组合和拆分,分成了好多个类。
1、 新的日期时间 API 是线程安全的。不仅没有 setter 方法,而且任何对实例的变更都会返回一个新的实例而保证原来的实例不变。
2、 新的日期时间 API 提供了大量的方法,用于修改日期时间的各个部分,并返回一个新的实例。
3、 在时区方面,新的日期时间 API 引入了 域 ( domain ) 这个概念。
四、本地日期时间 API
Java 8 为处理本地的日期时间提供了三个LocalDate 、LocalTime 和 LocalDateTime。分别用于处理 本地日期、本地时间 和 本地日期时间,他们默认使用的是操作系统的时区。
代码范例
使用 LocalDateTime.now() 方法返回当前的日期时间:
package com.sjh.test.java8.time;
import java.time.LocalDateTime;
public class LocalDateTimeTest {
public static void main(String args[]) {
LocalDateTimeTest tester = new LocalDateTimeTest();
tester.run();
}
public void run() {
LocalDateTime currentTime = LocalDateTime.now();
System.out.println("当前日期时间: " + currentTime);
}
}
运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.time.LocalDateTimeTest
当前日期时间: 2020-06-08T20:38:52.775
Process finished with exit code 0
调用 LocalDateTime 对象的 toLocalDate() 方法和 toLocalTime() 分别返回当前的日期和当前的时间,也就是 LocalDate 和 LocalTime 两个类的实例:
package com.sjh.test.java8.time;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class LocalDateTimeTest1 {
public static void main(String args[]) {
LocalDateTimeTest1 tester = new LocalDateTimeTest1();
tester.run();
}
public void run() {
LocalDateTime currentTime = LocalDateTime.now();
System.out.println("当前日期时间: " + currentTime);
LocalDate date1 = currentTime.toLocalDate();
System.out.println("当前日期: " + date1);
LocalTime time1 = currentTime.toLocalTime();
System.out.println("当前时间: " + time1);
}
}
运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.time.LocalDateTimeTest1
当前日期时间: 2020-06-08T20:40:49.327
当前日期: 2020-06-08
当前时间: 20:40:49.327
Process finished with exit code 0
调用LocalDateTime 对象的 getMonth() 方法返回当前的月、
调用 getDayOfMonth() 返回当前的日期,调用 getSecond() 返回当前时间的秒数:
package com.sjh.test.java8.time;
import java.time.LocalDateTime;
import java.time.Month;
public class LocalDateTimeTest3 {
public static void main(String args[]) {
LocalDateTimeTest3 tester = new LocalDateTimeTest3();
tester.run();
}
public void run() {
LocalDateTime currentTime = LocalDateTime.now();
System.out.println("当前日期时间: " + currentTime);
Month month = currentTime.getMonth();
System.out.println("当前月份: " + month);
int day = currentTime.getDayOfMonth();
System.out.println("当前月中的第几天: " + day);
int seconds = currentTime.getSecond();
System.out.println("当前秒数: " + seconds);
}
}
运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.time.LocalDateTimeTest3
当前日期时间: 2020-06-08T20:42:47.518
当前月份: JUNE
当前月中的第几天: 8
当前秒数: 47
Process finished with exit code 0
调用 LocalDateTime 对象的 withDayOfMonth() 修改日并返回一个新的实例,
调用 withYear() 修改年,调用其它 with* 方法修改其它属性:
package com.sjh.test.java8.time;
import java.time.LocalDateTime;
public class LocalDateTimeTest4 {
public static void main(String args[]) {
LocalDateTimeTest4 tester = new LocalDateTimeTest4();
tester.run();
}
public void run() {
LocalDateTime currentTime = LocalDateTime.now();
System.out.println("当前日期时间: " + currentTime);
LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2019);
System.out.println("新的日期时间: " + date2);
System.out.println("原来的日期时间: " + currentTime);
}
}
运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.time.LocalDateTimeTest4
当前日期时间: 2020-06-08T20:45:19.249
新的日期时间: 2019-06-10T20:45:19.249
原来的日期时间: 2020-06-08T20:45:19.249
Process finished with exit code 0
可以发现 with 方法都是返回新的实例,而原来的实例并不会改变。
新的日期时间 API 还大量引入了 of() 方法,比如我们可以调用 LocalDate.of() 方法创建一个日期实例,调用 LocalTime.of() 方法创建一个时间实例:
package com.sjh.test.java8.time;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Month;
public class LocalDateTimeTest5 {
public static void main(String args[]) {
LocalDateTimeTest5 tester = new LocalDateTimeTest5();
tester.run();
}
public void run() {
// 2018-10-01
LocalDate date = LocalDate.of(2018, Month.OCTOBER, 01);
System.out.println("日期是: " + date);
// 22:15
LocalTime time = LocalTime.of(22, 15);
System.out.println("时间是: " + time);
}
}
运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.time.LocalDateTimeTest5
日期是: 2018-10-01
时间是: 22:15
Process finished with exit code 0
调用 LocalDateTime.parse() 、LocalDate.parse() 、 LocalTime.parse() 方法解析字符串格式的日期时间、日期和时间:
package com.sjh.test.java8.time;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class LocalDateTimeTest6 {
public static void main(String args[]) {
LocalDateTimeTest6 tester = new LocalDateTimeTest6();
tester.run();
}
public void run() {
LocalDateTime datetime = LocalDateTime.parse("2012-10-10T21:58:00");
System.out.println("日期时间是:" + datetime);
LocalDate date = LocalDate.parse("2012-10-10");
System.out.println("日期是: " + date);
LocalTime time = LocalTime.parse("21:58:01");
System.out.println("时间是: " + time);
}
}
运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.time.LocalDateTimeTest6
日期时间是:2012-10-10T21:58
日期是: 2012-10-10
时间是: 21:58:01
Process finished with exit code 0
end