java8日期時間API

java8日期時間API

在這裏插入圖片描述

爲什麼要使用java8的日期時間API,因爲以前用的Date,Calendar都是線程不安全的!

  • 演示線程不安全
public class TestSimpleDateFormat {

    /**
     * 使用之前的時間API,會發生線程不安全的問題
     * java.util.concurrent.ExecutionException: java.lang.NumberFormatException: multiple points
     * @throws Exception
     */
    @Test
    public void test() throws Exception {
        //創建線程池
        ExecutorService pool = Executors.newFixedThreadPool(10);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        Callable<Date> task = new Callable<Date>() {
            @Override
            public Date call() throws Exception {
                return sdf.parse("2020/06/15");//Mon Jun 15 00:00:00 GMT+08:00 2020
            }
        };

        //定義一個集合來裝時間!
        List<Future<Date>> list = new ArrayList<>();
        for(int i=0; i<10; i++){
            list.add(pool.submit(task));
        }

        for(Future<Date> future:list){
            System.out.println(future.get());
        }

        //關閉線程池
        pool.shutdown();
    }


    /**
     * 使用ThreadLocal來進行改進
     */
    @Test
    public void test2()throws Exception{
        //創建線程池
        ExecutorService pool = Executors.newFixedThreadPool(10);

        Callable<Date> task = new Callable<Date>() {
            @Override
            public Date call() throws Exception {
                return TestSimpleDateFormat2.convert("2020/06/15");//Mon Jun 15 00:00:00 GMT+08:00 2020
            }
        };

        //定義一個集合來裝時間!
        List<Future<Date>> list = new ArrayList<>();
        for(int i=0; i<10; i++){
            list.add(pool.submit(task));
        }

        for(Future<Date> future:list){
            System.out.println(future.get()); // Mon Jun 15 00:00:00 GMT+08:00 2020
        }

        //關閉線程池
        pool.shutdown();
    }

    /**
     * java8新的時間API改進!
     * LocalDate
     * @throws Exception
     */
    @Test
    public void test3()throws Exception{
        //創建線程池
        ExecutorService pool = Executors.newFixedThreadPool(10);

        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        Callable<LocalDate> task = new Callable<LocalDate>() {
            @Override
            public LocalDate call() throws Exception {
                return LocalDate.parse("2020/06/15",dateTimeFormatter);
            }
        };

        //定義一個集合來裝時間!
        List<Future<LocalDate>> list = new ArrayList<>();
        for(int i=0; i<10; i++){
            list.add(pool.submit(task));
        }

        for(Future<LocalDate> future:list){
            System.out.println(future.get()); //2020-06-15
        }
        //關閉線程池
        pool.shutdown();
    }

}

上面test2()方法中的輔助類

/**
 * 使用ThreadLocal來進行改進
 */
public class TestSimpleDateFormat2 {
    private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(){
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy/MM/dd");
        }
    };

    public static Date convert(String source) throws Exception {
        return threadLocal.get().parse(source);
    }
}
  • LocalDateTime
  • Instant
  • Duration
  • Period
public class TestLocalDateTime {


    //1. LocalDateTime, LocalDate, LocalTime:人讀的時間
    @Test
    public void test1(){
        LocalDateTime ldt = LocalDateTime.now();
        System.out.println(ldt);//2020-06-16T07:42:45.330

        LocalDateTime ldt2 = LocalDateTime.of(2020, 06, 16, 07, 44, 44);
        System.out.println(ldt2); //2020-06-16T07:44:44

        LocalDateTime ldt3 = ldt.plusYears(2);//加2年,
        System.out.println(ldt3);//2022-06-16T07:46:34.174

        LocalDateTime ldt4 = ldt.minusDays(2);//減2天
        System.out.println(ldt4);//2020-06-14T07:46:34.174

        //單獨獲取年月日,時分秒
        System.out.println(ldt.getYear()+"年");
        System.out.println(ldt.getMonthValue()+"月");
        System.out.println(ldt.getDayOfMonth()+"日");
        System.out.println(ldt.getHour()+"時");
        System.out.println(ldt.getMinute()+"分");
        System.out.println(ldt.getSecond()+"秒");
    }

