1. JDK8之前传统的时间API缺点
(1) 时间api设计不合理,使用不方便,很多都被淘汰了;
(2) 都是可变对象,修改之后会丢失最开始的时间信息
(3) 线程不安全(很多人一起使用同一个对象容易出bug)
(4) 只能精确到毫秒
2. JDK8之后新增的时间API优点
(1) 设计更合理,功能丰富,使用方便
(2) 都是不可变对象,修改之后会返回新的时间对象,不会丢失最开始的时间信息
(3) 线程安全
(4) 能精确到毫秒、纳秒
3. 新时间API与旧时间API
代替Calendar | LocalDate:年、月、日 LocalTime:时、分、秒 LocalDateTime:年、月、日、时、分、秒 Zoneld:时区 ZonedDateTime:带时区的时间 |
代替Date (传统的Date只能精确到毫秒,并且是可变对象;Instant精确到纳秒,不可变对象)所有推荐使用Instant代替Date | Instant:时间戳/时间线; |
代替SimpleDateFormat(线程不安全) | DateTimeFormatter:用于时间的格式化和解析 |
Duration:时间间隔(时、分、秒、纳秒) Period:时间间隔(年、月、日) |
4. LocalDate、LocalTime、LocalDateTime
(1) LocalDate:代表的是本地日期(年、月、日、星期)
常用方法:
public static void main(String[] args) {
// LocalDate
LocalDate ld = LocalDate.now();//年月日
//1. 获取日期对象中的信息
int year = ld.getYear();//年
int month = ld.getMonthValue();//月(1-12月)
int day = ld.getDayOfMonth();//日
int dayOfYear = ld.getDayOfYear();//一年当中的第几天
int dayOfWeek = ld.getDayOfWeek().getValue();//星期几
//2. 直接修改某个信息:withYear、withMonth、withDayOfMonth、withDayOfYear
LocalDate ld2 = ld.withYear(2030);
System.out.println(year);
System.out.println(ld2.getYear());
//3. 把某个信息加多少 plusYears、plusMonths、plusDays、plusWeeks
LocalDate ld3 = ld.plusYears(6);
LocalDate ld4 = ld.plusMonths(4);
LocalDate ld5 = ld.plusDays(5);
//4. 把某个信息减多少 minusYears、minusMonths、minusDays、minusWeeks
LocalDate ld6 = ld.minusYears(6);
LocalDate ld7 = ld.minusMonths(4);
LocalDate ld8 = ld.minusDays(5);
//5. 获取指定日期的LocalDate对象: public ststic LocalDate of(int year, int month, int dayOfMonth)
LocalDate ld9 = LocalDate.of(2030,1,1);
LocalDate ld10 = LocalDate.of(2040,1,1);
//6. 判断2个日期对象是否相等,equals 在前还是在后 isBefore isAfter
System.out.println(ld9.equals(ld10));//false
System.out.println(ld9.isBefore(ld10));//true
System.out.println(ld9.isAfter(ld10));//false
}
(2) LocalTime:代表的是本地时间(时、分、秒、纳秒)
常用方法:
public static void main(String[] args) {
//LocalTime
LocalTime lt = LocalTime.now();//时、分、秒、纳秒
System.out.println(lt);
//1. 获取时间对象中的信息
int hour = lt.getHour();//时
int minute = lt.getMinute();//分
int second = lt.getSecond();//秒
int nano = lt.getNano();//纳秒
//2. 直接修改某个信息:withHour、withMinute、withSecond、withNano
LocalTime lt2 = lt.withHour(10);
System.out.println(hour);
System.out.println(lt2.getHour());
//3. 把某个信息加多少 plusHours、、plusSeconds、plusNanos
LocalTime lt3 = lt.plusHours(6);
LocalTime lt4 = lt.plusMinutes(4);
LocalTime lt5 = lt.plusNanos(5);
//4. 把某个信息减多少 minusHours、minusMinutes、minusSeconds、minusNanoks
LocalTime lt6 = lt.minusHours(6);
LocalTime lt7 = lt.minusMinutes(4);
LocalTime lt8 = lt.minusSeconds(5);
//5. 获取指定时间的LocalTime对象: public ststic LocalTime of(int hour, int minute, int second)
LocalTime lt9 = LocalTime.of(9,30,26);
LocalTime lt10 = LocalTime.of(10,36,6);
//6. 判断2个时间对象是否相等,equals 在前还是在后 isBefore isAfter
System.out.println(lt9.equals(lt10));//false
System.out.println(lt9.isBefore(lt10));//true
System.out.println(lt9.isAfter(lt10));//false
}
(3) LocalDateTime:代表的是本地日期、时间(年、月、日、星期、时、分、秒、纳秒)
常用方法:
public static void main(String[] args) {
//LocalDateTime
LocalDateTime ldt = LocalDateTime.now();//年、月、日、时、分、秒、纳秒
System.out.println(ldt);
//1. 获取日期时间对象中的信息
int year = ldt.getYear();//年
int month = ldt.getMonthValue();//月
int day = ldt.getDayOfMonth();//日
int dayOfYear = ldt.getDayOfYear();//一年当中的第几天
int dayOfWeek = ldt.getDayOfWeek().getValue();//星期几
int hour = ldt.getHour();//时
int minute = ldt.getMinute();//分
int second = ldt.getSecond();//秒 当前时间的秒数 (1-60)
System.out.println(second);
int nano = ldt.getNano();//不够一秒的纳秒数
System.out.println(nano);
//2. 直接修改某个信息:withYear、withMonth、withDayOfMonth、withDayOfYear withHour、withMinute、withSecond、withNano
LocalDateTime lt2 = ldt.withHour(10);
LocalDateTime lt21 = ldt.withYear(2030);
System.out.println(hour);
System.out.println(lt2.getHour());
System.out.println(year);
System.out.println(lt21.getYear());
//3. 把某个信息加多少 plusYears、plusMonths、plusDays、plusWeeks、plusHours、、plusSeconds、plusNanos
LocalDateTime lt3 = ldt.plusYears(6);
LocalDateTime lt4 = ldt.plusMonths(4);
LocalDateTime lt5 = ldt.plusHours(5);
//4. 把某个信息减多少 minusYears、minusMonths、minusDays、minusWeeks、 minusHours、minusMinutes、minusSeconds、minusNanoks
LocalDateTime lt6 = ldt.minusYears(6);
LocalDateTime lt7 = ldt.minusMonths(4);
LocalDateTime lt8 = ldt.minusWeeks(5);
//5. 获取指定日期时间的LocalTime对象: public ststic LocalTime of(int hour, int minute, int second)
LocalDateTime lt9 = LocalDateTime.of(2030,1,1,9,30,26);
LocalDateTime lt10 = LocalDateTime.of(2040,1,1,10,36,6);
//6. 判断2个日期时间对象是否相等,equals 在前还是在后 isBefore isAfter
System.out.println(lt9.equals(lt10));//false
System.out.println(lt9.isBefore(lt10));//true
System.out.println(lt9.isAfter(lt10));//false
//7. 可以把LocalDateTime转换成LocalTime和LocalDate
//public LocalDate toLocalDate()
//public LocalTime toLocalTime()
LocalDate ld = ldt.toLocalDate();
LocalTime lt = ldt.toLocalTime();
//8.可以把LocalTime和LocalDate 直接合成LocalDateTim
// public static LocalDateTime of(LocalDate date, LocalTime time)
LocalDateTime ldt2 = LocalDateTime.of(ld,lt);
}
(4) 获取对象
方法名 | 示例 |
public static Xxx now();获取当前时间对应的对象 | LocalDate id = LocalDate.now() LocalTime it = LocalTime.now() LocalDateTime idt = LocalDateTime.now() |
5. Zoneld、ZonedDateTime
(1) Zoneld:时区Id(世界各国与地区的经度不同,各地区的时间也就有所不同,因此会划分不同的时区)-州名/城市名 或 国家名/城市名
(2) ZonedDateTime 带时区的时间(修改/获取 日期时间的方法与LocalDateTime相同)
public static void main(String[] args) {
//Zoneld ZonedDateTime
//1. Zoneld时区 的常见方法
// public static Zoneld systemDefault();获取系统默认的时区
ZoneId zone = ZoneId.systemDefault();
System.out.println(zone);//Asia/Shanghai
//public static Set<String> getAvailableZoneIds(); 获取Java支持的全部时区id
System.out.println(ZoneId.getAvailableZoneIds());
// public static ZoneId of(String zoneId); 把某个时区id封装成ZoneId对象
ZoneId zone2 = ZoneId.of("America/Panama");
System.out.println(zone2);//America/Panama
//2. ZonedDateTime 带时区的时间
// public static ZonedDateTime now(ZoneId zoneId);获取某个时区的ZonedDateTime对象
ZonedDateTime zdt = ZonedDateTime.now(zone);
System.out.println(zdt);//2024-12-20T00:03:30.981524900+08:00[Asia/Shanghai]
//时间标准时间
ZonedDateTime zdt1 = ZonedDateTime.now(Clock.systemUTC());
System.out.println(zdt1);//2024-12-19T16:05:26.459059500Z
//public static ZonedDateTime now(); 获取系统默认时区的ZonedDateTime对象
ZonedDateTime zdt2 = ZonedDateTime.now();
System.out.println(zdt2);//2024-12-20T00:04:10.401501700+08:00[Asia/Shanghai]
//修改/获取日期时间的方法与LocalDateTime相同
int year = zdt2.getYear();
ZonedDateTime zdt3 = zdt2.withHour(5);//小时修改为5
ZonedDateTime zdt4 = zdt2.plusHours(6);//小时+6
}
6. Instant
(1) Instant :时间线上的某个时刻/时间戳;通过获取Instant的对象可以拿到此刻的时间,该时间由两部分组成:从1970-01-01 00:00:00开始到此刻的总秒数 + 不够1秒的纳秒数
(2) 常用方法
常用方法名 | 说明 |
public static Instant now() | 获取当前时间的Instant对象(标准时间) |
public long getEpochSecond() | 从1970-01-01 00:00:00开始到此刻的总秒数 |
public int getNano() | 不够一秒的纳秒数 |
plusMillis()、 plusSeconds()、 plusNanos() | 增加时间系列的方法 |
minusMillis()、minusSeconds()、 minusNanos() | 减少时间系列的方法 |
equals、isBefore、isAfter | 判断系列的方法 |
public static void main(String[] args) {
//Instant
//1. public static Instant now() 获取当前时间的Instant对象(标准时间)
Instant instant = Instant.now();
System.out.println(instant); //
//2. public long getEpochSecond() 从1970-01-01 00:00:00开始到此刻的总秒数
long seconds = instant.getEpochSecond();
System.out.println(seconds);
//3. public int getNano() 不够一秒的纳秒数
int nanos = instant.getNano();
System.out.println(nanos);
//4. plusMillis()、 plusSeconds()、 plusNanos() 增加时间系列的方法
Instant instant2 = instant.plusMillis(5);//增加5分钟
Instant instant3 = instant.plusNanos(1000);//增加1000纳秒
//minusMillis()、minusSeconds()、 minusNanos() 减少时间系列的方法
Instant instant4 = instant.plusMillis(5);//减4分钟
Instant instant5 = instant.plusNanos(1000);//减1000纳秒
//equals、isBefore、isAfter 判断系列的方法
System.out.println(instant4.equals(instant2));//true
System.out.println(instant4.isBefore(instant5));//false
System.out.println(instant4.isAfter(instant5));//true
//Instant 对象的作用--做代码的性能分析或记录用户的操作时间点
Instant instant6 = Instant.now();
System.out.println(instant6);
for (int i = 0; i < 110; i++) {
System.out.println(i);
}
System.out.println(Instant.now());
}
(3) Instant 对象的作用--做代码的性能分析或记录用户的操作时间点;
(4) LocalDateTime 与 Instant:LocalDateTime不能拿到从1970-01-01 00:00:00的总秒数,只能拿到不到一秒的纳秒数;而Instant都可以拿到。
7. DateTimeFormatter
(1) DateTimeFormatter:格式化器,用于时间的格式化、解析(线程安全)
(2) DateTimeFormatter常用方法
常用方法 | 说明 |
public static DateTimeFormatter ofPattern(时间格式) | 获取格式化器对象 |
public String format(时间对象) | 格式化时间 |
(3) LocalDateTime 提供的格式化、解析时间的方法
方法 | 说明 |
public String format(DateTimeFormatter formatter) | 格式化时间 |
public static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter) | 解析时间 |
public static void main(String[] args) {
//DateTimeFormatter
//1. public static DateTimeFormatter ofPattern(时间格式) 获取格式化器对象
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
//2. public String format(时间对象) 格式化时间
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);
String format = dtf.format(ldt);//正向格式化:用格式化器去格式化时间
System.out.println(format);
//3.LocalDateTime 格式化时间 public String format(DateTimeFormatter formatter)
String s = ldt.format(dtf);//方向格式化:
System.out.println(s);
//4. LocalDateTime 解析时间 public static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter)
String s2 = "2030/01/01 12:00:00";
LocalDateTime ldt2 = LocalDateTime.parse(s2, dtf);
System.out.println(ldt2);
}
6. Period、Duration
(1) Period(一段时间):计算时间间隔(年、月、日);用于计算两个LocalDate对象的年数、月数、天数差
(2) Period常用方法
Period 常用方法名 | 说明 |
public static Period between(LocalDate start, LocalDate end) | 传入两个日期对象,得到Period对象 |
public int getYears() | 计算隔几年,并返回 |
public int getMonths() | 计算隔几月,并返回 |
public int getDays() | 计算隔几天,并返回 |
public static void main(String[] args) {
//Period
//public static Period between(LocalDate start, LocalDate end) 传入两个日期对象,得到Period对象
LocalDate ld = LocalDate.of(2024, 12, 01);
LocalDate ld2 = LocalDate.now();
Period p = Period.between(ld, ld2);
//public int getYears() 计算隔几年,并返回
int years = p.getYears();
System.out.println(years);
//public int getMonths() 计算隔几月,并返回
int months = p.getMonths();
System.out.println(months);
//public int getDays() 计算隔几天,并返回
int days = p.getDays();
System.out.println(days);
}
(3) Duration(持续时间):计算时间间隔(时、分、秒、纳秒);用于计算两个时间对象相差的天数、小时数、分钟数、秒数、纳秒数;支持LocalTime、LocalDateTime、Instant等时间对象
(4) Duration常用方法
Duration常用方法名 | 说明 |
public static Duration between(开始时间对象1, 结束时间对象2) | 传入两个时间对象,得到Duration对象 |
public long toDays() | 计算隔多少天 |
public long toHours() | 计算隔多少小时 |
public long toMinutes() | 计算隔多少分钟 |
public long toSeconds() | 计算隔多少秒 |
public long toMillis() | 计算隔多少毫秒 |
public long toNanos() | 计算隔多少纳秒 |
public static void main(String[] args) {
//Duration
//public static Duration between(开始时间对象1, 结束时间对象2) 传入两个时间对象,得到Duration对象 支持LocalTime、LocalDateTime、Instant等时间对象
LocalDateTime start = LocalDateTime.of(2024, 12, 1, 0, 0, 0);
LocalDateTime end = LocalDateTime.now();
Duration duration = Duration.between(start, end);
//public long toDays() 计算隔多少天
System.out.println(duration.toDays());
//public long toHours() 计算隔多少小时
System.out.println(duration.toHours());
//public long toMinutes() 计算隔多少分钟
System.out.println(duration.toMinutes());
//public long toSeconds() 计算隔多少秒
System.out.println(duration.toSeconds());
//public long toMillis() 计算隔多少毫秒
System.out.println(duration.toMillis());
//public long toNanos() 计算隔多少纳秒
System.out.println(duration.toNanos());
}