十分详细的jdk8时间相关操作以及知识点(文章很长)

1. 前言

学习时间无非就是下面内容:

  1. 时间怎么创建
  2. 时间怎么加减
  3. 时间怎么格式化
  4. 时间怎么比大小
  5. 时间怎么求之间差值

2. 时间的创建

先总结

// 创建时间方法 有两种
// 1. 创建当前时间 now方法
LocalDate.now();
LocalTime.now();
LocalDateTime.now();
Year.now();
YearMonth.now();
MonthDay.now();

// 2. 创建具体指定的时间 of方法
LocalDate.of();
LocalTime.of();
LocalDateTime.of();
Year.of();
YearMonth.of();
MonthDay.of();

1. now方法

now方法:创建当前时间

public class createNowTime {
    public static void main(String[] args) {
        System.out.println(LocalDate.now());
        System.out.println(LocalTime.now());
        System.out.println(LocalDateTime.now());
        System.out.println("-----");
        System.out.println(Year.now());
        System.out.println(YearMonth.now());
        System.out.println(MonthDay.now());

    }
}

在这里插入图片描述

2. of方法

of方法:指定创建需求时间

public class createNowTime {
    public static void main(String[] args) {
        System.out.println(LocalTime.of(22, 0, 20, 12));
        System.out.println(LocalDate.of(2021, 1, 20));
        System.out.println("----");
        System.out.println(LocalDateTime.of(2021, 1, 20, 22, 11, 3));
        // 也可以LocalDateTime.of(LocalDateTime,LocalTime)
        System.out.println(LocalDateTime.of(LocalDate.now(), LocalTime.now()));
        System.out.println("---");
        System.out.println(Year.of(1658));
        System.out.println(YearMonth.of(2121, 5));
        System.out.println(MonthDay.of(1, 21));
    }
}

在这里插入图片描述

3. 时间的加减(plus、minus)

直接总结
这种固定时间加减自己去试一下就懂了,就不代码演示了

1. 加法
	plusNanos()
	plusSeconds()
	plusMinutes()
	plusHours()
	plusDays()
	plusWeeks()
	plusMonths()
	plusYears()
	
2. 减法
	就是将上面的plus改成minus
	或者再加法的时候传入参数为负数:如plusDays(-2) 等于减两天

时间的加减还有一点知识点:请跳到 其他知识点的Period类、ChronoUnit类查看

4. plus()使用Period类(一段时间)

  1. LocalDateTime.plus(TemporalAmount amountToAdd)
    Period类 代表一段时间的值。
    public class demo {
        public static void main(String[] args) {
            LocalDateTime now = LocalDateTime.now();
            // 求当前时间 过了1年2个月15天之后的值
            // 固然下面的方法可以,但是太过于啰嗦了
            System.out.println(now.plusYears(1).plusMonths(2).plusDays(15));
            // 因此产生了Period类,代表一段时间
            // 下面则表示1年2个月15天的一段时间
            Period period = Period.of(1, 2, 15);
            // 直接加一段时间,简单明了
            System.out.println(now.plus(period));
        }
    }
    
    在这里插入图片描述

5. plus()方法使用ChronoUnit类(枚举类 时间单位)

  1. LocalDateTime.plus(long amountToAdd, TemporalUnit unit)
    jdk8为了让时间操作更加方便,还定义了ChronoUnit枚举:
    在这里插入图片描述

    public class demo {
        public static void main(String[] args) {
            LocalDateTime now = LocalDateTime.now();
            // 当前时间
            System.out.println(now);
            // 直接加一星期
            System.out.println(now.plus(1, ChronoUnit.WEEKS));
            // 直接加10年
            System.out.println(now.plus(1, ChronoUnit.DECADES));
        }
    }
    

    在这里插入图片描述

6. 直接修改时间(不是加减方式)(with方法)

  1. 解释:比如我获取到当前时间是某月某号,但是我想直接获取这个月1号,如果是加减则需要知道到底现在几号,然后减,有点麻烦,因此产生了 直接修改时间方法(with方法)
    在这里插入图片描述

  2. 代码例子:

    public class demo {
        public static void main(String[] args) {
            LocalDateTime now = LocalDateTime.now();
            // 当前时间
            System.out.println(now);
            // 直接修改 当前月15号
            System.out.println(now.withDayOfMonth(15));
            // 直接修改 今天8点
            System.out.println(now.withHour(8));
            // 直接修改 今年6月
            System.out.println(now.withMonth(Month.JUNE.getValue()));
        }
    }
    

    在这里插入图片描述

