103-java8新特性(3)-新日期API/重复注解

一.原有日期处理

1.SimpleDateFormate线程不安全

(1) 不安全代码

public static void main(String[] args) throws Exception {
        //1.8 之前使用的线程不安全的转换类
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); //1.8之前用的日期转换工具内,线程不安全
        Callable<Date> task = () -> sdf.parse("20200711"); //线程不安全

        ArrayList<Future> list = new ArrayList<>();

        ExecutorService pool = Executors.newFixedThreadPool(10);

        for (int i = 0; i < 10; i++) {
            list.add(pool.submit(task));
        }

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

        pool.shutdown();
    }

(2) java 1.8之前的解决方案

public class TestSimpleDateFormate {

    //1.8之前用ThreadLocal加锁
    private static final ThreadLocal<DateFormat> LOCAL = new ThreadLocal<DateFormat>(){
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyyMMdd");
        }
    };


    public static void main(String[] args) throws Exception {
    
        //1.8之前的解决方案
        Callable<Date> task = () -> LOCAL.get().parse("20200711"); //线程安全.ThreadLocal加锁

        ArrayList<Future> list = new ArrayList<>();

        ExecutorService pool = Executors.newFixedThreadPool(10);

        for (int i = 0; i < 10; i++) {
            list.add(pool.submit(task));
        }

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

        pool.shutdown();
    }
}

(3) java 1.8的解决方案

 		//1.8之后的线程安全的日期转换类
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
        Callable<LocalDate> task = () -> LocalDate.parse("20200711",dtf);


        ArrayList<Future> list = new ArrayList<>();

        ExecutorService pool = Executors.newFixedThreadPool(10);

        for (int i = 0; i < 10; i++) {
            list.add(pool.submit(task));
        }

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

        pool.shutdown();
    

二.java 1.8 新时间/日期API

时间操作的需求:

  • 获取任意时刻的时间
  • 获取当前时间的相关时间,例如下月10号,当天10点,下周五等
  • 计算时间之间的差值
  • 时间与字符串之间的转换

1.获取日期/时间

  • LocalDate : 获取日期
  • LocalTime : 获取时间
  • LocalDateTime : 获取日期+时间
	/**
     * LocalDate : 获取日期
     * LocalTime : 获取时间
     * LocalDateTime : 获取日期+时间
     * 这三个API使用用法相同
     * 获取时间
     */
    @Test
    public void test1(){
        //获取当前日期
        LocalDate now = LocalDate.now();
        System.out.println(now);

        //获取当前时间
        LocalTime now1 = LocalTime.now();
        System.out.println(now1);

        //获取当前日期+时间
        LocalDateTime now2 = LocalDateTime.now();
        System.out.println(now2);

        //获取指定日期
        LocalDateTime of = LocalDateTime.of(2021, 1, 31, 22, 22, 22);
        System.out.println("of日期:" + of);

        //获取当前时间的年,月,日,天,时,分
        System.out.println("year:" + now2.getYear());
        System.out.println("month:" + now2.getMonth());
        System.out.println("mothOfDate:" + now2.getDayOfMonth());
        System.out.println("hour:" + now2.getHour());

    }

2.时间的加减

  • plusYears(10) #10年后
  • minusDays(3) #3天前
	/**
     * 时间的加减
     */
    @Test
    public void test2(){
        LocalDateTime now = LocalDateTime.now();
        //计算多久之后的时间
        //10年之后的今天
        LocalDateTime localDateTime = now.plusYears(10);
        System.out.println("10年后的今天:" + localDateTime);
        //3天之前的今天
        LocalDateTime localDateTime1 = now.minusDays(3);
        System.out.println("3天之前的现在" + localDateTime1);
    }

3.时间戳 -->计算机读取的时间

  • instant
	 /**
     * Instant
     * 时间戳 -->计算机读取的时间
     */
    @Test
    public void test3(){
        //默认获取以UTC时间的时间戳
        Instant instant = Instant.now();
        System.out.println(instant);

        //获取当前时区的时间
        OffsetDateTime odt = instant.atOffset(ZoneOffset.ofHours(8));
        System.out.println(odt);

        //获取时间毫秒数
        long l = instant.toEpochMilli();
        System.out.println(l);

        //获取从计算机元年开始的时间
        Instant instant1 = Instant.ofEpochSecond(60);
        System.out.println(instant1);
    }

4.计算时间间隔

  • Duration: 计算时间之间的间隔
  • Period: 计算两个日期之间的间隔
