原文链接:SimpleDateFormat线程不安全及解决方案及LocalDate和Date的相互转换/获取一段时间内的所有日期 – 编程屋
目录
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的相互转换/获取一段时间内的所有日期 – 编程屋