Java8 时间处理类的使用实践(LocalDate...)
有了它,谁还在用Date?Calendar?
其实也不能这么绝对,毕竟还没到那个程度上。Java8 新增了处理时间的一组类(LocalDate、LocalDateTime、LocalTime),刚开始使用时觉得非常费劲,没有Calendar好用,但是真的使用之后觉得还是比较好用的啊。建议大家以后多多使用。废话少说,看代码~
1、Date与LocalDate的互转
Date转LocalDate:
Date date = new Date(); LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate 转 Date:
LocalDateTime localDateTime = LocalDateTime.now();
Date date = Date.from(localDateTime.toInstant(ZoneOffset.UTC))
显然,LocalDate和Date之间使用了Instant来转换类型,也可以使用其他的方式来转换。LocalDate.of()等等,稍微复杂的狠呢!
2、LocalDate的一些时间操作
1 DateTimeFormatter ymd = DateTimeFormatter.ofPattern("yyyy-MM-dd"); 2 //字符串转换成LocalDate类型 3 LocalDate ld = LocalDate.parse("2015-11-23", ymd); 4 System.out.println("年月日:"+ld.getYear()+"-"+ld.getMonthValue()+"-"+ld.getDayOfMonth()); 5 System.ouot.println("从1970年1月1日开始的总天数:"+ld.toEpochDay()); 6 ld = LocalDate.of(2015,11,25); 7 System.out.println("新年月日:"+ld.getYear()+"-"+ld.getMonthValue()+"-"+ld.getDayOfMonth()); 8 9 ld = ld.plusDays(1); 10 System.out.println("加一天年月日:"+ld.getYear()+"-"+ld.getMonthValue()+"-"+ld.getDayOfMonth()); 11 12 ld = ld.minusDays(2); 13 System.out.println("减两天年月日:"+ld.getYear()+"-"+ld.getMonthValue()+"-"+ld.getDayOfMonth()); 14 15 ld = ld.plusMonths(1); 16 System.out.println("加一个月年月日:"+ld.getYear()+"-"+ld.getMonthValue()+"-"+ld.getDayOfMonth()); 17 18 ld = ld.minusMonths(1); 19 System.out.println("减一个月年月日:"+ld.getYear()+"-"+ld.getMonthValue()+"-"+ld.getDayOfMonth()); 20 21 ld.plusWeeks(1);//加一星期 22 ld.plusYears(1);//加一年 23 ld.minusWeeks(1);//减一星期 24 ld.minusYears(1);//减一年
强大到我们不用去手工的计算这些东西,省事,省力,灵活性很强。
3、部分框架的支持
因为项目是Spring4+MyBatis3的,所以我只测试了这两个框架对它的支持性。
(1)Spring4 是支持LocalDate的。在spring mvc接收参数时做下格式转换:
1 @RequestMapping("/test") 2 public void method(HttpServletRequest request,HttpServletResponse response, 3 @DateTimeFormat(pattern="yyyy-MM-dd") LocalDate localDate){ 4 //接收处理逻辑 5 }
对于Spring MVC的接收参数还需要说明:如果是传入的Date类型,也需要使用注解@DateTimeFormat进行格式化,不然会报400参数错误。如果是bean对象,而且含有Date或者LocalDate类型字段,也需要添加注解@DateTimeFormat。
(2)MyBatis3 对LocalDate的支持。现阶段还是不支持的,需要我们做些处理。
方案一、修改MyBatis包源码。不到迫不得已的情况下,是不会尝试的。
方案二、增加一个Handler处理类型转换。网上找到的处理方案,亲试,完全可以。
此处只介绍方案二,大牛可以去尝试下方案一。
第一步:创建转换器
1 package com.hfms.mybatis.type; 2 3 import java.sql.CallableStatement; 4 import java.sql.PreparedStatement; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Timestamp; 8 import java.time.LocalDateTime; 9 10 import org.apache.ibatis.type.BaseTypeHandler; 11 import org.apache.ibatis.type.JdbcType; 12 import org.apache.ibatis.type.MappedTypes; 13 /** 14 *类型转换器,以LocalDateTime为例,使用LocalDate需做相应修改 15 * 16 **/ 17 @MappedTypes(LocalDateTime.class) 18 public class LocalDateTimeTypeHandler extends BaseTypeHandler<LocalDateTime> { 19 20 @Override 21 public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime parameter, JdbcType jdbcType) throws SQLException { 22 ps.setTimestamp(i, Timestamp.valueOf(parameter)); 23 } 24 25 @Override 26 public LocalDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException { 27 Timestamp date = rs.getTimestamp(columnName); 28 if (date == null) { 29 return null; 30 } else { 31 return date.toLocalDateTime(); 32 } 33 } 34 35 @Override 36 public LocalDateTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException { 37 Timestamp date = rs.getTimestamp(columnIndex); 38 if (date == null) { 39 return null; 40 } else { 41 return date.toLocalDateTime(); 42 } 43 } 44 45 @Override 46 public LocalDateTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { 47 Timestamp date = cs.getTimestamp(columnIndex); 48 if (date == null) { 49 return null; 50 } else { 51 return date.toLocalDateTime(); 52 } 53 } 54 }
第二步:在mybatis-config.xml中配置
1 <typeHandlers> 2 <package name="com.hfms.mybatis.type"/> 3 </typeHandlers>
第三步:创建对象的时候使用:
1 public class Test{ 2 LocalDateTime localDateTime; 3 }
这样在TestHandler.xml中就可以直接使用了。
未完待续~~