日期时间对象的种类很多,很多情况下这些日期时间对象都可以相互转换。为方便表述,我们把包含数据较多的对象称为“大对象”,把包含数据较少的对象称为“小对象”。例如LocalDateTime包含年、月、日、时、分、秒的数据,而LocalDate只包含年、月、日的数据,因此相较而言,LocalDate类对象是小对象,而LocalDateTime类对象则是大对象。大小的概念是相对而言的,与ZonedDateTime类对象相比,LocalDateTime类对象又成了小对象。
如果把一个小对象转换为大对象,一般都调用小对象中以at开头的方法,这些方法可以使小对象与一些数据结合起来成为一个大对象,下面的【例10_35】展示了把小对象转换为大对象的过程。
【例10_35对象的转换1】
Exam10_35.java
- import java.time.*;
- public class Exam10_35 {
- public static void main(String[] args){
- LocalDate ld = LocalDate.of(2022,2,18);
- LocalTime lt = LocalTime.of(16,35,20);
- ZoneId zid = ZoneId.of("Europe/Paris");
- LocalDateTime ldt1 = ld.atTime(14,20,35);//为ld添加时间(14点20分35秒)
- LocalDateTime ldt2 = lt.atDate(ld);//为lt添加日期
- ZonedDateTime zdt = ldt1.atZone(zid);//为ldt1添加时区
- System.out.println("ldt1:"+ldt1);
- System.out.println("ldt2:"+ldt2);
- System.out.println("zdt:"+zdt);
- }
- }
【例10_35】为一个LocalDate类对象添加了时间使之成为一个LocalDateTime对象,相应的也为一个LocalTime类对象添加了日期使之成为了一个LocalDateTime类对象,最后为一个LocalDateTime类对象添加了时区使之成为一个ZonedDateTime类对象。实际上,用于把小对象转换为大对象的以at开头的方法还有很多,本例不能一一列举,读者可以仿照本例尝试使用这些方法完成对象的转换。【例10_35】的运行结果如图10-32所示。
图10-32【例10_35】的运行结果
如果想把大对象转换为小对象,一般用以to开头的方法实现,这些方法可以去除大对象中多出的数据使之成为一个小对象。to开头的方法一般定义在大对象中,实际上,用小对象中定义的from()方法也能把大对象转换成小对象。下面的【例10_36】展示了用两种方式把大对象转换为小对象的过程。
【例10_36对象的转换2】
Exam10_36.java
- import java.time.*;
- public class Exam10_36 {
- public static void main(String[] args){
- LocalDateTime ldt = LocalDateTime.of(2022,3,18,20,45,20);
- ZoneId zid = ZoneId.of("Asia/Shanghai");
- ZonedDateTime zdt = ZonedDateTime.of(ldt,zid);
- LocalDate ld1 = ldt.toLocalDate();//把LocalDateTime类对象转换为LocalDate类对象
- LocalTime lt1 = ldt.toLocalTime();//把LocalDateTime类对象转换为LocalTime类对象
- //把ZonedDateTime类对象转换为
- OffsetDateTime odt1 = zdt.toOffsetDateTime();OffsetDateTime
- LocalDate ld2 = LocalDate.from(ldt);//把LocalDateTime类对象转换为LocalDate类对象
- LocalTime lt2 = LocalTime.from(ldt);//把LocalDateTime类对象转换为LocalTime类对象
- //把ZonedDateTime类对象转换为OffsetDateTime
- OffsetDateTime odt2 = OffsetDateTime.from(zdt);
- System.out.println("ld1:"+ld1);
- System.out.println("lt1:"+lt1);
- System.out.println("odt1:"+odt1);
- System.out.println("ld2:"+ld2);
- System.out.println("lt2:"+lt2);
- System.out.println("odt2:"+odt2);
- }
- }
【例10_36】的运行结果如图10-33所示。
图10-33【例10_36】运行结果
有时候程序员还需要把新旧日期时间系统中的对象相互转换。从JDK1.8开始,对Date和Calendar这两个类进行了一次升级,给它们都添加了一个toInstant()方法。通过这个方法就能转换出一个Instant对象。Instant这个类在整个日期时间系统中扮演着一个很重要的角色,它充当了新旧日期时间系统之间转换的桥梁。程序员可以利用转换得到的Instant对象生成一个ZoneDateTime类对象,之后再调用ZoneDateTime对象的那些以to开头的方法,就转换出Java8新日期时间系统中各种日期时间类的对象。
如果想把新日期时间系统的日期时间类对象转换成旧日期时间系统中的Date或者是Calendar类对象,也可以用Instant对象当作桥梁。具体做法是:首先调用ZonedDateTime或OffsetDateTime类的toInstant()方法转换出一个Instant对象,然后调用这个对象的toEpochMilli()方法,得到这个对象与时间原点相差的毫秒数,最后再以这个毫秒数作为参数就能构造出一个Date类的对象,而把一个Date类对象转换成Calendar类对象也很容易,只要调用Calendar类的setTime()方法就能完成这个转换操作。下面的【例10_37】展示了新旧日期时间系统日期时间类对象的相互转换过程。
【例10_37新旧日期时间系统相互转换】
Exam10_37.java
- import java.time.*;
- import java.util.*;
- public class Exam10_37 {
- public static void main(String[] args) {
- ZoneId zid = ZoneId.systemDefault();
- Date date1 = new Date(122,1,5,6,5,10);
- Instant it1 = date1.toInstant();
- //以it1为桥梁转换出ZonedDateTime类对象
- ZonedDateTime zdt1 = ZonedDateTime.ofInstant(it1,zid);
- ZonedDateTime zdt2 = ZonedDateTime.of(2022,3,15,8,25,30,0,zid);
- Instant it2 = zdt2.toInstant();
- long time = it2.toEpochMilli();//获得it2距离时间原点的毫秒数
- Date date2 = new Date(time);//以毫秒数为参数创建Date类对象
- Calendar calendar = Calendar.getInstance();
- calendar.setTime(date2);//把calendar的日期设置为date2相同
- System.out.println("date1:"+date1);
- System.out.println("date1转换为ZonedDateTime类对象:"+zdt1);
- System.out.println("zdt2:"+zdt2);
- System.out.println("zdt2转换为Date类对象:"+date2);
- }
- }
【例10_37】的运行结果如图10-34所示。
图10-34【例10_37】运行结果