JAVA8新特性(三) 清疚 2023-03-01 03:11 1阅读 0赞 ### 文章目录 ### * 日期和时间 * * LocalDate 和 LocalDateTime * 时间间隔 # 日期和时间 # java8之前我们遇到关于时间的需求,常用的几个类java.util.Date,java.util.Calendar,java.text.SimpleDateFormat等,其实这些类都有一些缺陷。比如:Date的起始年份是1900,月份从0开始,比如今天是2020年7月20日,那么通过Date创建时间 Date date = new Date(120, 6, 20); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); String format = simpleDateFormat.format(date); System.out.println(format); 结果: 2020-07-20 当然在java8中这样的方法已经被弃用了。 上面的示例中用到了SimpleDateFormat,通过此类设置日期格式,它的父类DateFormat,它也有问题,它不是线程安全的,如果有两个线程尝试使用一个format解析日期,可能会得到无法预期的结果。 java8出现了一些特别好用的日期和时间的类。 ## LocalDate 和 LocalDateTime ## 查看LocalDate源码会发现很多方便使用的方法 I. 获取当前日期,可以设定时区,或者使用系统默认时区 public static LocalDate now() { return now(Clock.systemDefaultZone()); } public static LocalDate now(ZoneId zone) { return now(Clock.system(zone)); } 上面提到时区,通过ZoneId类获取 //当前默认时区 ZoneId zoneId = TimeZone.getDefault().toZoneId(); System.out.println(zoneId.toString()); 结果: Asia/Shanghai //也可以设定时区 LocalDate now = LocalDate.now(ZoneId.of("Europe/Rome")); System.out.println(now.toString()); 结果: 2020-07-20 II. 创建日期,同样有两个方法重载 public static LocalDate of(int year, Month month, int dayOfMonth){...} public static LocalDate of(int year, int month, int dayOfMonth){...} 示例如下,还有一些获取日期中年月日的方法 LocalDate of = LocalDate.of(2020, Month.JULY, 20); System.out.println(of.toString()); System.out.println(of.getDayOfYear()); System.out.println(of.getDayOfMonth()); System.out.println(of.getDayOfWeek()); System.out.println(of.getYear()); System.out.println(of.getMonth().toString()); System.out.println(of.getMonthValue()); 结果: 2020-07-20 202 20 MONDAY 2020 JULY 7 方法:getDayOfYear()、getDayOfMonth()、getYear()、getMonthValue()返回int类型 方法:getDayOfWeek()返回DayOfWeek 方法:getMonth()返回Month **注意:如果创建的日期有误,编译可以通过但是执行会抛异常,例如:** LocalDate of = LocalDate.of(2020, Month.FEBRUARY, 30); System.out.println(of); 结果: Exception in thread "main" java.time.DateTimeException: Invalid date 'FEBRUARY 30' II. 获取某年第多少天的日期 public static LocalDate ofYearDay(int year, int dayOfYear){...} 示例: LocalDate localDate = LocalDate.ofYearDay(2020, 7); System.out.println(localDate.toString()); 结果: 2020-01-07 III. 根据日期格式获取日期 //默认要求日期格式为yyyy-MM-dd public static LocalDate parse(CharSequence text){...} public static LocalDate parse(CharSequence text, DateTimeFormatter formatter){...} 示例1: LocalDate parse = LocalDate.parse("2020-07-20"); System.out.println(parse.toString()); 结果: 2020-07-20 注意:parse()方法的参数日期格式必须是“yyyy-MM-dd”,否则报异常 LocalDate parse = LocalDate.parse("2020/07/20"); System.out.println(parse.toString()); 结果: Exception in thread "main" java.time.format.DateTimeParseException: Text '2020/07/20' could not be parsed at index 4 示例2: LocalDate parse1 = LocalDate.parse("20200720",DateTimeFormatter.BASIC_ISO_DATE); System.out.println(parse1); LocalDate parse2 = LocalDate.parse("2020-07-20",DateTimeFormatter.ISO_LOCAL_DATE); System.out.println(parse2); LocalDate of = LocalDate.of(2020, 7, 21); String format = of.format(DateTimeFormatter.ISO_LOCAL_DATE); System.out.println(format); String format1 = of.format(DateTimeFormatter.BASIC_ISO_DATE); System.out.println(format1); String format2 = of.format(DateTimeFormatter.ISO_WEEK_DATE); System.out.println(format2); 结果: 2020-07-20 2020-07-20 2020-07-21 20200721 2020-W30-2 IV. 判断方法 1. 判断闰年 java8以前判断某一年是不是闰年,还需要根据公式进行计算,LocalDate提供了方法可以直接判断,如果是闰年返回true,否则返回false public boolean isLeapYear() { return IsoChronology.INSTANCE.isLeapYear(year); } 1. 判断月份天数 public int lengthOfMonth(){...} 1. 判断年份天数 public int lengthOfYear(){...} V. 修改日期 将给定的一个日期修改它的年、月、日 示例: LocalDate parse = LocalDate.parse("2020-07-20"); LocalDate localDate = parse.withDayOfMonth(2); LocalDate localDate1 = parse.withDayOfYear(20); LocalDate localDate2 = parse.withMonth(8); LocalDate localDate3 = parse.withYear(2021); System.out.println(localDate3); System.out.println(localDate2); System.out.println(localDate1); System.out.println(localDate); 结果: 2021-07-20 2020-08-20 2020-01-20 2020-07-02 VI. 添加时间 LocalDate只有日期年月日,但是通过方法可以添加具体时间时分秒 public LocalDateTime atTime(LocalTime time){...} public LocalDateTime atTime(int hour, int minute){...} public LocalDateTime atTime(int hour, int minute, int second){...} public LocalDateTime atTime(int hour, int minute, int second, int nanoOfSecond){...} 示例: LocalDateTime localDateTime = parse.atTime(20, 56); System.out.println(localDateTime.toString()); 结果: 2020-07-20T20:56 VII. 日期比较 //方法返回-1,表示调用日期较小,返回正数1,表示调用日期较大 public int compareTo(ChronoLocalDate other){...} //判断日期前后 public boolean isAfter(ChronoLocalDate other){...} public boolean isBefore(ChronoLocalDate other){...} //判断日期是否相同 public boolean isEqual(ChronoLocalDate other){...} 示例: LocalDate parse = LocalDate.parse("2020-07-20"); LocalDate parse1 = LocalDate.parse("2020-07-21"); int i = parse.compareTo(parse1); System.out.println(i); 结果: -1 (即parse < parse1) LocalDateTime和LocalDate相似,区别在于LocalDate处理日期年、月、日,LocalDateTime处理的是年、月、日、时、分、秒,当然还有LocalTime用来处理时、分、秒。 ## 时间间隔 ## I. 日期间隔 java8以前如果计算两个日期之间隔间会怎么计算呢? 示例: public void ComparDay() throws ParseException { //注意必须是日期dt2大于日期dt1 String dt1 = "2016-12-23"; String dt2 = "2017-1-24"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date date1 = simpleDateFormat.parse(dt1); Date date2 = simpleDateFormat.parse(dt2); Calendar cal1 = Calendar.getInstance(); cal1.setTime(date1); Calendar cal2 = Calendar.getInstance(); cal2.setTime(date2); int day1= cal1.get(Calendar.DAY_OF_YEAR); int day2 = cal2.get(Calendar.DAY_OF_YEAR); int year1 = cal1.get(Calendar.YEAR); int year2 = cal2.get(Calendar.YEAR); if(year1 != year2) //不同一年 { int timeDistance = 0 ; for(int i = year1 ; i < year2 ; i ++) { if(i%4==0 && i%100!=0 || i%400==0) //闰年 { timeDistance += 366; } else //不是闰年 { timeDistance += 365; } } System.out.println("判断day2 - day1 : "+ (timeDistance + (day2-day1))); } else //同年 { System.out.println("判断day2 - day1 : " + (day2-day1)); } } 结果: 判断day2 - day1 : 32 如果使用java8提供的新的方式怎么计算呢? 示例: private static void test(){ String dt1 = "2016-12-23"; String dt2 = "2017-01-24"; LocalDate parse1 = LocalDate.parse(dt1); LocalDate parse2 = LocalDate.parse(dt2); Period between = Period.between(parse1, parse2); System.out.println("两个日期相隔:" +between.getYears() +"年"+ between.getMonths()+"月" +between.getDays() + "天"); } 结果: 两个日期相隔:0年1月1天 如果是相隔多少天怎么计算呢? java8以前,示例1: private static void test() throws ParseException { String dt1 = "2016-12-23"; String dt2 = "2017-01-24"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date parse1 = simpleDateFormat.parse(dt1); Date parse2 = simpleDateFormat.parse(dt2); long result = (parse2.getTime() - parse1.getTime()) / (24 * 3600 * 1000); System.out.println(result); } 结果: 32 java8新姿势,示例2: private static void test(){ String dt1 = "2016-12-23"; String dt2 = "2017-01-24"; LocalDate parse1 = LocalDate.parse(dt1); LocalDate parse2 = LocalDate.parse(dt2); int dayOfYear1 = parse1.getDayOfYear(); int dayOfYear2 = parse2.getDayOfYear(); if (parse1.isLeapYear()){ System.out.println(366 - dayOfYear1 + dayOfYear2); }else { System.out.println(365 - dayOfYear1 + dayOfYear2); } } 结果: 32 **注意:使用LocalDate.parse()方法,参数格式必须是“yyyy-MM-dd”,比如String dt2 = “2017-01-24”;不能写成String dt2 = “2017-1-24”;** II. 时间间隔 判断LocalDateTime之间的间隔 示例: private static void test(){ LocalDateTime startTime = LocalDateTime.of(2020, 7, 21, 20, 15, 50); LocalDateTime endTime = LocalDateTime.of(2020, 7, 22, 8, 5, 20); Duration between = Duration.between(startTime, endTime); System.out.println(between.toString()); System.out.println(between.toDays() + "天"); System.out.println(between.toHours() + "小时"); System.out.println(between.toMinutes() + "分钟"); System.out.println(between.getSeconds() + "秒"); } 结果: PT11H49M30S 0天 11小时 709分钟 42570秒 其实这个结果是个约数,真正计算机计算 42570除以60等于709.5分钟 709.5除以60等于11.825小时 III. 计算一定时长之后的日期 java8以前计算就比较麻烦了,可能需要判断是否是闰年,闰年的判断还得是一堆公式,可能需要判断哪一个月是多少天… 但是java8提供了非常便捷的方式,示例: LocalDate parse1 = LocalDate.parse("2020-07-20"); //20天以后的日期 LocalDate localDate = parse1.plusDays(20); System.out.println("20天以后日期为:"+localDate.toString()); //3个月以后的日期 LocalDate localDate1 = parse1.plusMonths(3); System.out.println("3个月以后日期为:"+localDate1.toString()); //5周以后日期 LocalDate localDate2 = parse1.plusWeeks(5); System.out.println("5周以后日期为:"+localDate2.toString()); //24年以后日期 LocalDate localDate3 = parse1.plusYears(24); System.out.println("24年以后日期为:"+localDate3.toString()); 结果: 20天以后日期为:2020-08-09 3个月以后日期为:2020-10-20 5周以后日期为:2020-08-24 24年以后日期为:2044-07-20 当然LocalDate可以计算多少天、多少月、多少年后的日期,LocalDateTime也可以,而且还能计算多少小时、多少分钟、多少秒以后的时间,示例: LocalDateTime startTime = LocalDateTime.of(2020, 7, 21, 20, 15, 50); System.out.println(startTime); LocalDateTime localDateTime = startTime.plusHours(5); System.out.println("5小时以后时间:"+localDateTime); LocalDateTime localDateTime1 = startTime.plusMinutes(10); System.out.println("10分钟以后时间:"+localDateTime1); LocalDateTime localDateTime2 = startTime.plusSeconds(70); System.out.println("70秒以后时间:"+localDateTime2); 结果: 2020-07-21T20:15:50 5小时以后时间:2020-07-22T01:15:50 10分钟以后时间:2020-07-21T20:25:50 70秒以后时间:2020-07-21T20:17 IV. 获取一些特定时间 比如,将日期调整到下个周日、下个工作日,或者是本月的最后一天。这时,你可以使用重载版本的with方法,向其传递一个提供了更多定制化选择的TemporalAdjuster对象,更加灵活地处理日期。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkxNTgwOA_size_16_color_FFFFFF_t_70] 示例: import static java.time.temporal.TemporalAdjusters.* LocalDate parse1 = LocalDate.parse("2020-07-20"); LocalDate with = parse1.with(lastDayOfMonth()); System.out.println(with); 结果: 2020-07-31 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkxNTgwOA_size_16_color_FFFFFF_t_70]: /images/20230209/5c41c87fb61e40e79b2a3b3188ba2811.png
还没有评论,来说两句吧...