JDK1.6关于时间处理的缺点:
- 像日期和时间这样的类应该是不可变的
- Date和Calendar不是线程安全的,需要编写额外的代码处理线程安全问题
- 由于Date和Calendar的设计不当,无法完成日常的日期操作
JDK1.8解决的点:
- java.time包下所有类都是线程安全的
- 日期、时间及对比相关的对象创建完均不可修改
- 可并发解析与格式化日期与时间
- 支持设置不同的时区与历法
JDK1.8提供的API
- LocalDate,LocalTime,LocalDateTime 本地日期,本地时间,本地日期时间
- Instant 时间戳类
- Duration和Period 计算间隔
- ZoneId时区
- ZonedDateTime带时区的时间日期
- DateTimeFormatter 格式化日期的类
1.1LocalDate本地日期
本地日期,不包含具体时间, 格式 yyyy-MM-dd,不可变并且线程安全。
//JDK1.6获取当前日期
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
//JDK1.8获取当前日期
LocalDate localDate = LocalDate.now();
//自定义时间
LocalDate localDate2 = LocalDate.of(2022, 7, 22);
获取当前日期对象的具体信息
LocalDate localDate = LocalDate.now();
int year = localDate.getYear();
Month month = localDate.getMonth();
int dayOfMonth = localDate.getDayOfMonth();
int dayOfYear = localDate.getDayOfYear();
System.out.println("年 = " + year);
System.out.println("月 = " + month.getValue()); //枚举类型中的getValue()来获得信息
System.out.println("当天在这个月中第几天 = " + dayOfMonth);
System.out.println("当天在这一年中第几天= " + dayOfYear);
对日期进行年月日的加减运算
/*
plusDays()
plusWeeks()
plusMonths()
plusYears()
minusDays()
minusWeeks()
minusMonths()
minusYears()
*/
//示例:
LocalDate d1 = localDate2.plusYears(3); //增加三年
LocalDate d2 = localDate2.minusMonths(3); //减少三个月
System.out.println(d1);
System.out.println(d2);
对日期进行比较大小
//isAfter isBefore
//示例:
LocalDateTime ldt4 = LocalDateTime.now();
LocalDateTime ldt5 = ldt4.plusMinutes(10);
System.out.println("当前时间是否大于:" + ldt4.isAfter(ldt5));
1.2LocalTime本地时间
本地时间,不包含具体日期, 格式 HH:mm:ss.SSS,不可变并且线程安全。
//JDK1.6获取时间
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
//JDK1.8获取时间
LocalTime localTime = LocalTime.now();
//自定义设置时间
LocalTime localTime2 = LocalTime.of(21, 30, 59);
时间获取以及时间计算(和日期使用方式一样)
//获取时分秒
/*
getHour()
getMinute()
getSecond()
getNano()
*/
增加时分秒
/*
plusHours()
plusMinutes()
plusSeconds()
plusNanos()
minusHours()
minusMinutes()
minusSeconds()
minusNanos()
*/
//时间比较:isAfter isBefore
1.3LocalDateTime本地日期时间
组合了日期和时间, 格式 yyyy-MM-dd HH:mm:ss.SSS,不可变并且线程安全。 不包含时差和时区信息
//JDK1.6获取日期时间
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
//JDK1.8获取日期时间
LocalDateTime localDateTime = LocalDateTime.now();
//自定义设置日期时间
LocalDateTime localDateTime2 = LocalDateTime.of(2018, 11, 26, 13, 55, 36, 123);
日期时间获取以及时间计算
//获取其日期时间
/*
getYear()
getMonth()
getDayOfMonth()
getDayOfWeek()
getDayOfYear()
getHour()
getMinute()
getSecond()
getNano()
*/
//加减日期时间计算
/*
plusYears()
plusMonths()
plusDays()
plusHours()
plusMinutes()
plusSeconds()
plusNanos()
minusYears()
minusMonths()
minusDays()
minusHours()
minusMinutes()
minusSeconds()
minusNanos()
*/
//日期时间比较:isAfter isBefore
2.1Instant 时间戳类
瞬时时间,用来表示时间线上的一个点,类似new Date(),当前时间戳。
//JDK1.6中获取时间
Date date = new Date();
//JDK1.8中获取时间
Instant now = Instant.now();
//新旧方法之间的转换
date = Date.from(now);
now = date.toInstant();
获取当前时间戳。
//JDK1.6获取当前时间戳
long oldSeconds = System.currentTimeMillis();
//JDK1.8获取当前时间戳
long epochMilli = now.toEpochMilli();
//距离初始时间的秒钟数
long seconds = now.getEpochSecond();
//在当前一秒内的第几纳秒 比秒更精确的维度 JDK1.8之前无法获取纳秒
int nanos = now.getNano();
日期时间加减运算
//加减方法
/*
plusSeconds()
plusMillis()
plusNanos()
minusSeconds()
minusMillis()
minusNanos()
*/
//示例
Instant later = now.plusSeconds(30);
Instant earlier = now.minusSeconds(30);
3.1Duration计算时间间隔
计算两个时间之间的差值。
//JDK1.6中算相差秒数
long startTime = System.currentTimeMillis();
long endTime = System.currentTimeMillis();
long time = (endTime - startTime) / 1000;
//JDK1.8中加入的新功能
Instant first = Instant.now();
Thread.sleep(2000);
Instant second = Instant.now();
Duration duration = Duration.between(first, second);
System.out.println("相差" + duration.getSeconds() + "秒");
--相差2秒
//Duration计算时间差--LocalDateTime
LocalDateTime localDate = LocalDateTime.now();
LocalDateTime localDateTime = localDate.plusHours(18);
Duration duration1 = Duration.between(localDate, localDateTime);
System.out.println("相差" + duration1.toMinutes() + "分钟");
--相差1080分钟
//向上换算会舍入,失去精度
System.out.println("不足一天的话相差" + duration1.toDays() + "天");
--不足一天的话相差0天
3.2Period计算日期间隔
计算两个日期之间的差值。
//Period计算时间差--LocalDate
LocalDate localDate3 = LocalDate.now();
LocalDate localDate4 = localDate3.plusDays(5);
Period be = Period.between(localDate3,localDate4);
System.out.println("相差" + be.getDays() + "天");
--相差5天
//计算日期差,获取的值为年月日
LocalDate date = LocalDate.now();
LocalDate tenThousandDaysAgo = date.minusDays(1000);
Period period = Period.between(tenThousandDaysAgo, date);
System.out.println("一千年之前距今已相隔" + period.getYears() + "年" + period.getMonths() + "月" + period.getDays() + "日");
--一千年之前距今已相隔2年8月26日
//计算间隔天数需要改成
long dayNum = ChronoUnit.DAYS.between(localDate1, localDate3);
System.out.println("千日之前距今已相隔" + dayNum + "天");
--千日之前距今已相隔1000天
4.1ZoneId时区
时区ID
//JDK1.6获取系统默认时区
TimeZone systemTimeZone = TimeZone.getDefault();
System.out.println("JDK1.6当前时区为:" + systemTimeZone.getID());
//JDK1.8获取系统默认时区
ZoneId systemZoneId = ZoneId.systemDefault();
System.out.println("JDK1.8当前时区为:" + systemZoneId);
//对于老的时区类 TimeZone,Java 8也提供了转化方法
ZoneId oldToNewZoneId = TimeZone.getDefault().toZoneId();
设置时区
//设置时区为纽约
ZoneId shanghaiZoneId = ZoneId.of("America/New_York");
//获取所有合法的“区域/城市”字符串
Set<String> zoneIds = ZoneId.getAvailableZoneIds();
--[Asia/Aden, America/Cuiaba, Etc/GMT+9, Etc/GMT+8, Africa/Nairobi, America/Marigot, Asia/Aqtau, Pacific/Kwajalein, America/El_Salvador, Asia/Pontianak,...]
5.1ZonedDateTime带时区日期
包含时区时差的日期时间
//获取当日系统默认时区的日期
ZonedDateTime dateTime = ZonedDateTime.now();
System.out.println(dateTime);
--2022-07-25T14:16:38.398+08:00[Asia/Shanghai]
//通过时区ID 获取日期对象
ZonedDateTime dateTime2 = ZonedDateTime.now(ZoneId.of("America/New_York"));
System.out.println(dateTime2);
--2022-07-25T02:16:38.401-04:00[America/New_York]
6.1DateTimeFormatter 格式化日期的类
格式化日期的类
//JDK1.6中设置格式
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String daytemp = sdf.format(calendar.getTime());
System.out.println(daytemp);
--20220725
//JDK1.8中格式化日期
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(dateTime.format(DateTimeFormatter.BASIC_ISO_DATE));
--20220725
DateTimeFormatter类包含一系列预定义(常量)的实例
BASIC_ISO_DATE
ISO_LOCAL_DATE
ISO_LOCAL_TIME
ISO_LOCAL_DATE_TIME
ISO_OFFSET_DATE
ISO_OFFSET_TIME
ISO_OFFSET_DATE_TIME
ISO_ZONED_DATE_TIME
ISO_INSTANT
ISO_DATE
ISO_TIME
ISO_DATE_TIME
ISO_ORDINAL_TIME
ISO_WEEK_DATE
RFC_1123_DATE_TIME
自定义格式
//自定义格式
String dateTimeStr = dateTime.format(DateTimeFormatter.ofPattern("yyyy- MM-dd"));
System.out.println(dateTimeStr);
--2022-07-25
//将字符串解析为日期对象
String dateStr1 = "2022-07-22";
LocalDate dateTime1 = LocalDate.parse(dateStr1, DateTimeFormatter.ofPattern("yyyy-MM-dd"));