新时间日期 API

 传统时间格式化的线程安全问

/**
 * 测试传统时间格式化的线程安全问题
 */
public class TestSimpleDateFormat {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

        Callable<Date> task = new Callable<Date>() {
            @Override
            public Date call() throws Exception {
                return sdf.parse("20180805");
            }
        };

        ExecutorService pool = Executors.newFixedThreadPool(10);

        List<Future<Date>> results = new ArrayList<>();

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

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

 运行会发生安全问题报错

Java8之前的解决方法:

public class DateFormatThreadLocal {

    private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyyMMdd");
        }
    };

    public static Date convert(String source) throws ParseException {
        return df.get().parse(source);
    }
}


/**
 * 测试传统时间格式化的线程安全问题
 */
public class TestSimpleDateFormat {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

//        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

        Callable<Date> task = new Callable<Date>() {
            @Override
            public Date call() throws Exception {
//                return sdf.parse("20180805");
                return DateFormatThreadLocal.convert("20170805");
            }
        };

        ExecutorService pool = Executors.newFixedThreadPool(10);

        List<Future<Date>> results = new ArrayList<>();

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

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

        pool.shutdown();
    }
}

Java8的解决方法:


/**
 * 测试传统时间格式化的线程安全问题
 */
public class TestSimpleDateFormat {
    public static void main(String[] args) throws ExecutionException, InterruptedException {


        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");

        Callable<LocalDate> task = new Callable<LocalDate>() {
            @Override
            public LocalDate call() throws Exception {
                return LocalDate.parse("20180805", dtf);
            }
        };

        ExecutorService pool = Executors.newFixedThreadPool(10);

        List<Future<LocalDate>> results = new ArrayList<>();

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

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

        pool.shutdown();
    }
}

使用 LocalDate、LocalTime、LocalDateTime

 LocalDate、LocalTime、LocalDateTime 类的实 例是不可变的对象,分别表示使用 ISO-8601日 历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。
 

    // LocalDate LocalTime LocalDateTime 使用方法类似
    @Test
    public void test1(){
        LocalDateTime ldt = LocalDateTime.now();//获取当前时间
        System.out.println(ldt);
        System.out.println("------------------");
        //指定时间
        LocalDateTime ldf2 = LocalDateTime.of(2018, 01, 01, 00, 00, 59);
        System.out.println(ldf2);
        System.out.println("------------------");
        //加时间
        LocalDateTime ldt3 = ldt.plusYears(2);//加两年
        System.out.println(ldt3);
        System.out.println("------------------");
        //减
        LocalDateTime ldt4 = ldt.minusMonths(2);//减两个月
        System.out.println(ldt4);
        System.out.println("------------------");
        //获取日期年月日时分秒
        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());
    }

运行结果: 

2018-08-05T22:58:32.333
------------------
2018-01-01T00:00:59
------------------
2020-08-05T22:58:32.333
------------------
2018-06-05T22:58:32.333
------------------
2018
8
5
22
58
32

Instant 时间戳

 

用于“时间戳”的运算。它是以Unix元年(传统 的设定为UTC时区1970年1月1日午夜时分)开始 所经历的描述进行运算

    //Instant 时间戳
    @Test
    public void test2(){
        Instant ins1 = Instant.now();//默认获取的UTC(本初子午线)时区
        System.out.println(ins1);
        OffsetDateTime odt1 = ins1.atOffset(ZoneOffset.ofHours(8));//偏移量运算 偏移8个小时
        System.out.println(odt1);

        System.out.println(ins1.toEpochMilli());//获取毫秒值 时间戳
    }
2018-08-05T15:05:34.158Z
2018-08-05T23:05:34.158+08:00
1533481534158

计算日期时间间隔Duration 和 Period

Duration:用于计算两个“时间”间隔
Period:用于计算两个“日期”间隔

Duration

  @Test
    public void test3(){
        Instant ins1 = Instant.now();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Instant ins2 = Instant.now();
        Duration dur = Duration.between(ins1, ins2);
        System.out.println(dur.toMillis());
        System.out.println("------------------");

        LocalTime lt1 = LocalTime.now();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LocalTime lt2 = LocalTime.now();
        System.out.println(Duration.between(lt1,lt2).toMillis());
    }
1001
------------------
1000

Period

 @Test
    public void test4(){
        LocalDate ld1 = LocalDate.of(2018, 1, 1);
        LocalDate ld2 = LocalDate.now();
        Period per = Period.between(ld1, ld2);
        System.out.println(per);//

        System.out.println(per.getYears());
        System.out.println(per.getMonths());
        System.out.println(per.getDays());


    }
P7M4D
0
7
4

时间校正器

    //TemporalAdjuster  时间校正器
    @Test
    public void test5(){
        LocalDateTime ldt1 = LocalDateTime.now();
        System.out.println(ldt1);

        LocalDateTime ldt2 = ldt1.withDayOfMonth(10);//当前月10号
        System.out.println(ldt2);

        LocalDateTime ldt3 = ldt1.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));//下周日
        System.out.println(ldt3);

        //自定义:下一个工作日
        LocalDateTime ldt5 = ldt1.with((l) -> {
            LocalDateTime ldt4 = (LocalDateTime) l;
            DayOfWeek dow = ldt4.getDayOfWeek();
            if (dow.equals(DayOfWeek.FRIDAY)){
                return ldt4.plusDays(3);
            }else if (dow.equals(DayOfWeek.SATURDAY)){
                return ldt4.plusDays(2);
            }else{
                return ldt4.plusDays(1);
            }
        });
        System.out.println(ldt5);
    }
2018-08-05T23:42:46.459
2018-08-10T23:42:46.459
2018-08-12T23:42:46.459
2018-08-06T23:42:46.459

DateTimeFormatter 格式化时间/日期

    @Test
    public void test6(){
        DateTimeFormatter dtf1 = DateTimeFormatter.ISO_DATE;
        LocalDateTime ldt = LocalDateTime.now();
        String strDate1 = ldt.format(dtf1);
        System.out.println(strDate1);

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

        DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
        String strDate2 = dtf2.format(ldt);
        System.out.println(strDate2);

        LocalDateTime newDate = ldt.parse(strDate2, dtf2);
        System.out.println(newDate);

    }
2018-08-05
------------------
2018年08月05日 23:55:16
2018-08-05T23:55:16

时区的处理

 Java8 中加入了对时区的支持,带时区的时间为分别为:ZonedDate、ZonedTime、ZonedDateTime其中每个时区都对应着 ID,地区ID都为 “{区域}/{城市}”的格式
例如 :Asia/Shanghai 等
ZoneId:该类中包含了所有的时区信息
getAvailableZoneIds() : 可以获取所有时区时区信息
of(id) : 用指定的时区信息获取 ZoneId 对象

    @Test
    public void test7(){
        LocalDateTime ldt1 = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
        System.out.println(ldt1);
        ZonedDateTime zdt1 = ldt1.atZone(ZoneId.of("Asia/Shanghai"));
        System.out.println(zdt1);
    }
2018-08-06T00:01:13.727
2018-08-06T00:01:13.727+08:00[Asia/Shanghai]

猜你喜欢

转载自blog.csdn.net/m0_37450089/article/details/81436650
今日推荐