在Java 8中引入全新的时间和日期API,并且都是线程安全的
-
新时间日期API常用对象介绍
LocalDate: 表示没有时区的日期, LocalDate是不可变且线程安全
LocalTime: 表示没有时区的时间, LocalTime是不可变且线程安全
LocalDateTime: 表示没有时区的日期时间, LocalDateTime是不可变且线程安全
ZoneId: 时区ID,用来确定Instant和LocalDateTime互相转换的规则
Instant: 用来表示时间线上的一个点(瞬时/时间戳)
Clock: 用于访问当前时刻、日期、时间,用到时区
Duration: 用秒和纳秒表示时间的数量(长短),用于计算两个日期的“时间”间隔
Period: 用于计算两个“日期”间隔
其中,LocalDate、LocalTime、LocalDateTime是新API里的基础对象:
LocalDate : 只含年月日的日期对象
LocalTime :只含时分秒的时间对象
LocalDateTime : 同时含有年月日时分秒的日期对象
-
新时间日期API示例
(1)获取当前时间:
- now() : 静态方法,根据当前时间创建对象
LocalDate localDate = LocalDate.now(); LocalTime localTime = LocalTime.now(); LocalDateTime localDateTime = LocalDateTime.now(); System.out.println(localDate); System.out.println(localTime); System.out.println(localDateTime); /* 输出: 2019-02-23 19:23:10.865021300 2019-02-23T19:23:10.866021400 */
(2)获取当前年、月、日
LocalDate today = LocalDate.now(); int year = today.getYear(); int month = today.getMonthValue(); int day = today.getDayOfMonth(); System.out.println("年:"+year+" 月:"+month+" 日:"+day); /* 输出: 年:2019 月:2 日:23 */
(3)根据指定日期时间创建对象
- of() : 静态方法 并返回一个LocalDate实例
LocalDate localDate = LocalDate.of(2019, 2, 23); LocalTime localTime = LocalTime.of(9, 43, 20); LocalDateTime localDateTime = LocalDateTime.of(2019, 2, 23, 9, 43, 20); System.out.println(localDate); System.out.println(localTime); System.out.println(localDateTime); /* 输出: 2019-02-23 9:43:20 2019-02-23T9:43:20 */
(4)检查两个日期是否相等
LocalDate重写了equals方法来进行日期的比较
LocalDate today = LocalDate.now(); LocalDate day = LocalDate.of(2019, 2, 14); System.out.println("今天的日期是2019-02-14么?"+today.equals(day)); // 今天的日期是2019-02-14么?false
(5)判断是否闰年
LocalDate now = LocalDate.now(); System.out.println( now + "是否是闰年" + now.isLeapYear()); // 2019-02-23 是否是闰年 false
(6)获取当前时间戳
Instant类由一个静态的工厂方法now()可以返回当前时间戳
Instant instant = Instant.now(); System.out.println(instant); // 2019-02-23T12:19:53.455638400Z
可以使用这个两个类中的方法在这两个类型之间进行转换
- Date.from(Instant)就是用来把Instant转换成java.util.date
- Date.toInstant()就是将Date转换成Instant
以上获取到的是 UTC 时区的时间,与中国时间相差8小时,可以设置偏移量
Instant instant = Instant.now(); System.out.println(instant.atOffset(ZoneOffset.ofHours(8))); // 中国当前时间:2019-02-23T20:37:26.980896600+08:00
(7)两个日期之间相差多少时间 LocalDate today = LocalDate.now();
LocalDate day = LocalDate.of(2018, 2, 14); Period period = Period.between(day, today); System.out.println(period.getYears()+"-"+period.getMonths()+"-"+period.getDays()); // 两者 相差 1年-0月-9天
// 以下用来判断时间的差
LocalTime startTime = LocalTime.now();
LocalTime endTime = LocalTime.now();
System.out.println(Duration.between(startTime, endTime).toSeconds());
LocalDate startDate = LocalDate.of(1993, Month.OCTOBER, 19);
LocalDate endDate = LocalDate.of(2017, Month.JUNE, 16);
long daysDiff = ChronoUnit.DAYS.between(startDate, endDate);
System.out.println("两天之间的差在天数 : " + daysDiff);
(8)获取这个年中月有多少天
用于检查2月是否润2
YearMonth yMonth = YearMonth.now(); System.out.println("这个"+yMonth+"年月有"+yMonth.lengthOfMonth()+"天"); // 这个2019-02年月有28天
(9)使用时钟
获取某个时区下当前的瞬时时间、日期,代替System.currentTimelnMillis()与TimeZone.getDefault()方法
Clock clock = Clock.systemUTC(); System.out.println(clock); // SystemClock[Z] Clock.systemDefaultZone(); System.out.println(clock); // SystemClock[Z]
(10)判断某个日期在另一个日期的之前/之后
LocalDate today = LocalDate.now(); LocalDate tommorow = today.plus(1,ChronoUnit.DAYS); System.out.println("明天的日期:"+tommorow); System.out.println("日期:"+tommorow+"是否在日期:"+today+"之后:"+tommorow.isAfter(today)); System.out.println("日期:"+tommorow+"是否在日期:"+today+"之后:"+tommorow.isBefore(today)); //今天的日期:2019-02-23 //明天的日期:2019-02-24 //日期:2019-02-24是否在日期:2019-02-23之后:true //日期:2019-02-24是否在日期:2019-02-23之后:false
(11)时间/日期的修改
LocalDate nowDate = LocalDate.now(); System.out.println(nowDate.minusYears(1));//一年前 System.out.println(nowDate.minusMonths(1));//一月前 System.out.println(nowDate.minusWeeks(1));//一周前 System.out.println(nowDate.minusDays(1));//一天前 System.out.println(nowDate.plusYears(1));//一年后 System.out.println(nowDate.plusMonths(1));//一月后 System.out.println(nowDate.plusWeeks(1));//一周后 System.out.println(nowDate.plusDays(1));//一天后
LocalTime nowTime = LocalTime.now(); System.out.println(nowTime.minusHours(1));//一小时前 System.out.println(nowTime.minusMinutes(1));//一分钟前 System.out.println(nowTime.minusSeconds(1));//一秒前 System.out.println(nowTime.minusNanos(1));//一纳秒前 System.out.println(nowTime.plusHours(1));//一小时后 System.out.println(nowTime.plusMinutes(1));//一分钟后 System.out.println(nowTime.plusSeconds(1));//一秒后 System.out.println(nowTime.plusNanos(1));//一纳秒后
(12)时间日期格式化
LocalDateTime ldt = LocalDateTime.now(); System.out.println(ldt);//2018-09-06T18:22:47.366 DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String ldtStr = ldt.format(dtf); System.out.println(ldtStr);//2018-09-06 18:22:47 String ldtStr1 = dtf.format(ldt); System.out.println(ldtStr1);//2018-09-06 18:22:47
预定义的格式器来对日期进行解析/格式化:
String temp = "20190214"; LocalDate formatted = LocalDate.parse(temp,DateTimeFormatter.BASIC_ISO_DATE); System.out.println("格式化后的格式是:"+formatted); // 格式化后的格式是:2019-02-14
自定义解析为日期:
String str = "01 12 2014"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM dd yyyy"); LocalDate lDate = LocalDate.parse(str,formatter); System.out.println("格式化后的格式是:"+lDate); // 格式化后的格式是:2014-01-12
日期进行格式化,转换成字符串:
LocalDateTime lDateTime = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM dd yyyy HH:mm a"); String str = localDateTime.format(formatter); System.out.println("格式化后的格式是:"+str); // 2019-02-23T9:45:20 格式化后的格式是:02 23 2019 22:37 下午
OffsetDateTime类实际上包含了LocalDateTime与ZoneOffset。它用来表示一个包含格林威治时间偏移量(+/-小时:分,比如+06:00或者 -08:00)的完整的日期(年月日)及时间(时分秒,纳秒)
“MMM d yyyy”与“MMm dd yyyy”这两个日期格式也略有不同,前者能识别出"Jan 2 2019"与"Jan 14 2019"这两个串,而后者如果传进来的是"Jan 2 2014"则会报错,因为它期望月份处传进来的是两个字符。为了解决这个问题,在天为个位数的情况下,你得在前面补0,比如"Jan 2 2019"应该改为"Jan 02 2019"
DateTimeFormatter类用于在Java中进行日期的格式化与解析。与SimpleDateFormat不同,它是不可变且线程安全的
时区指的是地球上共享同一标准时间的地区。每个时区都有一个唯一标识符,同时还有一个地区/城市(Asia/Tokyo)的格式以及从格林威治时间开始的一个偏移时间。比如说,东京的偏移时间就是+09:00