SimpleDateFormat线程不安全及解决方案及LocalDate和Date的相互转换/获取一段时间内的所有日期


原文链接:SimpleDateFormat线程不安全及解决方案及LocalDate和Date的相互转换/获取一段时间内的所有日期 – 编程屋

目录

1 simpleDateFormat的用法

 2 SimpleDateFormat类的线程不安全问题

 3 SimpleDateFormat线程不安全原因

 4 如何解决线程不安全问题

5 LocalDate和Date的相互转换

6.Java8中的解析和格式化 

7 获取一段时间内的所有日期


1 simpleDateFormat的用法

        simpleDateFormat是Java提供的一个格式化和解析日期的工具类。它可以进行格式化(日期->文本),解析(文本->日期)和规范化。

        我们可以使用SimpleDateFormat方法中的format方法将data类转为String类型,并转为我们想要的格式

 我们也可以使用SimpleDateFormat方法中的parse方法中的将String类型转为data类型

 2 SimpleDateFormat类的线程不安全问题

        在Java1.8没出来之前,我们可能对SimpleDateFormat类使用的较多,但是SimpleDateFormat在多线程环境下是不安全的

 如图所示,在多线程环境下,使用SimpleDateFormat类是有线程安全问题的

 3 SimpleDateFormat线程不安全原因

        因为SimpleDateFoemat类继承了DateFormat,而DateFormat类中定义了一个成员变量calendar。我们的SimpleDateFormat类中的parse和format方法都用到了calendar

 

 

 在这样多线程的情况下 很容易出现线程覆盖等线程安全问题

 4 如何解决线程不安全问题

        4.1利用ThreadLocal解决

                

  

        4.2 利用Java8新特性

5 LocalDate和Date的相互转换

LocalDate转为Date:

    public static void main(String[] args)  {
        LocalDate now = LocalDate.now();
        Date from1 = Date.from(now.atStartOfDay(ZoneId.systemDefault()).toInstant());
//        Date from2 = Date.from(now.atStartOfDay(ZoneOffset.ofHours(8)).toInstant());
        System.out.println(from1);//Wed Oct 20 00:00:00 CST 2021

    }

Date转为LocalDate:

    public static void main(String[] args)   {
        Date date = new Date();
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        System.out.println(localDate);//2021-10-20

    }

LocalDateTime转Date:

    public static void main(String[] args)  {
        LocalDateTime localDateTime = LocalDateTime.now();
        Date from1 = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
        System.out.println(from1);//Wed Oct 20 16:56:40 CST 2021

    }

Date转LocalDateTime:

    public static void main(String[] args)  {
        Date date = new Date();
        LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        System.out.println(localDateTime);//2021-10-20T16:59:03.541

    }

6.Java8中的解析和格式化 

6.1将字符串解析成一个日期格式

    @Test
    public void test6() throws ParseException {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String str = "2021-11-30";
        LocalDate parse = LocalDate.parse(str,formatter);
        System.out.println(parse); //2021-11-30

//        String start = "2021-10-10";
//        String s = start.replaceAll("-", "");
    }

6.2 日期时间格式化为字符串

    @Test
    public void test6(){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate now = LocalDate.now();
        String format = now.format(formatter);
        System.out.println(format); //2021-12-01

//        String start = "2021-10-10";
//        String s = start.replaceAll("-", "");
    }

7 获取一段时间内的所有日期

    @Test
    public void test6() throws ParseException {

       String start = "2021-10-10";
        String end = "2022-01-10";
        List<String> dates = findDates(start, end);
        System.out.println(dates);
    }

    //获取一段时间内的所有日期
    private  List<String> findDates(String dBegin, String dEnd) throws ParseException {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        //设置开始时间
        Calendar calBegin = Calendar.getInstance();
        calBegin.setTime(format.parse(dBegin));
        //设置结束时间
//        Calendar calEnd = Calendar.getInstance();
//        calEnd.setTime(format.parse(dEnd));

        List<String> Datelist = new ArrayList<>();
        //加上开始时间
        Datelist.add(format.format(calBegin.getTime()));
        // 每次循环给calBegin日期加一天,直到calBegin.getTime()时间等于dEnd
        while (format.parse(dEnd).after(calBegin.getTime()))  {
            // 根据日历的规则,为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            Datelist.add(format.format(calBegin.getTime()));
        }
        System.out.println(Datelist.size());

        return Datelist;
    }

输出结果:

93
[2021-10-10, 2021-10-11, 2021-10-12, 2021-10-13, 2021-10-14, 2021-10-15, 2021-10-16, 2021-10-17, 2021-10-18, 2021-10-19, 2021-10-20, 2021-10-21, 2021-10-22, 2021-10-23, 2021-10-24, 2021-10-25, 2021-10-26, 2021-10-27, 2021-10-28, 2021-10-29, 2021-10-30, 2021-10-31, 2021-11-01, 2021-11-02, 2021-11-03, 2021-11-04, 2021-11-05, 2021-11-06, 2021-11-07, 2021-11-08, 2021-11-09, 2021-11-10, 2021-11-11, 2021-11-12, 2021-11-13, 2021-11-14, 2021-11-15, 2021-11-16, 2021-11-17, 2021-11-18, 2021-11-19, 2021-11-20, 2021-11-21, 2021-11-22, 2021-11-23, 2021-11-24, 2021-11-25, 2021-11-26, 2021-11-27, 2021-11-28, 2021-11-29, 2021-11-30, 2021-12-01, 2021-12-02, 2021-12-03, 2021-12-04, 2021-12-05, 2021-12-06, 2021-12-07, 2021-12-08, 2021-12-09, 2021-12-10, 2021-12-11, 2021-12-12, 2021-12-13, 2021-12-14, 2021-12-15, 2021-12-16, 2021-12-17, 2021-12-18, 2021-12-19, 2021-12-20, 2021-12-21, 2021-12-22, 2021-12-23, 2021-12-24, 2021-12-25, 2021-12-26, 2021-12-27, 2021-12-28, 2021-12-29, 2021-12-30, 2021-12-31, 2022-01-01, 2022-01-02, 2022-01-03, 2022-01-04, 2022-01-05, 2022-01-06, 2022-01-07, 2022-01-08, 2022-01-09, 2022-01-10]

以上只是部分内容,为了维护方便,本文已迁移到新地址:SimpleDateFormat线程不安全及解决方案及LocalDate和Date的相互转换/获取一段时间内的所有日期 – 编程屋

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值