7. with()方法使用chronoField类(枚举类)

  1. 其代表 就是 月中的天数,一周的天数等等类似枚举
    在这里插入图片描述

  2. LocalDateTime.with(TemporalField field, long newValue)(使用枚举类,修改时间)

    public class demo {
        public static void main(String[] args) {
            LocalDateTime now = LocalDateTime.now();
            // 当前时间 星期四
            System.out.println(now);
            // 直接修改时间为:这周星期二
            System.out.println(now.with(ChronoField.DAY_OF_WEEK, 2));
            // 直接修改时间为:今年第10天
            System.out.println(now.with(ChronoField.DAY_OF_YEAR, 10));
        }
    }
    

    在这里插入图片描述

8. with()方法配合使用调节器TemporalAdjuster

  1. 有时候我们还需要更加复杂的改变当前时间,比如改为当前时间的下个月,下个星期什么什么,针对的是下一月,而不是当前月,

  2. 上面的with方法已经无法满足这个需求了,除非先让当前时间plus到下个月,然后再使用with方法,这样子你还要判到底是加30天还是31天,实在繁琐,因此出现了调节器TemporalAdjuster。

  3. with中有个方法是with(TemporalAdjuster temporalAdjuster),而jdk本身就自带了一些返回调节器的方法,在TemporalAdjusters中
    在这里插入图片描述

  4. 代码:

    public class demo {
        public static void main(String[] args) {
            final LocalDateTime nowTime = LocalDateTime.now();
            System.out.println("当前时间:" + nowTime);
            System.out.println("-----previous/next方法");
            // previous(DayOfWeek) :上个星期几
            System.out.println("上个星期天的时间: " + nowTime.with(TemporalAdjusters.previous(DayOfWeek.SUNDAY)));
            // next(DayOfWeek) :下个星期几
            System.out.println("下个星期天的时间: " + nowTime.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)));
            // nextOrSame(DayOfWeek.SUNDAY)
            // 今天是星期六,而这周的星期天还没有过,因此会返回这周的星期天
            // 若这周星期天已经过了,则会直接返回下个星期天的时间
            System.out.println("下个星期天的时间: " + nowTime.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)));
            System.out.println("----");
            System.out.println("下个月第一天的时间: " + nowTime.with(TemporalAdjusters.firstDayOfNextMonth()));
            System.out.println("下一年第一天的时间: " + nowTime.with(TemporalAdjusters.firstDayOfNextYear()));
            System.out.println("这个月最后一天的时间: " + nowTime.with(TemporalAdjusters.lastDayOfMonth()));
            System.out.println("今年最后一天: " + nowTime.with(TemporalAdjusters.lastDayOfYear()));
            
        }
    }
    
    

    在这里插入图片描述

9. with()使用自定义的调节器TemporalAdjuster

  1. 需求:每个月15号下午5点发工资,若15号是周六周日,则星期五发工资,现求输入指定时间,求当月实际发工资时间。

  2. 这个时候jdk自带的调节器无法帮助我们完成该任务,则需要我们自己定义调节器:

    public class demo {
        public static void main(String[] args) {
            final LocalDateTime nowTime = LocalDateTime.now();
            System.out.println(nowTime.with(new TemporalAdjuster() {
                @Override
                public Temporal adjustInto(Temporal temporal) {
                    LocalDate localDate = LocalDate.from(temporal);
                    LocalDateTime localDateTime = LocalDateTime.of(localDate, LocalTime.of(17, 0, 0));
                    localDateTime = localDateTime.with(ChronoField.DAY_OF_MONTH, 15);
    //                localDateTime = localDateTime.withDayOfMonth(15);
                    if(localDateTime.getDayOfWeek() == DayOfWeek.SUNDAY || localDateTime.getDayOfWeek() == DayOfWeek.SATURDAY){
                        localDateTime = localDateTime.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY));
                    }
                    return localDateTime;
                }
            }));
    
        }
    }
    

    在这里插入图片描述