    //2. Instant: 時間戳(以Unix元年: 1970年1月1日 00:00:00到某個時間之間的毫秒值!)
    @Test
    public void test2(){
        Instant ins1 = Instant.now();// 默認獲取UTC時區
        System.out.println(ins1); //2020-06-15T23:52:31.319Z

        //上面打印的時間跟現在的時間不符,因爲我們在東八區,所以得加8個時區
        OffsetDateTime odt = ins1.atOffset(ZoneOffset.ofHours(8));
        System.out.println(odt);//2020-06-16T07:54:30.292+08:00

        //獲取秒
        System.out.println(ins1.getEpochSecond());
        //獲取毫秒值
        System.out.println(ins1.toEpochMilli());

        Instant instant = Instant.ofEpochSecond(60);
        System.out.println(instant); //1970-01-01T00:01:00Z
    }

    /**
     * 計算“時間”之間的間隔!!: Duration
     */
    @Test
    public void test3(){
        Instant instant1 = Instant.now();
        try {
            Thread.sleep(1000); //間隔1秒
        } catch (InterruptedException e) {
        }
        Instant instant2 = Instant.now();

        Duration duration = Duration.between(instant1, instant2);
        System.out.println(duration);//PT1S
        System.out.println("間隔:"+duration.getSeconds()+"秒");

        System.out.println("=================================");

        LocalTime localTime = LocalTime.now();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        LocalTime localTime2 = LocalTime.now();

        Duration duration2 = Duration.between(localTime, localTime2);
        System.out.println(duration2);
        System.out.println("間隔"+duration2.getSeconds()+"秒");
    }

    /**
     * 計算“日期”之間的間隔!
     */
    @Test
    public void test4(){
        LocalDate localDate = LocalDate.now(); //2020/6/16
        LocalDate localDate2 = LocalDate.of(2022,6,16);

        Period period = Period.between(localDate, localDate2);
        System.out.println(period); //P2Y

        System.out.println(period.getYears()); //2
        System.out.println(period.getMonths());//0
        System.out.println(period.getDays());//0
    }
}
  • TemporalAdjuster
  • DateTimeFormatter
public class TestTemporaAdjuster {


    /**
     * TemporaAdjuster(函數式接口): 時間校正器
     * LocalDateTime,LocalDate,LocalTime: 實現了該接口!
     */

    @Test
    public void test(){
        LocalDateTime ldt = LocalDateTime.now();
        System.out.println(ldt); //2020-06-16T20:59:19.763

        LocalDateTime ldt2 = ldt.withDayOfMonth(10);
        System.out.println(ldt2); //2020-06-10T20:59:19.763

        //下一個星期天!
        LocalDateTime ldt3 = ldt.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
        System.out.println(ldt3);//2020-06-21T21:01:11.733

        //自定義:下一個工作日
//        ldt.with(new TemporalAdjuster() {
//            @Override
//            public Temporal adjustInto(Temporal temporal) {
//                return null;
//            }
//        });

        //lambda表達式
        LocalDateTime ldt5 = ldt.with(temporal -> {
            LocalDateTime ldt4 = (LocalDateTime) temporal;
            DayOfWeek dayOfWeek = ldt4.getDayOfWeek();
            if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
                return ldt4.plusDays(3); //如果是星期五,加三天就是下一個工作日(星期一)
            } else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
                return ldt4.plusDays(2);
            } else {
                return ldt4.plusDays(1); //其他星期天~星期4,加一天也還是工作日!
            }
        });

        System.out.println("下一個工作日:"+ldt5);
    }

    /**
     * 格式化:日期(Date)時間(Time)
     */
    @Test
    public void test2(){

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
        LocalDateTime ldt = LocalDateTime.now();
        //將時間 -> 格式化成字符串
        String format = dtf.format(ldt);
        System.out.println(format); // 2020年06月16日 21:27:37

        //字符串 -> 時間
        LocalDateTime ldt2 = ldt.parse(format,dtf); //要格式化哪種時間!
        System.out.println(ldt2); //2020-06-16T21:31:10
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章