很神奇,为什么java中不推荐使用Date与Calendar日期了,很多时候初学者在刚学习java时,大部分使用的日期都是Date与Calendar,只有及少数个别使用的LocalDateTime日期
Date 与 Calendar存在的共性问题
- 毫秒值与日期直接转换麻烦和繁琐,然后通过毫秒值来计算时间的差额步骤较多,并且还可能存在误差
- 再有一个就是线程问题,我们都知道在创建一个Date日期变量时,它的格式不是我们能看懂的日期格式,这时候就需要使用SimpleDateFormat了,然后
这就引发了一个问题,这个类的线程是不安全的(在做生产总览的时候,需要大量使用日期类,当时每个类我都创建了一个SimpleDateFormat,想着有点
浪费内存空间了,然后在service层最上面定义了一个静态的日期格式类,接着就引发了一个问题,页面报错,然后查询资料才知道,多个线程
对同一个类操作造成了格式化错误,甚至有可能引发内存泄漏,可能导致内存泄漏问题,占用过多的内存资源)
使用日期推荐LocalDate、LocalTime、LocalDateTime这三个日期类
1. LocalDate类是一个不可变的日期时间对象,表示日期,通常被视为年月日
// 获取当前年、月、日
LocalDate today = LocalDate.now();
// 获取年
int year = today.getYear();
// 获取月
int month = today.getMonthValue();
// 获取天
int day = today.getDayOfMonth();
// 获取毫秒值
LocalDateTime startOfDay = localDate.atStartOfDay();
long millisecondsFromDate = startOfDay.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
2. LocalTime类是一个不可变的日期时间对象,代表一个时间,通常被看作小时-秒,时间表示为纳秒精度
// 获取当前年、月、日
LocalTime time = LocalTime.now();
int hour = time.getHour(); // 获取小时
int minute = time.getMinute(); // 获取分钟
int second = time.getSecond(); // 获取秒
int nano = time.getNano(); // 获取纳秒
3. LocalDateTime是一个不可变的日期时间对象,代表日期时间,通常被视为年-月-日- 时-分-秒
LocalDateTime dateTime = LocalDateTime.now();
int year = dateTime.getYear(); // 获取年份
int month = dateTime.getMonthValue(); // 获取月份 (1-12)
int dayOfMonth = dateTime.getDayOfMonth(); // 获取月份中的天数
int hour = dateTime.getHour(); // 获取小时
int minute = dateTime.getMinute(); // 获取分钟
int second = dateTime.getSecond(); // 获取秒
int nano = dateTime.getNano(); // 获取纳秒
// 获取毫秒值
// 需要将LocalDateTime变量转换为ZoneDateTime对象
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
Instant instant = zonedDateTime.toInstant();
long milliseconds = instant.toEpochMilli();
// 日期格式化
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String dayTime = dateTimeFormatter.format(dateTime);
方法名 | 说明 |
public LocalDateTime plusYears(long years) | 添加或者减去年 |
public LocalDateTime plusMonths(long months) | 添加或者减去月 |
public LocalDateTime plusDays(long months) | 添加或者减去日 |
public LocalDateTime plusHours(long hours) | 添加或者减去时 |
public LocalDateTime plusMinutes(long minutes) | 添加或者减去分 |
public LocalDateTime plusSeconds(long seconds) | 添加或者减去秒 |
public LocalDateTime plusWeeks(long weeks) | 添加或者减去周 |
这里要注意!!根据业务需求使用不同的日期,如果前端传值为年-月-日,而后端使用了LocalDateTime日期会报无法转换的问题,这是因为LocalDateTime底层是被final修饰了无法更改,它的格式只能是年-月-日 时:分:秒,所以要使用对应的日期格式
使用示例:(获取一天中的24小时,然后使用String的format方法截取)
// 创建 DateTimeFormatter 对象,指定时间格式为 "yyyy-MM-dd HH:mm:ss"
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDate date = LocalDate.parse(dayTime);
// 获取当前时间,小时取整,分和秒设为0 使用with将日期设定为指定日期,然后分与秒为0
LocalDateTime now = LocalDateTime.now().with(date).withMinute(0).withSecond(0);
for(int j = 0; j < 24; j++){
TbProductionLineStopDTO tbProductionLineStopDTO = new TbProductionLineStopDTO();
if(j == 23){
// 设置当前日期小时为23,并且格式化
startTime = now.withHour(23).format(formatter);
// 天数减1,并且小时设置为0
endTime = now.plusDays(1).withHour(0).format(formatter);
starHour = String.format("%02d", j);
endHour = String.format("%02d", 00);
}else{
// 创建 startTime 和 endTime 变量
startTime = now.withHour(j).format(formatter);
endTime = now.withHour(j+1).format(formatter);
starHour = String.format("%02d", j);
endHour = String.format("%02d", j+1);
}
Integer productionCount = realTimeMapper.queryTbProductPassrecord(startTime,endTime,lineCode);
if(productionCount == null){
productionCount = 0;
}
String time = starHour + "-" + endHour;
tbProductionLineStopDTO.setLineCount(productionCount);
tbProductionLineStopDTO.setTimeHour(time);
tbProductionLineStopDTOList.add(tbProductionLineStopDTO);
}