JDK1.8中中使用Period和Duration类计算两个时间差,两个类不可变,线程安全。
1.1、Duration简介
Duration 用于计算两个时间间隔,最高精度为纳秒,时间量可以是整数也可以是负数。
Duration 表示一个时间段,Duration 包含两部分:seconds 表示秒,nanos 表示纳秒,它们的组合表达了时间长度。
Duration 类中不包含 now() 静态方法。注意,Duration 不包含毫秒这个属性。
Duration不能处理所有时间类,如LocalTime、LocalDateTime、ZonedDateTime,如果传入的是LocalDate,将会抛出异常
Period 是以年月日来衡量一个时间段,用于计算两个日期间隔,最高精度是天,只能接收 LocalDate 类型的参数,时间量可以是整数也可以是负数。
Period默认输出格式为PnYnMnD,如P2021Y12M3D。以P前缀开头,Y:年 M:月份 D:天,当Period为0时,默认为:P0D
public static void main(String[] args) {
Period p = Period.of(2023, 06,12);
System.out.println("输出年月日=>"+p);//P2023Y6M12D
p = Period.ofYears(1);
System.out.println("输出年=>"+p);//P1Y
p=Period.ofMonths(10);
System.out.println("输出月=>"+p);//P10M
p=Period.ofDays(30);
System.out.println("输出日=>"+p);//P30D
p = Period.ofWeeks(40);
System.out.println("输出周一年洪第多少天"+p);//P280D
Period period = Period.of(2023,06,12);
System.out.println("判断年月日是否有负值=>"+period.isNegative());//false
Period period = Period.of(2023, 4, 3);
System.out.println("年月日=>"+period);//年月日=>P2023Y4M3D
long years = period.get(ChronoUnit.YEARS);
System.out.println("year=>"+years);//year=>2023
long months = period.get(ChronoUnit.MONTHS);
System.out.println("months=>"+months);//months=>4
long days = period.get(ChronoUnit.DAYS);
System.out.println("days=>"+days);//days=>3
}
public static void main(String[] args) {
//Period计算两时间差,后面的时间减去前面的时间
Period between = Period.between(
LocalDate.of(2022, 6, 12), LocalDate.of(2023, 6, 8)); // P18D
int year = between.getYears();
System.out.println("====相差年=>"+year);//相差年=>0
int month = between.getMonths();
System.out.println("====相差月=>"+month);//相差月=>11
int day = between.getDays();
System.out.println("====相差天=>"+day);//相差天=>27
}
基于ofDays(), ofHours(), ofMillis(), ofMinutes(), ofNanos(), ofSeconds()创建Duration
public static void main(String[] args) {
//计算出一天有多少天、小时、秒、毫秒、纳秒
Duration duration= Duration.ofDays(1);
//以天为单位=>1
System.out.println("以天为单位=>"+duration.toDays());
//以小时为单位=>24
System.out.println("以小时为单位=>"+ duration.toHours());
//以分钟为单位=>1440
System.out.println("以分钟为单位=>"+duration.toMinutes());
//以秒为单位=>86400
System.out.println("以秒为单位=>"+duration.getSeconds());
//以毫秒为单位=86400000
System.out.println("以毫秒为单位="+duration.toMillis());
//以纳秒为单位=>86400000000000
System.out.println("以纳秒为单位=>"+duration.toNanos());
//获取当前时间的时间戳
long todayTimeMillis = System.currentTimeMillis();
//当前的时间戳减去一天。
long yesterdayTimeMillis = todayTimeMillis - 24 * 60 * 60 * 1000;
//通过Instant类,可以直接将毫秒值转换为Instant对象
Instant yesterday = Instant.ofEpochMilli(yesterdayTimeMillis);
Instant today = Instant.ofEpochMilli(todayTimeMillis);
Duration duration = Duration.between(yesterday, today);
System.out.println("相差天数=>"+duration.toDays()); //天数 = 1
}
static Duration between(startTime, endTime): 计算两个时间的间隔,默认是秒
boolean isNegative(): 检查结果是否出现负数
long toDays(): 输出以天为单位
long toHours(): 输出以小时为单位
long toMinutes(): 输出以分钟为单位
long toSeconds(): 输出以秒为单位
long toMillis(): 输出以毫秒为单位
long toNanos(): 输出以纳秒为单位
public static void main(String[] args) {
LocalDateTime start = LocalDateTime.parse("2023-04-26T22:50:30");
LocalDateTime end = LocalDateTime.parse("2023-04-27T23:59:50");
//用end-start
Duration duration = Duration.between(start, end);
//相差天=>1
System.out.println("相差天=>"+duration.toDays());
//相差小时=>25
System.out.println("相差小时=>"+ duration.toHours());
//相差分钟=>1509
System.out.println("相差分钟=>"+duration.toMinutes());
//相差秒=>90560
System.out.println("相差秒=>"+duration.getSeconds());
//相差毫秒=90560000
System.out.println("相差毫秒="+duration.toMillis());
//相差纳秒=>90560000000000
System.out.println("相差纳秒=>"+duration.toNanos());
//判断结果是否有负数,end早于start会得到负数
结果是否有负数=>false
System.out.println("结果是否有负数=>"+duration.isNegative());
//输出如PT25H9M20S,表示相差25小时9秒20毫秒
String timeString = duration.toString();
System.out.println("时间字符串=>"+timeString);//PT25H9M20S
}
public static void main(String[] args) {
LocalTime start = LocalTime.parse("12:00:01. 154336700");
LocalTime end = LocalTime.parse("12:01:01. 154336700");
//用end-start
Duration duration = Duration.between(start, end);
//相差小时=>0小时
System.out.println("相差小时=>"+duration.toHours()+"小时");
//相差分钟=>1分钟
System.out.println("相差分钟=>"+duration.toMinutes()+"分钟");
//相差秒=>60秒
System.out.println("相差秒=>"+duration.getSeconds()+"秒");
//toSecondOfDay():距离开始时间过去了多长时间
int startSecond=start.toSecondOfDay();
int endSecond=end.toSecondOfDay();
//相差秒=>60
System.out.println("相差秒=>"+(endSecond-startSecond));
}
public static void main(String[] args) {
LocalTime start = LocalTime.parse("12:00:01.167526700");
LocalTime end = LocalTime.parse("12:01:01.167526700");
long seconds = ChronoUnit.SECONDS.between(start , end );
long hour = ChronoUnit.HOURS.between(start , end );
long minute = ChronoUnit.MINUTES.between(start , end );
//相差秒=>60秒
System.out.println("相差秒=>"+seconds+"秒");
//相差小时=>0小时
System.out.println("相差小时=>"+hour+"小时");
//相差 =>1分钟
System.out.println("相差 =>"+minute+"分钟");
}
public static void main(String[] args) {
LocalDateTime start = LocalDateTime.now();
LocalDateTime end = LocalDateTime.of(2023, 5, 12, 0, 0, 0, 0);
System.out.println("年数=>" + ChronoUnit.YEARS.between(end,start));
System.out.println("月数=>" + ChronoUnit.MONTHS.between(end,start));
System.out.println("周数=>" + ChronoUnit.WEEKS.between(end,start));
System.out.println("天数=>" + ChronoUnit.DAYS.between(end,start));
System.out.println("时数=>" + ChronoUnit.HOURS.between(end, start));
System.out.println("分数=>" + ChronoUnit.MINUTES.between(end, start));
System.out.println("秒数=>" + ChronoUnit.SECONDS.between(end,start));
System.out.println("毫秒数=>" + ChronoUnit.MILLIS.between(end,start));
System.out.println("微秒数=>" + ChronoUnit.MICROS.between(end,start));
System.out.println("纳秒数=>" + ChronoUnit.NANOS.between(end, start));
System.out.println("半天数=>" + ChronoUnit.HALF_DAYS.between(end, start));
System.out.println("十年数=>" + ChronoUnit.DECADES.between(end,start));
System.out.println("相差的世纪有年数=>" + ChronoUnit.CENTURIES.between(end,start));
System.out.println("千年数=>" + ChronoUnit.MILLENNIA.between(end,start));
System.out.println("纪元数=>" + ChronoUnit.ERAS.between(end,start));
}
新增的API严格区分了时刻、本地日期、本地时间,并且,对日期和时间进行运算更加方便。
其次,新API的类型几乎全部是不变类型(和String的使用类似),可以放心使用不必担心被修改。
LocalDateTime是JDK1.8开始的新特性,主要的核心类有:
1、时间和日期类:LocalDateTime-获取年月日时分秒 LocalDate-年月日 LocalTime-时分秒
【2、带时区的日期和时间:ZonedDateTime】
详解地址:https://blog.csdn.net/tangshiyilang/article/details/131058869
【3、时刻:Instant是时间线上的一个瞬时点。】
Java中Date类的toInstant()方法用于将Date对象转换为Instant对象。在转换过程中会创建一个Instant,用于表示时间轴上与此日期相同的点。
【4、时区:ZoneId,ZoneOffSet】
java.time.ZoneOffset.ofHours(int hours)方法使用以小时为单位的偏移量获取 ZoneOffset 的实例
ZoneId.systemDefault():获取时区名称 输出:Asia/Shanghai
【5、时间间隔:Period,Duration】
使用详解:https://blog.csdn.net/tangshiyilang/article/details/131178453
6、Month月份
7、Week周
8、Clock: