lambda表达式Stream流学习十四,十五—Java8中新增的时间API:LocalDateTime、TemporalAdjuster、DateTimeFormatter

lambda表达式Stream流学习十四,十五—Java8中新增的时间API:LocalDate、LocalTime、LocalDateTime、DateTimeFormatter

一,传统时间 API 与新增的 API

  Java8 新增的时间日期类都在 java.time.* 包下,不可变元素,线程安全。
  LocalDate、LocalTime、LocalDateTime 类的实例是不可变对象,,分别表示使用 ISO-8601 日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。
注 : ISO-8601 日历系统是国际标准化组织制定的现代公民的日期和时间的表示法

public class Time8 {

    @Test
    public void test1() throws Exception {//传统时间API存在多线程安全性问题
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        /*Callable<Date> cal = new Callable<Date>() {
            @Override
            public Date call() throws Exception {
                return sdf.parse("20211227");
            }
        };*/
        Callable<Date> cal = () -> sdf.parse("20211227");
        ExecutorService pool = Executors.newFixedThreadPool(10);//创建一个线程池
        List<Future<Date>> results = new ArrayList<>();
        for (int i=0; i<10; i++){
            results.add(pool.submit(cal));
        }
        for (Future f : results){
            System.out.println(f.get());//多线程环境下,传统的时间API转换时间格式会报错
        }
    }

    @Test
    public void test2() throws Exception {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
        Callable<LocalDate> cal = () -> LocalDate.parse("20211227", dtf);
        ExecutorService es = Executors.newFixedThreadPool(10);
        List<Future<LocalDate>> list = new ArrayList<>();
        for (int i=0; i<10; i++){
            list.add(es.submit(cal));
        }
        for (Future<LocalDate> f : list){
            System.out.println(f.get());//java8中新增的localDate是不可变的,和String一样每次操作都会创建一个新的对象,线程安全
        }
    }
}

二,新增的常用时间 API

  时间格式,LocalDateTime

//LocalDate   LocalTime   LocalDateTime, 三者很类似,很多的API也都是相同方法调用的
@Test
public void test1(){
    LocalDateTime time1 = LocalDateTime.now();//.now() 获取当前时间
    System.out.println(time1);//2021-12-27T23:15:25.332

    LocalDateTime time2 = LocalDateTime.of(2021, 12, 27, 23, 15);//.of() 获得一个实例时间
    System.out.println(time2);//2021-12-27T23:15

    LocalDateTime time3 = time1.plusYears(2);//.plus() 可以往时间里面添加年月日,时分秒,自动计算年份,和String一样,任何操作都会创建一个新的对象
    System.out.println(time3);//2023-12-27T23:19:10.464

    LocalDateTime time4 = time1.minusMonths(2);//.minus() 可以减少年月日,时分秒,自动计算年份,和String一样,任何操作都会创建一个新的对象
    System.out.println(time4);//2021-10-27T23:22:40.331
}

  时间戳格式,Instance

//Instant : 时间戳 (以 Unix 元年 : 1970年1月1日 00:00:00 到某个时间之间的毫秒值)
@Test
public void test2(){
    Instant ins1 = Instant.now();//默认获取UTC时区,相差8个小时
    System.out.println(ins1);//2021-12-27T15:27:00.353Z

    OffsetDateTime ins2 = ins1.atOffset(ZoneOffset.ofHours(8));//.atOffset() 偏移量,对时间进行处理
    System.out.println(ins2);//2021-12-27T23:31:16.248+08:00

    System.out.println(ins1.toEpochMilli());//1640619138313, 返回时间戳

    System.out.println(Instant.ofEpochSecond(1));//1970-01-01T00:00:00 添加一秒
}

  计算时间之间的间隔,Duration

