JDK8之前的日期api
在介绍JDK8新增的api之前,有必要先回顾下老的日期api,所谓没有对比就没有伤害,我们先用下老的api看下难不难用。
JDK8之前的api主要有3个类:Date、SimpleDateFormat、Calendar,他们的主要使用方法如下:
- Date类:
//1、演示java.util.date
System.out.println("演示Date:");
//无参构造方法,表示当前日期时间
Date date1 = new Date();
//带参构造方法,返回代表1970-1-1后经过多少毫秒的时间
Date date2 = new Date(1000);
System.out.println(date1);
System.out.println(date2);
//getTime方法 返回自1970年1月1日 00:00:00 GMT以来此Date对象表示的毫秒数
System.out.println(date1.getTime());
System.out.println(date2.getTime());
输出结果为:
- SimpleDateFormat类
//2、演示SimpleDateFormat
//创建SimpleDateFormat对象,传入格式化字符串
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//将Date对象格式化为字符串
String dateString = sdf.format(new Date());
System.out.println(dateString);
//将字符串转化为Date对象
Date date = sdf.parse("2019-5-27");
System.out.println(date);
输出结果如下:
- Calendar类
//3、演示Calendar
System.out.println("演示Calendar:");
//得到Calendar对象
Calendar calendar = Calendar.getInstance();
//利用Calendar对象得到当前时间
Date time = calendar.getTime();
System.out.println(time);
//给Calendar对象设置指定的时间
calendar.setTime(new Date(1000));
//通过Calendar对象得到各种时间信息的字段并打印
System.out.println(calendar.getTime());
System.out.println("YEAR" + ":" + calendar.get(Calendar.YEAR));//年
System.out.println("MONTH" + ":" + calendar.get(Calendar.MONTH));//月,0~11
System.out.println("DATE" + ":" + calendar.get(Calendar.DATE));//日
System.out.println("DAY_OF_MONTH" + ":" + calendar.get(Calendar.DAY_OF_MONTH));//一个月中的第几天
System.out.println("DAY_OF_WEEK" + ":" + calendar.get(Calendar.DAY_OF_WEEK));//一周中的第几天
//给字段设置指定的值
calendar.set(Calendar.YEAR,2017);//设置年份为2017
System.out.println(calendar.getTime());
calendar.add(Calendar.YEAR,2);//在2017年基础上加2年
System.out.println(calendar.getTime());
输出结果为:
JDK8新引入的日期api
相信用过老的日期api的同学都会觉得比较难用吧,它们主要存在如下问题:
- 缺失不可变性:日期类型应该类似于String类属于不可变的,而Calendar类的对象却可以通过set/add方法随意修改日期的值,这是不合理的
- 构造日期对象不符合常规习惯:应该不难发现我们在创建Date对象时非常痛苦,如果我们想自己指定一个时间,那么只有一个构造方法Date(long date)可以使用,需要传入1970年到你所要指定的时间之间所经过的毫秒值,这就很违反常理了,试想一下,如果跟别人约会,你说:“我们在1564371138883的时候见面,别迟到哦”,这会是一个多么崩溃的事。理想的状态是构造日期时传入年、月、日的值,然而类似的构造方法在Date类中均已标记为过时,需要用Calendar.set(year + 1900, month, date)代替,而该方法的年份是以1900为基准的,月份范围是0~11,也就是说如果想表示2019年7月,年份得传入119,月份得传入6,同样这也是不符合日常习惯的方式
- 格式化类型支持不全面:SimpleDateFormat只支持格式化Date,不支持Calendar。这也是很不可理解的一个地方,Calendar类是JDK1.1引入在某种程度上想代替Date类的,而SimpleDateFormat缺没有更新对它的支持,这样导致我们使用了Calendar,想格式化时还得转化为Date类,非常不方便
由于以上的种种问题,于是乎JDK8引入了新的日期api,新的api是非常成功的,基本上改进了上述缺陷。这里介绍一下新api的常用类和方法:
- 表示日期时间:LocalTime 、 LocalDate 、 LocalDateTime类,它们的使用相当简单,都可以通过now方法获取当前时间日期,通过of方法构造一个指定的时间日期,通过一系列get方法获取对象中的日期时间信息。与老的api不同,它们都是类似String的不可变对象
- LocalTime:代表时间,可以通过时、分、秒来构造
//1、演示LocalTime
System.out.println("演示LocalTime:");
//获取当前时间
LocalTime localTime = LocalTime.now();
System.out.println("LocalTime.now() " + localTime);
//构造指定时间
localTime = LocalTime.of(18,45,20);
System.out.println("LocalTime.of(hour,minute,second) " + localTime);
//获取时间对象中的小时、分钟、秒等信息
System.out.println(localTime.getHour() + ":" + localTime.getMinute() + ":" + localTime.getSecond());
输出结果如下:
- LocalDate:代表日期,可以通过年、月、日构造,并且年/月/日的值都是符合日常使用习惯的,并不会像老的api那样反人类
//2、演示LocalDate
System.out.println("演示LocalDate:");
//获取当前日期
LocalDate localDate = LocalDate.now();
System.out.println("LocalDate.now() " + localDate);
//构造指定日期
localDate = LocalDate.of(2018,5,31);
System.out.println("LocalDate.of(year,month,dayOfMonth) " + localDate);
//获取日期对象的年、月、日等信息
System.out.println(localDate.getYear() + "-" + localDate.getMonthValue() + "-" + localDate.getDayOfMonth());
输出结果如下:
- LocalDateTime:表示日期和时间,可以通过年、月、日、时、分、秒来构造,也可以通过一个LocalDate和LocalTime来构造。可以调用with、plus、minus方法来修改LocalDateTime对象,但是修改后原对象的值不变,会返回一个新的对象
//3、演示LocalDateTime
System.out.println("演示LocalDateTime:");
//获取当前日期时间
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("LocalDateTime.now() " + localDateTime);
//构造指定日期时间
localDateTime = LocalDateTime.of(2019, 5, 27, 8, 30,20);
System.out.println("LocalDate.of(year,month,dayOfMonth,hour,minute,second) " + localDateTime);
//通过LocalDate、LocalTime对象构造指定日期时间
localDateTime = LocalDateTime.of(localDate,localTime);
System.out.println("LocalDateTime.of(localDate,localTime) " + localDateTime);
//修改LocalDateTime对象的信息并返回一个新的LocalDateTime对象
LocalDateTime localDateTime1 = localDateTime.withDayOfMonth(25);
LocalDateTime localDateTime2 = localDateTime1.plusWeeks(5);
System.out.println("修改后的localDateTime:" + localDateTime);
System.out.println("修改localDateTime后得到的localDateTime1: " + localDateTime1);
System.out.println("修改localDateTime1后得到的localDateTime2: " + localDateTime2);
输出结果如下:
- 格式化:DateTimeFormatter类,它的使用也非常简单,调用静态方法ofPattern生成指定匹配格式的实例;调用实例的format方法可以将TemporalAccessor对象转换成指定格式的日期时间字符串,实际上这个TemporalAccessor是1个接口,前面介绍的LocalTime/LocalDate/LocalDateTime都间接实现了这个接口;调用实例的parse方法可以将时间日期字符串转换为TemporalAccessor对象,进而得到对应的LocalTime/LocalDate/LocalDateTime对象
//4、演示DateTimeFormatter
System.out.println("演示DateTimeFormatter");
//根据指定格式创建DateTimeFormatter对象
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
//将localDateTime对象转化为字符串
String formatString = dateTimeFormatter.format(LocalDateTime.now());
System.out.println(formatString);
//将字符串解析为LocalDate对象
TemporalAccessor temporalAccessor = dateTimeFormatter.parse("2019-07-07");
System.out.println(LocalDate.from(temporalAccessor));
输出结果如下:
- 计算日期/时间差:Duration、Period类,调用它们的静态方法between,传入2个日期或时间对象即可得到日期/时间差值
- Duration:用于计算2个LocalTime对象的时间差
//5、演示Duration
System.out.println("演示Duration");
//计算两个LocalTime的时间差
Duration duration = Duration.between(LocalTime.now(),LocalTime.of(18,20));
System.out.println("duration:" + duration);
输出结果如下:
- Period:用于计算2个LocalDate对象的日期差
//6、演示Period
System.out.println("演示Period");
//计算两个LocalDate的日期差
Period period = Period.between(LocalDate.now(),LocalDate.of(2018,9,20));
System.out.println("period:" + period);
输出结果如下:
总结
相信通过新老api的对比使用,大家一定觉得新的api用得很爽,实际开发中建议都采用新的api。本文完整测试代码参考GitHub
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/2673.html