10. 两个时间怎么比较大小以及求差值

1. 比较大小(isAfter()、isBefore())

  1. A.isAfter(B):判断A是否在B的后面,即A时间是否比B时间晚

  2. A.isBefore(B):判断A是否在B的前面,即A时间是否比B时间早

  3. 代码:

    public class demo {
        public static void main(String[] args) {
            final LocalDateTime nowTime = LocalDateTime.now();
            // 模拟 两周前的时间
            final LocalDateTime oldTime = nowTime.plus(-2, ChronoUnit.WEEKS);
            System.out.println("nowTime: " + nowTime);
            System.out.println("oldTime: " + oldTime);
            // 当前时间 是否在oldTime 后面
            System.out.println("isAfter: " + nowTime.isAfter(oldTime));
            // 当前时间 是否在oldTime 前面
            System.out.println("isBefore: " + nowTime.isBefore(oldTime));
        }
    }
    

    在这里插入图片描述

2. 两个时间之间求差值(ChronoUnit的between()方法)

  1. ChronoUnit是个时间单位枚举类:
    在这里插入图片描述

  2. 但是每个枚举后面都可以跟方法 between(A,B),表示A到B两个时间之间的差值时间戳(有正负之分),并转化为枚举的时间单位:

    public class demo {
        public static void main(String[] args) {
            final LocalDateTime nowTime = LocalDateTime.now();
            // 模拟 两周前的时间
            final LocalDateTime oldTime = nowTime.plus(-2, ChronoUnit.WEEKS);
            System.out.println("nowTime: " + nowTime);
            System.out.println("oldTime: " + oldTime);
            System.out.println("--");
            System.out.println("nowTime到oldTime之间相差的多少天: " + ChronoUnit.DAYS.between(nowTime, oldTime));
            System.out.println("oldTime到nowTime之间相差的多少天: " + ChronoUnit.DAYS.between(oldTime, nowTime));
            System.out.println("---");
            System.out.println("oldTime到nowTime之间相差的多少周: " + ChronoUnit.WEEKS.between(oldTime, nowTime));
            System.out.println("oldTime到nowTime之间相差的多少秒: " + ChronoUnit.SECONDS.between(oldTime, nowTime));
            System.out.println("oldTime到nowTime之间相差的多少分钟: " + ChronoUnit.MINUTES.between(oldTime, nowTime));
            System.out.println("oldTime到nowTime之间相差的多少小时: " + ChronoUnit.HOURS.between(oldTime, nowTime));
        }
    }
    

    在这里插入图片描述

3. 使用query(TemporalAccessor)计算时间差

  1. 需求:计算到5月1号还有多久?

  2. TemporalAccessor 是个接口,方法queryFrom

  3. 代码:

    public class demo {
        public static void main(String[] args) {
            final LocalDateTime nowTime = LocalDateTime.of(2021,10,1, 0,0 , 0);
            System.out.println("当前时间:" + nowTime + " ,距离5月1号还有:" + nowTime.query(new TemporalQuery<Object>() {
                @Override
                public Object queryFrom(TemporalAccessor temporal) {
                    LocalDate nowLocalDate = LocalDate.from(temporal);
                    // 获取当前时间的今年的 5.1 号
                    LocalDate laborDay = LocalDate.of(nowLocalDate.getYear(), Month.MAY, 1);
                    // 判断nowLocalDate是否过了今年的5月1号
                    // 若过了,则需要判断它到下一年的5月1号的时间差
                    // 因此需要在laborDay 加一年
                    if (nowLocalDate.isAfter(laborDay)) {
                        laborDay = laborDay.plusYears(1);
                    }
                    return ChronoUnit.DAYS.between(nowLocalDate, laborDay);
    
                }
            }));
    
        }
    }
    

    在这里插入图片描述

11. DateTimeFormatter 时间格式化(重点)

1. TimeToString(时间转String格式)

public class demo {
    private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm-ss.SSS");

    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        // 当前时间
        System.out.println(now);
        final String format = now.format(DATETIME_FORMATTER);
        System.out.println(format);
    }
}

在这里插入图片描述

2. StringToTime(String转时间)

public class demo {
    private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm-ss.SSS");