/**
     * 计算时间间隔
     * Duration: 计算时间之间的间隔
     * Period: 计算两个日期之间的间隔
     */
    @Test
    public void test4(){
        //获取当前时间
        Instant instant = Instant.now();
        //获取1000秒之前的时间
        Instant instant1 = instant.minusSeconds(1000);
        //输出两个时间的毫秒差值
        System.out.println(Duration.between(instant,instant1).toMillis());

        //获取当前时间
        LocalDateTime localDateTime = LocalDateTime.now();
        //获取1年之后
        LocalDateTime localDateTime1 = localDateTime.plusYears(1);
        //计算两个时间指的差值,相差天数
        System.out.println(Duration.between(localDateTime,localDateTime1).toDays());

        //不能计算instant和LocalDateTime之间的差值
        //出现异常DateTimeException: Unable to obtain Instant from TemporalAccesso
        //System.out.println(Duration.between(instant,localDateTime1).toDays());
    }

5.TemporalAdjusters 时间矫正器

功能:
* 获取下个月几号
* 获取下周几
* 获取当月…

	/**
     * TemporalAdjusters 时间矫正器
     * 功能:
     *  获取下个月几号
     *  获取下周几
     *  获取当月...
     */
    @Test
    public void test5(){
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime);

        //获取当前月的10号
        LocalDateTime localDateTime1 = localDateTime.withDayOfMonth(10);
        System.out.println(localDateTime1);

        //获取当天的12点
        LocalDateTime localDateTime2 = localDateTime.withHour(12);
        System.out.println(localDateTime2);

        //获取当前时间下周日
        LocalDateTime localDateTime3 = localDateTime.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
        System.out.println(localDateTime3);
    }

6.时间格式化 DateTimeFormatter

	/**
     * DateTimeFormatter
     * 时间格式化
     * 字符串转换成时间,时间转换成字符串
     */
    @Test
    public void test6(){
        DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE;

        //将时间转换成字符串
        LocalDateTime localDateTime = LocalDateTime.now();
        String s = formatter.format(localDateTime);
        System.out.println(s);

        //不能格式化Instant
        /*Instant instant = Instant.now();
        String s1 = formatter.format(instant);
        System.out.println(s1);*/

        //将字符串转换成时间
        /*TemporalAccessor parse = formatter.parse(s);
        System.out.println(parse);*/
        //或者
        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
        String s1 = formatter1.format(LocalDateTime.now());
        System.out.println(s1);

        LocalDateTime parse1 = LocalDateTime.parse(s1, formatter1);
        System.out.println(parse1);

    }

7.时区 ZonedDate/ZoneTime/ZoneDateTime

	/**
     * 时区
     * ZonedDate/ZoneTime/ZoneDateTime
     */
    @Test
    public void test7(){
        Set<String> set = ZoneId.getAvailableZoneIds();
        set.stream()
                .sorted()
                .parallel()
                .forEach(System.out::println);

        LocalDateTime localDateTime = LocalDateTime.now(ZoneId.of("Asia/Chongqing"));
        System.out.println("重庆当前时间:" + localDateTime);
    }

三.java 1.8 重复注解

我们可以实现这样:
在同一个地方重复使用注解.

	@MyAnnotation("hello")
    @MyAnnotation("world")
    public void show(){
        System.out.println("我爱我的锅");
    }

则需要以下几步:

  1. 定义注解
@Repeatable(MyAnnotations.class)  //指定本注解可以重复使用在同一个地方,并且指定他的容器类是哪个
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE,ElementType.PARAMETER})
public @interface MyAnnotation {

    String value() default "哈哈";
}

  1. 定义注解容器
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE,ElementType.PARAMETER})
public @interface MyAnnotations {

    //myAnnotation的容器属性
    MyAnnotation[] value();
}
  1. 业务上标注注解
public class TestRepeatAnnotation {

    @Test
    public void  test() throws NoSuchMethodException {
        Class<TestRepeatAnnotation> clazz = TestRepeatAnnotation.class;

        //获取该方法上的所有的MyAnnotation注解
        Method show = clazz.getMethod("show");
        MyAnnotation[] annotations = show.getAnnotationsByType(MyAnnotation.class);
        for (int i = 0; i < annotations.length; i++) {
            System.out.println(annotations[i].value());
        }
    }

    @MyAnnotation("hello")
    @MyAnnotation("world")
    public void show(){
        System.out.println("我爱我的锅");
    }
}

具体详情,后续补充

你可能感兴趣的:(javase,java,8新特性)