相关链接
6. 旧API转换
对于老项目的改造,需要将 Date 或者 Calendar 转换为 java.time 包中相应的类。
Java8中的java.time包中没有提供太多的内置方式来转换 java.util 包中用于预处理标准日期和时间的类,我们可以使用 Instant 类作为中介,也可以使用 java.sql.Date 和 java.sql.Timestamp 类提供的方法进行转换。
6.1 java.util.Date -> java.sql.Date
java.sql.Date -> long -> java.util.Date
public static void main(String[] args) {
java.util.Date uDate = new java.util.Date();
java.sql.Date sDate = new java.sql.Date(uDate.getTime());
System.out.println(uDate);//Fri Feb 11 16:55:49 CST 2022
System.out.println(sDate);//2022-02-11
}
6.2 java.util.Date -> java.time.Instant
java.util.Date -> Instant
public static void main(String[] args) {
//初始化 java.util.Date对象
java.util.Date date = new java.util.Date();
//java.util.Date -> Instant
Instant instant = date.toInstant();
System.out.println(date);//Fri Feb 11 17:09:14 CST 2022
System.out.println(instant);//2022-02-11T09:09:14.808Z
}
6.3 java.util.Date -> java.time.LocalDate
使用 Instant 类将 java.util.Date 转换为 java.time.LocalDate。
java.time 包中并没有提供很多的方式来进行直接转换,但是给之前的 Date 类,Calendar类在Java1.8中都提供了一个新的方法,叫做toInstant,可以将当前对象转换为Instant对象,通过给Instant添加时区信息转换为 LocalDate对象。
java.util.Date -> Instant -> ZonedDateTime -> LocalDate
public static void main(String[] args) {
//初始化 java.util.Date对象
java.util.Date date = new Date();
//Step1. java.util.Date -> Instant
Instant instant = date.toInstant();
//Step2. Instant -> ZonedDateTime
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
//Step3. ZonedDateTime -> LocalDate
LocalDate localDate = zonedDateTime.toLocalDate();
System.out.println("java.util.date:" + date);//Fri Feb 11 16:30:58 CST 2022
System.out.println("localDate:" + localDate);//2022-02-11
}
6.4 java.sql.Date -> java.util.Date
java.util.Date -> long -> java.sql.Date
public static void main(String[] args) {
java.sql.Date sDate = new java.sql.Date(System.currentTimeMillis());
java.util.Date uDate = new java.util.Date(sDate.getTime());
System.out.println(sDate);//2022-02-11
System.out.println(uDate);//Fri Feb 11 17:02:21 CST 2022
}
6.5 java.sql.Date -> java.time.Instant
java.sql.Date 类中自带了转换为LocalDate的方法:toInstant,但是这个方法用了就会报错。
java.sql.Date -> LocalDate -> ZonedDateTime -> Instance
public static void main(String[] args) {
//初始化 java.sql.Date对象
java.sql.Date date = new Date(System.currentTimeMillis());
//java.sql.Date 类中自带了转换为LocalDate的方法:toInstant,但是会报错
try {
Instant instant = date.toInstant();
} catch (Exception e) {
e.printStackTrace();//java.lang.UnsupportedOperationException
}
Instant instant = date.toLocalDate().atStartOfDay(ZoneId.systemDefault()).toInstant();
System.out.println(date);//2022-02-11
System.out.println(instant);//2022-02-10T16:00:00Z
}
6.6 java.sql.Date -> java.time.LocalDate
java.sql.Date 类中自带了转换为LocalDate的方法:toLocalDate。
java.sql.Date -> LocalDate
public static void main(String[] args) {
//初始化 java.sql.Date对象
java.sql.Date date = new Date(System.currentTimeMillis());
//java.sql.Date 类中自带了转换为LocalDate的方法:toLocalDate
LocalDate localDate = date.toLocalDate();
System.out.println(date);//2022-02-11
System.out.println(localDate);//2022-02-11
}
6.7 java.sql.Timestamp -> java.time.Instant
java.sql.Timestamp -> 时间戳对象,类中自带了转换为LocalDateTime的方法:toLocalDateTime。
java.sql.Timestamp -> LocalDateTime -> Instant
public static void main(String[] args) {
//初始化 java.sql.Timestamp 对象
java.sql.Timestamp timestamp = new java.sql.Timestamp(System.currentTimeMillis());
//Step1. java.sql.Timestamp -> LocalDateTime
LocalDateTime localDateTime = timestamp.toLocalDateTime();
//Step2. LocalDateTime -> Instant
Instant instant = localDateTime.toInstant(ZoneOffset.UTC);
System.out.println(timestamp);//2022-02-11 16:46:38.4
System.out.println(instant);//2022-02-11T16:46:38.400Z
}
6.8 java.sql.Timestamp -> java.time.toLocalDate
java.sql.Timestamp -> LocalDateTime -> LocalDate
public static void main(String[] args) {
//初始化 java.sql.Timestamp 对象
java.sql.Timestamp timestamp = new java.sql.Timestamp(System.currentTimeMillis());
//java.sql.Timestamp -> LocalDate
LocalDate localDate = timestamp.toLocalDateTime().toLocalDate();
System.out.println(timestamp);//2022-02-11T16:48:31.22
System.out.println(localDate);//2022-02-11
}
6.9 java.util.Calendar -> java.time.LocalDateTime
Calendar对象可以获取到年月日时分秒的信息,这些信息可以作为LocalDateTime构造方法的参数。
注意:Calendar的月从0开始,LocaldateTime的月从1开始,转换时需要+1。
public static void main(String[] args) {
java.util.Calendar calendar = java.util.Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
LocalDateTime localDateTime = LocalDateTime.of(year, month, day, hour, minute, second);
System.out.println(calendar);//java.util.GregorianCalendar[time=1644571749708,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2022,MONTH=1,WEEK_OF_YEAR=7,WEEK_OF_MONTH=2,DAY_OF_MONTH=11,DAY_OF_YEAR=42,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=29,SECOND=9,MILLISECOND=708,ZONE_OFFSET=28800000,DST_OFFSET=0]
System.out.println(localDateTime);//2022-01-11T05:29:09
}
6.10 java.util.Calendar -> java.time.ZonedDateTime
Calendar对象自Java1.1开始提供了一个方法获取时区对象的方法,getTimeZone,要将Calendar对象转换为ZonedDateTime需要先获取到时区对象。从Java1.8开始TimeZone类提供了一个方法可以获取到ZonedId。获取到ZoneId之后就可以初始化ZonedDateTime对象了,ZonedDateTime类有一个ofInstant方法,可以将一个Instant对象和ZonedId对象作为参数传入构造ZonedDateTime对象。
此转换过程较为复杂,建议直接封装工具类。
Step1. java.util.Calendar -> java.util.TimeZone -> ZoneID
Step2. java.util.Calendar -> Instant
Step3. Instant + ZoneId -> LocalDate
public static void main(String[] args) {
//java.util.Calendar
java.util.Calendar calendar = java.util.Calendar.getInstance();
//java.util.Calendar -> java.util.TimeZone
TimeZone timeZone = calendar.getTimeZone();
//java.util.TimeZone -> ZoneId
ZoneId zoneId = timeZone.toZoneId();
//java.util.Calendar -> Instant
Instant instant = calendar.toInstant();
//Instant + ZoneId -> ZonedDateTime
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, zoneId);
System.out.println(calendar);//java.util.GregorianCalendar[time=1644571446053,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2022,MONTH=1,WEEK_OF_YEAR=7,WEEK_OF_MONTH=2,DAY_OF_MONTH=11,DAY_OF_YEAR=42,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=24,SECOND=6,MILLISECOND=53,ZONE_OFFSET=28800000,DST_OFFSET=0]
System.out.println(zonedDateTime);//2022-02-11T17:24:06.053+08:00[Asia/Shanghai]
}
22/02/11
M