    public static void main(String[] args) {
        String time = "2022-01-20 23-26-54.540";
        System.out.println(LocalDateTime.parse(time, DATETIME_FORMATTER));

    }
}

在这里插入图片描述

2. jdk自带格式转化模式

1. DateTimeFormatter自带枚举属性

public class demo {
    public static void main(String[] args) {
        final LocalDateTime now = LocalDateTime.now();
        System.out.println("当前时间:" + now);
        System.out.println("格式化时间:");
        final String date_format = now.format(DateTimeFormatter.ISO_DATE);
        System.out.println(date_format);
        final String data_time_format2 = now.format(DateTimeFormatter.ISO_DATE_TIME);
        System.out.println(data_time_format2);

        System.out.println("恢复:");
        System.out.println(LocalDate.parse(date_format));
        System.out.println(LocalDateTime.parse(data_time_format2));
    }
}

在这里插入图片描述

2. FormatStyle类,格式化风格(jdk8自带)

  1. FULL:全显示(年月日+星期)
  2. LONG:全显示(年月日)
  3. MEDIUM:缩略显示(没有年月日汉字)
  4. SHORT:精简显示(精简年+月日)
public class demo {
    public static void main(String[] args) {
        final LocalDateTime now = LocalDateTime.now();
        System.out.println("当前时间:" + now);
        System.out.println("格式化时间:");
        System.out.println(now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)));
        System.out.println(now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)));
        System.out.println(now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)));
        System.out.println(now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)));
    }
}

在这里插入图片描述

12. 时区

  1. 先总结

    1. 时区相关类:
    	ZonedDateTime:带时区的时间类
    	ZoneId:时区类
    2. 获取所有时区信息:ZoneId.getAvailableZoneIds()
    3. 获取该系统的时区:ZoneId.systemDefault()
    4. 给不带时区的时间对象设置时区:time.atZone(ZoneId zoneId)
    
  2. 获取所有时区信息

    public class demo {
        public static void main(String[] args) {
            final Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
            for (String availableZoneId : availableZoneIds) {
                System.out.println(availableZoneId);
            }
        }
    }
    

    在这里插入图片描述

  3. 获取该系统使用的时区

    public class demo {
        public static void main(String[] args) {
            System.out.println(ZoneId.systemDefault());
        }
    }
    

    在这里插入图片描述

  4. 给 不带时区的时间对象设置时区

    public class demo {
        public static void main(String[] args) {
            LocalDateTime now = LocalDateTime.now();
            // 带上时区的时间对象
            ZonedDateTime zonedDateTime = now.atZone(ZoneId.systemDefault());
            System.out.println(zonedDateTime);
            // 获取使用相同时间内其他时区的时间对象
            ZonedDateTime zonedDateTime2 = zonedDateTime.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
            System.out.println(zonedDateTime2);
        }
    }
    

    在这里插入图片描述

13. 方法总结

1. 时间的常见类
	LocalTime: 时分秒
	LocalDate: 年月日
	LocalDateTime: 年月日 时分秒

	Year: 年
	YearMonth: 年月
	MonthDay: 月日

	Month 月份 枚举
	DayofWeek 星期几 枚举
	
	plus: Period 一段时间/chronoUnit 枚举单位
	with:chronoField 枚举,如:今年的天数/TemporalAccessor 调节器
	
2. 时间的创建方法:
	now():创建当前时间对象
	of(): 创建指定的时间 的对象
	
3. 时间怎么加减:
	plus/minus:直接加减
	plus(Period period): 加一段时间方法
	plus(amountToAdd,chronoUnit)  枚举时间单位加
	
4. 时间直接修改
	with方法
	with(ChronoField, value): 使用ChronoField枚举 方式 修改时间
	with使用调节器
	
5. 时间之间比大小,求差值
	isAfter()
	isBefore()
	between()
	query()
	
6. 时间格式化
	DateTimeFormatter 有自带枚举
	自带格式风格:
		FormatStyle.FULL:全显示(年月日+星期)
		FormatStyle.LONG:全显示(年月日) 
		FormatStyle.MEDIUM:缩略显示(没有年月日汉字) 
		FormatStyle.SHORT:精简显示(精简年+月日)
	DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
	自定义格式化:
		DateTimeFormatter.ofPattern()
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值