这里写目录标题
前言
这周接到一个时间转换任务需要处理,本来没什么问题,后来完成后发现时间有偏差,又重写了一遍代码,感觉很有记录必要性,希望看过的小伙伴可以避坑。照例,先说结论。
正确实例:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(CommonConstants.DATE_FORMAT);
LocalDateTime now = LocalDateTime.now();
错误实例:
Calendar calendar = Calendar.getInstance();
结果:如果我们使用了错误的工具类Calendar,求出的时间在时分秒中会有偏差,打到几小时,小到十几秒。这个时间的偏差是我们无法忍受的。
需求
这个工作是要求一个接口传输给我们一部分参数,然后根据参数求出对应的数据,比如昨天今天,三小时、天、月、年后等等。下面是代码实例,照例先放正确的,错误的留给大家参考。
//求出年月日小时对应要求的时间
public Intent dateForParams2(Intent intent, String time) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(CommonConstants.DATE_FORMAT);
LocalDateTime now = LocalDateTime.now();
String endTime = now.format(formatter);
// 将时间向前推移1小时
if (CommonConstants.HeHaiTimeKey.HOUR_1.equals(time)) {
now = now.minusHours(1);
}
if (CommonConstants.HeHaiTimeKey.HOUR_3.equals(time)) {
now = now.minusHours(3);
}
if (CommonConstants.HeHaiTimeKey.HOUR_24.equals(time)) {
now = now.minusDays(1);
}
if (CommonConstants.HeHaiTimeKey.HOUR_48.equals(time)) {
now = now.minusDays(2);
}
if (CommonConstants.HeHaiTimeKey.HOUR_72.equals(time)) {
now = now.minusDays(3);
}
// 将日期向前推移3天
if (CommonConstants.HeHaiTimeKey.DAY_3.equals(time)) {
now = LocalDateTime.of(
now.minusDays(3).toLocalDate(),
LocalTime.of(8, 0, 0) // 设置为8点整
);
}
if (CommonConstants.HeHaiTimeKey.DAY_7.equals(time)) {
now = LocalDateTime.of(
now.minusDays(7).toLocalDate(),
LocalTime.of(8, 0, 0)
);
}
if (CommonConstants.HeHaiTimeKey.DAY_15.equals(time)) {
now = LocalDateTime.of(
now.minusDays(15).toLocalDate(),
LocalTime.of(8, 0, 0)
);
}
if (CommonConstants.HeHaiTimeKey.DAY_30.equals(time)) {
now = LocalDateTime.of(
now.minusDays(30).toLocalDate(),
LocalTime.of(8, 0, 0)
);
}
// 将月份向前推移3个月
if (CommonConstants.HeHaiTimeKey.THREE_MONTH.equals(time)) {
now = LocalDateTime.of(
now.minusMonths(3).toLocalDate(),
LocalTime.of(8, 0, 0)
);
}
if (CommonConstants.HeHaiTimeKey.HALF_YEAR.equals(time)) {
// 将月份向前推移6个月
now = LocalDateTime.of(
now.minusMonths(6).toLocalDate(),
LocalTime.of(8, 0, 0)
);
}
// 将年份向前推移1年
if (CommonConstants.HeHaiTimeKey.ONE_YEAR.equals(time)) {
now = LocalDateTime.of(
now.minusYears(1).toLocalDate(),
LocalTime.of(8, 0, 0)
);
}
if (CommonConstants.HeHaiTimeKey.THREE_YEAR.equals(time)) {
now = LocalDateTime.of(
now.minusYears(3).toLocalDate(),
LocalTime.of(8, 0, 0)
);
}
if (CommonConstants.HeHaiTimeKey.FIVE_YEAR.equals(time)) {
now = LocalDateTime.of(
now.minusYears(5).toLocalDate(),
LocalTime.of(8, 0, 0)
);
}
if (CommonConstants.HeHaiTimeKey.TEN_YEAR.equals(time)) {
now = LocalDateTime.of(
now.minusYears(10).toLocalDate(),
LocalTime.of(8, 0, 0)
);
}
//设置早上8点
if (CommonConstants.HeHaiTimeKey.TODAY.equals(time)) {
now = LocalDateTime.of(
now.toLocalDate(), // 使用当前日期
LocalTime.of(8, 0, 0) // 设置为8点整
);
}
if (CommonConstants.HeHaiTimeKey.YESTERDAY.equals(time)) {
//减去1天
now = LocalDateTime.of(
now.minusDays(1).toLocalDate(),
LocalTime.of(8, 0, 0)
);
// 结束日期为今日8点整
endTime = eightForNow2(0);
}
if (CommonConstants.HeHaiTimeKey.LAST_DAY.equals(time)) {
//减去2天
now = LocalDateTime.of(
now.minusDays(2).toLocalDate(),
LocalTime.of(8, 0, 0)
);
// 结束日期为昨日8点整
endTime = eightForNow2(1);
}
String startTime = now.format(formatter);
log.info("输出开始时间:{}", startTime);
intent.setStartTime(startTime);
intent.setEndTime(endTime);
return intent;
}
/**
* 求出早8点
*/
public String eightForNow2(Integer day) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(CommonConstants.DATE_FORMAT);
LocalDateTime now = LocalDateTime.now();
if (day != null) {
if (day == 0) {
now = LocalDateTime.of(
now.toLocalDate(), // 使用当前日期
LocalTime.of(8, 0, 0) // 设置为8点整
);
} else {
now = LocalDateTime.of(
now.minusDays(day).toLocalDate(),
LocalTime.of(8, 0, 0)
);
}
}
return now.format(formatter);
}
这个没有集成一个工具类是因为需求开发时间小,而且要求时间短,再加上是使用频率低。有常用的可以集成到你们的时间工具类中。
-------------------------------错误-------------------------------
/**
* 根据Params求出不同的时间
*/
public Intent dateForParams(Intent intent, String time) {
SimpleDateFormat format = new SimpleDateFormat(CommonConstants.DATE_FORMAT);
Calendar calendar = Calendar.getInstance(); //获取日历实例
String endTime = format.format(calendar.getTime());//后去结束时间
calendar.setTime(date); //将当前时间设置给日历实例
int hour = calendar.get(Calendar.HOUR_OF_DAY); // 获取当前的小时数
// 将时间向前推移1小时
if (CommonConstants.HeHaiTimeKey.HOUR_1.equals(time)) {
if (hour < 1) {
calendar.add(Calendar.DAY_OF_MONTH, -1); // 将日期向前推移1天
hour += 24; // 计算出对应的小时数
calendar.add(Calendar.HOUR_OF_DAY, hour - 1);
} else {
calendar.add(Calendar.HOUR_OF_DAY, -1);
}
}
if (CommonConstants.HeHaiTimeKey.HOUR_3.equals(time)) {
if (hour < 1) {
calendar.add(Calendar.DAY_OF_MONTH, -1); // 将日期向前推移1天
hour += 24; // 计算出对应的小时数
calendar.add(Calendar.HOUR_OF_DAY, hour - 3);
} else {
calendar.add(Calendar.HOUR_OF_DAY, -3);
}
}
if (CommonConstants.HeHaiTimeKey.HOUR_24.equals(time)) {
calendar.add(Calendar.DAY_OF_MONTH, -1);
}
if (CommonConstants.HeHaiTimeKey.HOUR_48.equals(time)) {
calendar.add(Calendar.DAY_OF_MONTH, -2);
}
if (CommonConstants.HeHaiTimeKey.HOUR_72.equals(time)) {
calendar.add(Calendar.DAY_OF_MONTH, -3);
}
// 将日期向前推移3天
if (CommonConstants.HeHaiTimeKey.DAY_3.equals(time)) {
calendar.add(Calendar.DAY_OF_MONTH, -3);
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
}
if (CommonConstants.HeHaiTimeKey.DAY_7.equals(time)) {
calendar.add(Calendar.DAY_OF_MONTH, -7);
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
}
if (CommonConstants.HeHaiTimeKey.DAY_15.equals(time)) {
calendar.add(Calendar.DAY_OF_MONTH, -15);
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
}
if (CommonConstants.HeHaiTimeKey.DAY_30.equals(time)) {
calendar.add(Calendar.DAY_OF_MONTH, -30);
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
}
// 将月份向前推移3个月
if (CommonConstants.HeHaiTimeKey.THREE_MONTH.equals(time)) {
calendar.add(Calendar.MONTH, -3);
}
if (CommonConstants.HeHaiTimeKey.HALF_YEAR.equals(time)) {
// 将月份向前推移6个月
calendar.add(Calendar.MONTH, -6);
}
// 将年份向前推移1年
if (CommonConstants.HeHaiTimeKey.ONE_YEAR.equals(time)) {
calendar.add(Calendar.YEAR, -1);
}
if (CommonConstants.HeHaiTimeKey.THREE_YEAR.equals(time)) {
calendar.add(Calendar.YEAR, -3);
}
if (CommonConstants.HeHaiTimeKey.FIVE_YEAR.equals(time)) {
calendar.add(Calendar.YEAR, -5);
}
if (CommonConstants.HeHaiTimeKey.TEN_YEAR.equals(time)) {
calendar.add(Calendar.YEAR, -10);
}
//设置早上8点
if (CommonConstants.HeHaiTimeKey.TODAY.equals(time)) {
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
}
if (CommonConstants.HeHaiTimeKey.YESTERDAY.equals(time)) {
//减去1天
calendar.add(Calendar.DAY_OF_MONTH, -1);
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
// 结束日期为今日8点整
endTime = eightForNow(null);
intent.setEndTime(endTime);
}
if (CommonConstants.HeHaiTimeKey.LAST_DAY.equals(time)) {
//减去2天
calendar.add(Calendar.DAY_OF_MONTH, -2);
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
// 结束日期为昨日8点整
endTime = eightForNow(1);
intent.setEndTime(endTime);
}
String startTime;
Date dayTime = calendar.getTime();
if (CommonConstants.HeHaiTimeKey.REAL_TIME.equals(time)) {
startTime = endTime;
} else {
startTime = format.format(dayTime); //将时间格式化为字符串
}
log.info("输出开始时间:{}", startTime);
intent.setStartTime(startTime);
intent.setEndTime(endTime);
return intent;
}
/**
* 求出早8点
*/
public String eightForNow(Integer day) {
Calendar calendar = Calendar.getInstance(); //获取日历实例
calendar.setTime(date); //将当前时间设置给日历实例
if (day != null) {
calendar.add(Calendar.DAY_OF_MONTH, -day); //减去对应天数
}
calendar.set(Calendar.HOUR_OF_DAY, 8); //设置早上8点
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Date yesterday8am = calendar.getTime(); //获取昨天早上8点的时间
SimpleDateFormat format = new SimpleDateFormat(CommonConstants.DATE_FORMAT);
String formattedDateTime = format.format(yesterday8am);
log.info("输出开始时间:{}", formattedDateTime);
return formattedDateTime;
}
上面都是一些官网给出的答案,由此我们也可以看出,使用LocalDateTime是更好的一种选择,还在用calender的可以尝试替换了,不要停留在旧时代里。
代码就不具体讲解了也不是很难,注释也挺多,有什么不懂得可以评论下方提出,看到后会抓紧回复的。
ps:有的小伙伴可能的确是刚接触,这里提供一个calender的示例,自己试着修改成LocalDateTime,前者你可以不会,后者不行哦。
public static void main(String[] args) throws ParseException {
String dateTimeString = “2023-06-13 02:00:00”;
SimpleDateFormat format = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
Date date1 = format.parse(dateTimeString); // 解析为 Date 对象
Calendar calendar = Calendar.getInstance(); //获取日历实例
calendar.setTime(date1); //将当前时间设置给日历实例
//这里零时转换可以忽略,LocalDateTime没有这方面的烦恼
int hour = calendar.get(Calendar.HOUR_OF_DAY); // 获取当前的小时数
if (hour < 1) { // 如果小时数小于1,则需要特殊处理
calendar.add(Calendar.DAY_OF_MONTH, -1); // 将日期向前推移1天
hour += 24; // 计算出对应的小时数
}
//calendar.set(Calendar.HOUR_OF_DAY, hour - 72); // 将时间向前推移1小时
calendar.add(Calendar.YEAR, -10); // 将年份向前推移10年
Date yesterday8am = calendar.getTime();
String formattedDateTime = format.format(yesterday8am); //将时间格式化为字符串
System.out.println("输出结果:"+formattedDateTime); //输出结果
}