//Duration : 计算两个时间之间的间隔
@Test
public void test3() throws Exception{
    Instant ins1 = Instant.now();
    Thread.sleep(1000);
    Instant ins2 = Instant.now();
    Duration duration = Duration.between(ins1, ins2);//参数可以是时间戳也可以是时间类型
    System.out.println(duration.toMillis());//1003

    LocalDateTime ldt1 = LocalDateTime.now();
    Thread.sleep(1000);
    LocalDateTime ldt2 = LocalDateTime.now();
    Duration duration2 = Duration.between(ldt1, ldt2);
    System.out.println(duration2.toMillis());//1010
}

  计算日期之间的间隔,Period

//Period : 计算两个日期之间的间隔
@Test
public void test4(){
    LocalDate ld1 = LocalDate.of(2000, 01, 15);
    LocalDate ld2 = LocalDate.now();
    Period p = Period.between(ld1, ld2);//得到的是一个Period对象
    System.out.println(p.getYears());//21
    System.out.println(p.getMonths());//11
    System.out.println(p.getDays());//12
}

三,时间矫正器

  TemporalAdjuster:时间矫正器,可以对时间做特殊的矫正处理,有时我们可能需要获取例如将日期调整到"下个周日"等操作。
  TemporalAdjusters:该类通过静态方法提供了大量的常用 TemporalAdjuster 的实现。

//时间矫正器, 对时间进行特殊的处理后拿到自己想要的时间
@Test
public void test1(){
    LocalDateTime ldt1 = LocalDateTime.now();
    System.out.println(ldt1);//2021-12-28T22:28:07.984

    LocalDateTime ldt2 = ldt1.withDayOfMonth(10);//指定月中的天
    System.out.println(ldt2);//2021-12-10T22:28:07.984

    LocalDateTime ldt3 = ldt1.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));//下一个周日
    System.out.println(ldt3);//2022-01-02T22:30:32.590

    //配合lambda自定义方法, 计算下一个工作日
    LocalDateTime nextWorkday = ldt1.with(e -> {
        LocalDateTime time = (LocalDateTime) e;
        if (DayOfWeek.FRIDAY.equals(time.getDayOfWeek())) {
            return time.plusDays(3);
        }else if (DayOfWeek.SATURDAY.equals(time.getDayOfWeek())) {
            return time.plusDays(2);
        }else {
            return time.plusDays(1);
        }
    });
    System.out.println(nextWorkday);
}

四,时间格式化

  Java8 中加入了对时区的支持,带时区的时间分别为:ZonedDate、ZonedTime、ZonedDateTime。

  其中每个时区都对应着ID,地区ID都为 “{区域} / {城市}” 的格式,例如 Asia/Shanghai 等。

  ZoneId : 该类中包含了所有的时区信息,getAvailableZonedIds () : 获取所有可用时区信息,of (id) : 用指定的时区信息获取ZoneId 对象。

//时间格式化
@Test
public void test1(){
    LocalDateTime ldt1 = LocalDateTime.now();
    System.out.println(ldt1);//2021-12-28T22:52:06.605

    DateTimeFormatter dtf1 = DateTimeFormatter.ISO_DATE;//DateTimeFormatter 里面有很多封装好的时间格式可供使用
    String ldt2 = ldt1.format(dtf1);
    System.out.println(ldt2);//2021-12-28

    //可以自定义时间格式类型
    DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
    String ldt3 = dtf2.format(ldt1);
    System.out.println(ldt3);//2021年12月28日 23时15分11秒

    //将时间按照某种格式转回来
    LocalDateTime time = ldt1.parse(ldt3, dtf2);
    System.out.println(time);//2021-12-28T23:15:11
}
//时区处理
@Test
public void test2(){
    Set<String> set = ZoneId.getAvailableZoneIds();//得到所有的时区
    set.forEach(System.out::println);
}

@Test
public void test3(){
    LocalDateTime ldt1 = LocalDateTime.now(ZoneId.of("America/Marigot"));//获取指定时区的当前时间
    System.out.println(ldt1);//2021-12-28T11:15:27.017

    LocalDateTime ldt2 = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
    ZonedDateTime zdt = ldt2.atZone(ZoneId.of("Asia/Shanghai"));//得到一个带时区格式的时间
    System.out.println(zdt);//2021-12-28T23:17:29.521+08:00[Asia/Shanghai]
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值