日期的使用
前言
Github:https://github.com/HealerJean
一、Local
日期
1、基本方法
类 | |
---|---|
LocalTime |
只包括时间,mapper 对应 time |
LocalDate |
只包括日期,mapper 对应 date |
LocalDateTime |
包括日期和时间,,mapper 对应 timestamp |
1)LocalTime
基本方法 | 结果 | 说明 |
---|---|---|
LocalTime now = LocalTime.now() |
11:09:09.240 | LocalTime 包含毫秒 |
LocalTime now = LocalTime.now().withNano(0)); |
11:09:09 | 清除毫秒数 |
LocalTime localtime = LocalTime.of(0, 0, 0); |
00:00:00 | |
LocalTime localtime = LocalTime.parse("12:00:00"); |
12:00:00 | 字符串截取,严格按照ISO yyyy-MM-dd验证 |
2)LocalDate
基本方法 | 说明 |
---|---|
LocalDate today = LocalDate.now(); |
|
LocalDate date = LocalDate.of(2017, 5, 25); |
|
LocalDate date = LocalDate.of(2017, 05, 25); |
字符串截取,严格按照ISO yyyy-MM-dd验证 |
LocalDate date = LocalDate.parse("2014-02-28"); |
|
LocalDate date = LocalDate.parse("2014-2-28"); |
错误 |
3)LocalDateTime
基本方法 | 说明 |
---|---|
LocalDateTime d1 = LocalDateTime.of(2013, 12, 31, 23, 59); |
年,月,日,时,分 |
LocalDateTime d3 = LocalDateTime.of(2013, 12, 31, 23, 59,59); |
年,月,日,时,分,秒 |
LocalDateTime d2 = LocalDateTime.of(2013, 12, 31, 23, 59,59, 11); |
年,月,日,时,分,秒毫秒 |
LocalDateTime d1 = LocalDateTime.parse("2013-12-31T23:59"); |
|
LocalDateTime d2 = LocalDateTime.parse("2013-12-31T23:59:59"); |
|
LocalDateTime d3 = LocalDateTime.parse("2013-12-31T23:59:59.000000011"); |
2、常用方法
1)获取固定的日期
方法 | 说明 |
---|---|
LocalDate.now().getYear(); |
年份 |
LocalDate.now().getMonthValue(); |
月份(数值表示, 从1开始) |
LocalDate.now().getMonth(); |
月份(英文[enum]表示) |
LocalDate.now().getDayOfMonth(); |
日期(从1开始) |
LocalDate.now().getDayOfYear(): |
当天所在这一年的第几天(从1开始) |
LocalDate.now().getDayOfWeek() |
星期几 |
LocalDate.now().lengthOfYear(); |
当年的天数 |
LocalDate.now().lengthOfMonth(); |
当月的天数 |
LocalDate.now().toEpochDay(); |
与时间纪元(1970年1月1日)相差的天数,负数表示在时间纪元之前多少天 |
LocalDateTime todayStart = now.atStartOfDay(); |
当天开始时间 |
LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.MIN) |
获取当他开始时间 |
LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.MAX) |
获取当天结束时间 |
2)加减法
方法 | 说明 |
---|---|
LocalDate.now().plusDays(1) |
加1天 |
LocalDate.now().plusWeeks(1) |
加1周 |
LocalDate.now().plusMonths(1) |
加1月 |
LocalDate.now().plusYears(1) |
加1年 |
LocalDate.now().minusDays(1) |
减1天 |
LocalDate.now().minusWeeks(1) |
减1周 |
LocalDate.now().minusMonths(1) |
减1月 |
LocalDate.now().minusYears(1) |
减1年 |
LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS); |
加1周 |
LocalDate nextMonth = today.plus(1, ChronoUnit.MONTHS); |
加1月 |
LocalDate nextDecade = today.plus(1, ChronoUnit.DECADES); |
加1年 |
3)日期替换
| 方法 (当前:2019-07-17) | 说明 | 结果 |
| ———————————– | ————- | ———- |
| LocalDate.now().withDayOfMonth(1)
| 替换日期为1 | 2019-07-01 |
| ` LocalDate.now().withDayOfYear(1) | 替换天数为1 | 2019-01-01 |
|
LocalDate.now().withMonth(1) | 替换月份为1 | 2019-01-17 |
|
LocalDate.now().withYear(1)` | 替换年份为1: | 0001-07-17 |
4)比较
方法 (当天 LocalDate.now() = 2019-07-17 ) |
说明 | 结果 |
---|---|---|
LocalDate.now().minusDays(1).isBefore(LocalDate.now()) |
是否在当天之前 | true |
LocalDate.now().plusDays(1).isAfter(LocalDate.now()) |
是否在当天之后 | true |
LocalDate.now().isEqual(LocalDate.now()) |
是否在当天 | true |
LocalDate.now().isLeapYear() |
今年是否是闰年 | False |
5)计算
建议使用
ChronoUnit
更全面一些
方法 | 说明 |
---|---|
int daysNum = Period.between(startTime.toLocalDate(), endTime.toLocalDate()).getDays(); |
相差天数 |
int monthNum = Period.between(startTime.toLocalDate(), endTime.toLocalDate()).getMonths() |
相差月数 |
long daysDiff = ChronoUnit.DAYS.between(startTime, endTime); |
相差天数 |
` long monthDiff = ChronoUnit.MONTHS.between(startTime, endTime);` | 相差月数 |
long hourDiff = ChronoUnit.HOURS.between(startTime, endTime); |
相乘小时数 |
3、实战
1)Controller
建议用字符串做入参和出参
@Configuration
public class DateConfig {
/***
* 日期参数接收转换器,将json字符串转为日期类型
* @return
*/
@Bean
public Converter<String, LocalDateTime> LocalDateTimeConvert() {
return new Converter<String, LocalDateTime>() {
@Override
public JavaType getInputType(TypeFactory typeFactory) {
return null;
}
@Override
public JavaType getOutputType(TypeFactory typeFactory) {
return null;
}
@Override
public LocalDateTime convert(String source) {
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime date = null;
try {
date = LocalDateTime.parse((String) source,df);
} catch (Exception e) {
e.printStackTrace();
}
return date;
}
};
}
/***
* 日期参数接收转换器,将json字符串转为日期类型
* @return
*/
@Bean
public Converter<String, LocalDate> LocalDateConvert() {
return new Converter<String, LocalDate>() {
@Override
public JavaType getInputType(TypeFactory typeFactory) {
return null;
}
@Override
public JavaType getOutputType(TypeFactory typeFactory) {
return null;
}
@Override
public LocalDate convert(String source) {
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = null;
try {
date = LocalDate.parse((String) source,df);
} catch (Exception e) {
e.printStackTrace();
}
return date;
}
};
}
}
二、Date
日期
1、实战
1)DatePeriodUtils
package com.healerjean.proj.utils.date;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.springframework.util.CollectionUtils;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Stream;
/**
* 日期区间工具,月、季度、半年 等
*
* @author zhangyujin
* @date 2022/7/19 17:57.
*/
public final class DatePeriodUtils {
public static final String YYYY_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
private static final DateTimeFormatter DTF_YYYY_MM_DD = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private static final DateTimeFormatter DTF_YYYY_MM = DateTimeFormatter.ofPattern("yyyy-MM");
/**
* 1、获取固定一年前的起始时间
* 2、获取当前时间所在月份的最后一天
*
* @param date 日期如2022-05、2022-12 、2022-12-01
* @return DatePeriod
*/
public static DatePeriod getBackOneYearRange(String date) {
String[] split = date.split("-");
int year = Integer.parseInt(split[0]);
int month = Integer.parseInt(split[1]);
int halfPeripd = 1;
if (month > 6) {
halfPeripd = 2;
}
int lastYear = year - 1;
String startTime = getHalfYearDayRangeStartTime(lastYear, halfPeripd);
String endTime = getHalfYearDayRangeEndTime(year, halfPeripd);
return new DatePeriod(startTime, endTime);
}
/**
* 获取一段期间所在的最长半年周期
*
* @param startDate 起始时间 2022-01
* @param endDate 结束时间
* @return DatePeriod
*/
public static DatePeriod getBackOneYearRange(String startDate, String endDate) {
String[] startSplit = startDate.split("-");
int startYear = Integer.parseInt(startSplit[0]);
int startMonth = Integer.parseInt(startSplit[1]);
int startHalfPeripd = 1;
if (startMonth > 6) {
startHalfPeripd = 2;
}
String startTime = getHalfYearDayRangeStartTime(startYear, startHalfPeripd);
String[] endSplit = endDate.split("-");
int endYear = Integer.parseInt(endSplit[0]);
int endMonth = Integer.parseInt(endSplit[1]);
int endHalfPeripd = 1;
if (endMonth > 6) {
endHalfPeripd = 2;
}
String endTime = getHalfYearDayRangeEndTime(endYear, endHalfPeripd);
return new DatePeriod(startTime, endTime);
}
/**
* 获取某年某月的天数
*
* @param date yyyy-MM 如:2022-06
* @return 30
*/
public static int getMonthDay(String date) {
String[] split = date.split("-");
return getMonthDay(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
}
/**
* 获取某年某月的天数
*
* @param year 年
* @param month 月份
* @return 天数
*/
public static int getMonthDay(int year, int month) {
DatePeriod monthRange = getMonthDayRange(year, month);
return (int) ChronoUnit.DAYS.between(toLocalDateTime(monthRange.getStartDateTime()), toLocalDateTime(monthRange.getEndDateTime())) + 1;
}
/**
* 获取某年某季度的天数
*
* @param date 2022-4
* @return 92
*/
public static int getQuarterDay(String date) {
String[] split = date.split("-");
return getQuarterDay(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
}
/**
* 获取某年某季度的天数
*
* @param year 年
* @param quarter 季度
* @return 天数
*/
public static int getQuarterDay(int year, int quarter) {
DatePeriod monthRange = getQuarterDayRange(year, quarter);
return (int) ChronoUnit.DAYS.between(toLocalDateTime(monthRange.getStartDateTime()), toLocalDateTime(monthRange.getEndDateTime())) + 1;
}
/**
* 获取某半年的天数
*
* @param date 日期
* @return 天数
*/
public static int getHalfYearDay(String date) {
String[] split = date.split("-");
return getHalfYearDay(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
}
/**
* 获取某半年天数
*
* @param year 年
* @param quarter 前半年或后半年
* @return 天数
*/
public static int getHalfYearDay(int year, int quarter) {
DatePeriod monthRange = getHalfYearRange(year, quarter);
return (int) ChronoUnit.DAYS.between(toLocalDateTime(monthRange.getStartDateTime()), toLocalDateTime(monthRange.getEndDateTime())) + 1;
}
/**
* 计算环比月
*
* @param currMonth 2019-01
* @return 2018-12
*/
public static String getHbMonth(String currMonth) {
currMonth = currMonth + "-01";
LocalDate d = LocalDate.parse(currMonth, DTF_YYYY_MM_DD);
return DTF_YYYY_MM.format(d.minusMonths(1L));
}
/**
* 计算同比月
*
* @param currMonth 2019-01
* @return 2018-01
*/
public static String getTbMonth(String currMonth) {
currMonth = currMonth + "-01";
LocalDate d = LocalDate.parse(currMonth, DTF_YYYY_MM_DD);
return DTF_YYYY_MM.format(d.minusYears(1L));
}
/**
* 计算同比季度(去年同期)
* date 2022-4
*
* @return 2021-4
*/
public static String getTbQuarter(String date) {
String[] dateArray = date.split("-");
int year = Integer.parseInt(dateArray[0]) - 1;
return year + "-" + dateArray[1];
}
/**
* 计算环比季度
*
* @param date 2019-1
* @return 2019-1 -> 2018-4 、 2019-2 -> 2019-1
*/
public static String getHbQuarter(String date) {
String[] dateArray = date.split("-");
int quarter = Integer.parseInt(dateArray[1]) - 1;
if (quarter > 0) {
return dateArray[0] + "-" + quarter;
}
int year = Integer.parseInt(dateArray[0]) - 1;
return year + "-" + 4;
}
/**
* 计算同比 半年
* date 2022-1
*
* @return 2021-1
*/
public static String getTbHalfYear(String date) {
String[] dateArray = date.split("-");
int year = Integer.parseInt(dateArray[0]) - 1;
return year + "-" + dateArray[1];
}
/**
* 计算环比-半年
* date 2022-1
*
* @return 2021-1
*/
public static String getHbHalfYear(String date) {
String[] dateArray = date.split("-");
int num = Integer.parseInt(dateArray[1]) - 1;
if (num > 0) {
return dateArray[0] + "-" + num;
}
int year = Integer.parseInt(dateArray[0]) - 1;
return year + "-" + 2;
}
/**
* 获取半年起始和结束时间
*
* @param year 年
* @param period 1 前半年 2 后半年
* @return DatePeriod
*/
public static DatePeriod getHalfYearRange(int year, int period) {
LocalDate startDate, endDate;
switch (period) {
case 1:
// 01.01-06.30
startDate = LocalDate.of(year, 1, 1);
endDate = LocalDate.of(year, 6, 30);
break;
case 2:
// 07.01-12.31
startDate = LocalDate.of(year, 7, 1);
endDate = LocalDate.of(year, 12, 31);
break;
default:
throw new RuntimeException("quarter range [1-4]");
}
return new DatePeriod(toDateString(startDate.atTime(LocalTime.MIN)), toDateString(endDate.atTime(LocalTime.MAX)));
}
/**
* 获取某半年的起始时间
*
* @param year 年
* @param period 周期 1 前半年 2 后半年
* @return
*/
public static String getHalfYearDayRangeStartTime(int year, int period) {
LocalDate startDate;
switch (period) {
case 1:
// 01.01-06.30
startDate = LocalDate.of(year, 1, 1);
break;
case 2:
// 07.01-12.31
startDate = LocalDate.of(year, 7, 1);
break;
default:
throw new RuntimeException("quarter range [1-4]");
}
return toDateString(startDate.atTime(LocalTime.MIN));
}
/**
* 获取半年结束时间
*
* @param year 年
* @param period 1 前半年 2 后半年
* @return DatePeriod
*/
public static String getHalfYearDayRangeEndTime(int year, int period) {
LocalDate endDate;
switch (period) {
case 1:
// 01.01-06.30
endDate = LocalDate.of(year, 6, 30);
break;
case 2:
// 07.01-12.31
endDate = LocalDate.of(year, 12, 31);
break;
default:
throw new RuntimeException("quarter range [1-4]");
}
return toDateString(endDate.atTime(LocalTime.MAX));
}
/**
* 获取某年月的第一天和最后一天
*
* @param year 年
* @param month 月
* @return DatePeriod
*/
public static DatePeriod getMonthDayRange(int year, int month) {
LocalDate localDate = LocalDate.of(year, month, 1);
// 获取当前月的第一天
LocalDate startDate = localDate.with(TemporalAdjusters.firstDayOfMonth());
// 获取当前月的最后一天
LocalDate endDate = localDate.with(TemporalAdjusters.lastDayOfMonth());
return new DatePeriod(toDateString(startDate.atTime(LocalTime.MIN)), toDateString(endDate.atTime(LocalTime.MAX)));
}
/**
* 获取某月的第一天
*
* @param year 年
* @param month 月
* @return 某月的第一天
*/
public static String getMonthDayRangeStartTime(int year, int month) {
LocalDate localDate = LocalDate.of(year, month, 1);
// 获取当前月的第一天
LocalDate startDate = localDate.with(TemporalAdjusters.firstDayOfMonth());
return toDateString(startDate.atTime(LocalTime.MIN));
}
/**
* 获取某月的最后一天
*
* @param year 年
* @param month 月
* @return 某月的最后一天
*/
public static String getMonthDayRangeEndTime(int year, int month) {
LocalDate localDate = LocalDate.of(year, month, 1);
// 获取当前月的最后一天
LocalDate endDate = localDate.with(TemporalAdjusters.lastDayOfMonth());
return toDateString(endDate.atTime(LocalTime.MAX));
}
/**
* 获取某年某季度的第一天和最后一天
*
* @param year 哪一年
* @param quarter 第几季度
* @return DatePeriod
*/
public static DatePeriod getQuarterDayRange(int year, int quarter) {
LocalDate startDate, endDate;
switch (quarter) {
case 1:
// 01.01-03.31
startDate = LocalDate.of(year, 1, 1);
endDate = LocalDate.of(year, 3, 31);
break;
case 2:
// 04.01-06.30
startDate = LocalDate.of(year, 4, 1);
endDate = LocalDate.of(year, 6, 30);
break;
case 3:
// 07.01-09.30
startDate = LocalDate.of(year, 7, 1);
endDate = LocalDate.of(year, 9, 30);
break;
case 4:
// 10.01-12.31
startDate = LocalDate.of(year, 10, 1);
endDate = LocalDate.of(year, 12, 31);
break;
default:
throw new RuntimeException("quarter range [1-4]");
}
return new DatePeriod(toDateString(startDate.atTime(LocalTime.MIN)), toDateString(endDate.atTime(LocalTime.MAX)));
}
/**
* 获取包含日期所在月份的所有月
*
* @param startDateTime 起始时间
* @param endDateTime 结束时间
* @return 月份集合 如: 2022-06、2022-07
*/
public static List<String> getMonthList(String startDateTime, String endDateTime) {
LocalDateTime startDateTimeLocal = toLocalDateTime(startDateTime);
LocalDateTime endDateTimeLocal = toLocalDateTime(endDateTime);
List<String> result = Lists.newArrayList();
long distance = ChronoUnit.MONTHS.between(startDateTimeLocal, endDateTimeLocal);
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM");
Stream.iterate(startDateTimeLocal, d -> d.plusMonths(1)).limit(distance + 1).forEach(f -> result.add(df.format(f)));
Collections.sort(result);
return result;
}
/**
* 获取季度集合
*
* @param startDateTime 起始时间
* @param endDateTime 结束时间
* @return 季度集合 如: 2022-01、2022-02
*/
public static List<String> getQuarterList(String startDateTime, String endDateTime) {
List<String> monthList = getMonthList(startDateTime, endDateTime);
List<String> result = Lists.newArrayList();
if (CollectionUtils.isEmpty(monthList)) {
return result;
}
Set<String> monthSet = Sets.newHashSet();
List<String> oneQuarter = Lists.newArrayList("01", "02", "03");
List<String> twoQuarter = Lists.newArrayList("04", "05", "06");
List<String> threeQuarter = Lists.newArrayList("07", "08", "09");
List<String> fourQuarter = Lists.newArrayList("10", "11", "12");
for (String month : monthList) {
String[] split = month.split("-");
String y = split[0];
String p = split[1];
if (oneQuarter.contains(p)) {
monthSet.add(y + "-1");
}
if (twoQuarter.contains(p)) {
monthSet.add(y + "-2");
}
if (threeQuarter.contains(p)) {
monthSet.add(y + "-3");
}
if (fourQuarter.contains(p)) {
monthSet.add(y + "-4");
}
}
result.addAll(monthSet);
Collections.sort(result);
return result;
}
/**
* 获取半年集合
*
* @param startDateTime 起始时间
* @param endDateTime 结束时间
* @return 半年集合 如: 2022-1、2022-2
*/
public static List<String> getHalfYearList(String startDateTime, String endDateTime) {
List<String> monthList = getMonthList(startDateTime, endDateTime);
List<String> result = Lists.newArrayList();
if (CollectionUtils.isEmpty(monthList)) {
return result;
}
Set<String> monthSet = Sets.newHashSet();
List<String> firstYear = Lists.newArrayList("01", "02", "03", "04", "05", "06");
List<String> lastYear = Lists.newArrayList("07", "08", "09", "10", "11", "12");
for (String month : monthList) {
String[] split = month.split("-");
String y = split[0];
String p = split[1];
if (firstYear.contains(p)) {
monthSet.add(y + "-1");
}
if (lastYear.contains(p)) {
monthSet.add(y + "-2");
}
}
result.addAll(monthSet);
Collections.sort(result);
return result;
}
/**
* 获取半年集合
* @param month 2022-01
* @return 半年集合
*/
public static String getQuarter(String month){
return getQuarterList(month + "-01 00:00:00", month + "-01 00:00:00").get(0);
}
/**
* 获取半年集合
* @param month 2022-01
* @return 半年集合
*/
public static String getHalfYear(String month){
return getHalfYearList(month + "-01 00:00:00", month + "-01 00:00:00").get(0);
}
/**
* 根据半年周期获取季度周期
* @param halfYearList 半年周期
* @return 季度周期
*/
public static List<String> getQuarterList(List<String> halfYearList) {
if (CollectionUtils.isEmpty(halfYearList)) {
return Lists.newArrayList();
}
List<String> result = new ArrayList<>();
for (String halfYear : halfYearList) {
int y = Integer.parseInt(halfYear.split("-")[0]);
int p = Integer.parseInt(halfYear.split("-")[1]);
DatePeriod halfYearRange = getHalfYearRange(y, p);
List<String> quarterList = getQuarterList(halfYearRange.getStartDateTime(), halfYearRange.getEndDateTime());
result.addAll(quarterList);
}
return result;
}
/**
* 根据季度周期获取月份周期
* @param quarterList 季度周期
* @return 月份周期
*/
public static List<String> getMonthList(List<String> quarterList) {
if (CollectionUtils.isEmpty(quarterList)) {
return Lists.newArrayList();
}
List<String> result = new ArrayList<>();
for (String quarter : quarterList) {
int y = Integer.parseInt(quarter.split("-")[0]);
int p = Integer.parseInt(quarter.split("-")[1]);
DatePeriod halfYearRange = getQuarterDayRange(y, p);
List<String> monthList = getMonthList(halfYearRange.getStartDateTime(), halfYearRange.getEndDateTime());
result.addAll(monthList);
}
return result;
}
public static LocalDateTime toLocalDateTime(String dateStr) {
DateTimeFormatter df = DateTimeFormatter.ofPattern(YYYY_MM_dd_HH_mm_ss);
LocalDateTime parse = LocalDateTime.parse(dateStr, df);
return parse;
}
public static String toDateString(LocalDateTime localDateTime) {
DateTimeFormatter df = DateTimeFormatter.ofPattern(YYYY_MM_dd_HH_mm_ss);
return df.format(localDateTime);
}
public static class DatePeriod implements Serializable {
private static final long serialVersionUID = 7704935152782849727L;
private String startDateTime;
private String endDateTime;
private String monthStart;
private String monthEnd;
public DatePeriod() {
}
public DatePeriod(String startDateTime, String endDateTime) {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime startLocalDateTime = LocalDateTime.parse(startDateTime, dateTimeFormatter);
LocalDateTime endDateLocalDateTime = LocalDateTime.parse(endDateTime, dateTimeFormatter);
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM");
this.startDateTime = startDateTime;
this.endDateTime = endDateTime;
this.monthStart = df.format(startLocalDateTime);
this.monthEnd = df.format(endDateLocalDateTime);
}
public static long getSerialVersionUID() {
return serialVersionUID;
}
public String getStartDateTime() {
return startDateTime;
}
public void setStartDateTime(String startDateTime) {
this.startDateTime = startDateTime;
}
public String getEndDateTime() {
return endDateTime;
}
public void setEndDateTime(String endDateTime) {
this.endDateTime = endDateTime;
}
public String getMonthStart() {
return monthStart;
}
public void setMonthStart(String monthStart) {
this.monthStart = monthStart;
}
public String getMonthEnd() {
return monthEnd;
}
public void setMonthEnd(String monthEnd) {
this.monthEnd = monthEnd;
}
}
/**
* YYYY_MM_DD
*/
public static final String YYYY_MM_DD = "yyyy-MM-dd";
/**
* 获取两个日期之间的所有日期
*
* @param pattern 日期格式
* @param startDate 开始日期
* @param endDate 结束日期
* @return Set<String>
*/
public static List<String> getDates(String pattern, Date startDate, Date endDate) {
List<String> result = new ArrayList<>();
Calendar startCalendar = Calendar.getInstance();
Calendar endCalendar = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat(pattern);
startCalendar.setTime(startDate);
endCalendar.setTime(endDate);
result.add(df.format(startCalendar.getTime()));
while (true) {
startCalendar.add(Calendar.DAY_OF_MONTH, 1);
if (startCalendar.getTimeInMillis() <= endCalendar.getTimeInMillis()) {
result.add(df.format(startCalendar.getTime()));
} else {
break;
}
}
return result;
}
}
2、问题报备
1)Calendar.DAY_OF_MONTH
、Calendar.DAY_OF_YEAR
、Calendar.DATE
cal1.add(Calendar.DAY_OF_MONTH,1);
cal1.add(Calendar.DAY_OF_YEAR,1);
cal1.add(Calendar.DATE,1);
⬤ 以上执行结果是一样的,但是一般情况下加减运算我们使用 cal1.add(Calendar.DATE,1);
⬤ 而其他两种的主要作用是用来获取数据的
Calendar.DAY_OF_YEAR
的主要作用是 cal.get(Calendar.DAY_OF_YEAR)
,用来获得这一天在是这个月的第多少天
Calendar.DAY_OF_YEAR
的主要作用是 cal.get(Calendar.DAY_OF_YEAR)
,用来获得这一天在是这个年的第多少天
3、工具类
package com.healerjean.proj.utils.date;
import com.google.common.collect.Lists;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Stream;
import static com.healerjean.proj.utils.date.DateUtils.TimeTool.toLocalDateTime;
/**
* DateUtils
*
* @author zhangyujin
* @date 2023/6/14 16:06
*/
public class DateUtils {
public static class TimeTool {
/**
* toDateString
*
* @param localDate localDate
* @return String
*/
public static String toDateString(LocalDate localDate) {
return toDateString(localDate, DateConstants.YYYY_MM_DD);
}
/**
* toDateString
*
* @param localDate localDate
* @param format format
* @return String
*/
public static String toDateString(LocalDate localDate, String format) {
return Optional.ofNullable(localDate).map(item -> DateTimeFormatter.ofPattern(format).format(item)).orElse(null);
}
/**
* toDateString
*
* @param localDateTime localDateTime
* @return String
*/
public static String toDateString(LocalDateTime localDateTime) {
return toDateString(localDateTime, DateConstants.YYYY_MM_DD_HH_MM_SS);
}
/**
* toDateString
*
* @param localDateTime localDateTime
* @param format format
* @return String
*/
public static String toDateString(LocalDateTime localDateTime, String format) {
return Optional.ofNullable(localDateTime).map(item -> item.format(DateTimeFormatter.ofPattern(format))).orElse(null);
}
/**
* toLocalDate
*
* @param dateStr dateStr
* @return LocalDate
*/
public static LocalDate toLocalDate(String dateStr) {
return toLocalDate(dateStr, DateConstants.YYYY_MM_DD);
}
/**
* toLocalDate
*
* @param dateStr dateStr
* @param format format
* @return LocalDate
*/
public static LocalDate toLocalDate(String dateStr, String format) {
return Optional.ofNullable(dateStr).map(item -> LocalDate.parse(item, DateTimeFormatter.ofPattern(format))).orElse(null);
}
/**
* toLocalDate
*
* @param date date
* @return LocalDate
*/
public static LocalDate toLocalDate(Date date) {
return Optional.ofNullable(date).map(item -> item.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()).orElse(null);
}
/**
* LocalDateTime
*
* @param dateStr dateStr
* @return toLocalDateTime
*/
public static LocalDateTime toLocalDateTime(String dateStr) {
return toLocalDateTime(dateStr, DateConstants.YYYY_MM_DD_HH_MM_SS);
}
/**
* LocalDateTime
*
* @param dateStr dateStr
* @param format format
* @return toLocalDateTime
*/
public static LocalDateTime toLocalDateTime(String dateStr, String format) {
return Optional.ofNullable(dateStr).map(item -> LocalDateTime.parse(item, DateTimeFormatter.ofPattern(format))).orElse(null);
}
/**
* toLocalDateTime
*
* @param date date
* @return LocalDateTime
*/
public static LocalDateTime toLocalDateTime(Date date) {
return Optional.ofNullable(date).map(item -> item.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime()).orElse(null);
}
/**
* toDate
*
* @param localDateTime localDateTime
* @return Date
*/
public static Date toDate(LocalDateTime localDateTime) {
return Optional.ofNullable(localDateTime).map(item -> Date.from(item.atZone(ZoneId.systemDefault()).toInstant())).orElse(null);
}
/**
* toDate
*
* @param localDate localDate
* @return Date
*/
public static Date toDate(LocalDate localDate) {
return Optional.ofNullable(localDate).map(item -> Date.from(item.atStartOfDay(ZoneId.systemDefault()).toInstant())).orElse(null);
}
}
public static class TimeExtTool {
/**
* 获取开始时间
*
* @param localDateTime localDateTime
* @return LocalDateTime
*/
public static LocalDateTime getFirstTime(LocalDateTime localDateTime, ChronoUnit chronoUnit) {
switch (chronoUnit) {
case MINUTES:
return localDateTime.withSecond(0).withNano(0);
case HOURS:
return localDateTime.withMinute(0).withSecond(0).withNano(0);
case DAYS:
return localDateTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
case MONTHS:
return localDateTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
case YEARS:
return localDateTime.withDayOfYear(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
default:
throw new IllegalArgumentException("field 无日期匹配类型");
}
}
/**
* 获取结束时间
*
* @param localDateTime localDateTime
* @return LocalDateTime
*/
public static LocalDateTime getEndTime(LocalDateTime localDateTime, ChronoUnit chronoUnit) {
switch (chronoUnit) {
case MINUTES:
return localDateTime.withSecond(59).withNano(0);
case HOURS:
return localDateTime.withMinute(59).withSecond(59).withNano(0);
case DAYS:
return localDateTime.withHour(23).withMinute(59).withSecond(59).withNano(0);
case MONTHS:
return localDateTime.withDayOfMonth(localDateTime.getMonth().length(Year.isLeap(localDateTime.getYear()))).withHour(23).withMinute(59).withSecond(59).withNano(0);
case YEARS:
return localDateTime.with(TemporalAdjusters.lastDayOfYear()).with(LocalTime.MAX);
default:
throw new IllegalArgumentException("field 无日期匹配类型");
}
}
/**
* roll
*
* @param localDateTime localDateTime
* @param field field
* @param num num
* @return {@link LocalDateTime}
*/
public static LocalDateTime minusRoll(LocalDateTime localDateTime, ChronoUnit field, int num) {
return localDateTime.minus(num, field);
}
/**
* roll
*
* @param localDateTime localDateTime
* @param field field
* @param num num
* @return {@link LocalDateTime}
*/
public static LocalDateTime plusRoll(LocalDateTime localDateTime, ChronoUnit field, int num) {
return localDateTime.plus(num, field);
}
/**
* 获取包含日期所在月份的所有月
*
* @param startDateTime 起始时间
* @param endDateTime 结束时间
* @return 月份集合 如: 2022-06、2022-07
*/
public static List<String> getDates(String startDateTime, String endDateTime, ChronoUnit chronoUnit, String format) {
LocalDateTime startDateTimeLocal = toLocalDateTime(startDateTime);
LocalDateTime endDateTimeLocal = toLocalDateTime(endDateTime);
List<String> result = Lists.newArrayList();
long distance = chronoUnit.between(startDateTimeLocal, endDateTimeLocal);
DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
switch (chronoUnit) {
case MINUTES:
Stream.iterate(startDateTimeLocal, d -> d.plusMinutes(1)).limit(distance + 1).forEach(f -> result.add(df.format(f)));
break;
case HOURS:
Stream.iterate(startDateTimeLocal, d -> d.plusHours(1)).limit(distance + 1).forEach(f -> result.add(df.format(f)));
break;
case DAYS:
Stream.iterate(startDateTimeLocal, d -> d.plusDays(1)).limit(distance + 1).forEach(f -> result.add(df.format(f)));
break;
case MONTHS:
Stream.iterate(startDateTimeLocal, d -> d.plusMonths(1)).limit(distance + 1).forEach(f -> result.add(df.format(f)));
break;
case YEARS:
Stream.iterate(startDateTimeLocal, d -> d.plusYears(1)).limit(distance + 1).forEach(f -> result.add(df.format(f)));
break;
default:
throw new IllegalArgumentException("field 无日期匹配类型");
}
Collections.sort(result);
return result;
}
public static void main(String[] args) {
// TimeExtTool.getFirstTime
LocalDateTime dateTime = LocalDateTime.of(2023, 10, 23, 20, 23, 21); // 示例日期时间
System.out.println("TimeExtTool.getFirstTime" + DateUtils.TimeTool.toDateString(dateTime));
System.out.println(DateUtils.TimeTool.toDateString(getFirstTime(dateTime, ChronoUnit.MINUTES)));
System.out.println(DateUtils.TimeTool.toDateString(getFirstTime(dateTime, ChronoUnit.HOURS)));
System.out.println(DateUtils.TimeTool.toDateString(getFirstTime(dateTime, ChronoUnit.DAYS)));
System.out.println(DateUtils.TimeTool.toDateString(getFirstTime(dateTime, ChronoUnit.MONTHS)));
System.out.println(DateUtils.TimeTool.toDateString(getFirstTime(dateTime, ChronoUnit.YEARS)));
System.out.println();
System.out.println("TimeExtTool.getFirstTime" + DateUtils.TimeTool.toDateString(dateTime));
System.out.println(DateUtils.TimeTool.toDateString(dateTime));
System.out.println(DateUtils.TimeTool.toDateString(getEndTime(dateTime, ChronoUnit.MINUTES)));
System.out.println(DateUtils.TimeTool.toDateString(getEndTime(dateTime, ChronoUnit.HOURS)));
System.out.println(DateUtils.TimeTool.toDateString(getEndTime(dateTime, ChronoUnit.DAYS)));
System.out.println(DateUtils.TimeTool.toDateString(getEndTime(dateTime, ChronoUnit.MONTHS)));
System.out.println(DateUtils.TimeTool.toDateString(getEndTime(dateTime, ChronoUnit.YEARS)));
System.out.println();
System.out.println("TimeExtTool.minusRoll" + DateUtils.TimeTool.toDateString(dateTime));
System.out.println(DateUtils.TimeTool.toDateString(minusRoll(dateTime, ChronoUnit.DAYS, 1)));
System.out.println();
System.out.println("TimeExtTool.plusRoll" + DateUtils.TimeTool.toDateString(dateTime));
System.out.println(DateUtils.TimeTool.toDateString(plusRoll(dateTime, ChronoUnit.DAYS, 1)));
System.out.println();
System.out.println("TimeExtTool.getDates" + DateUtils.TimeTool.toDateString(dateTime));
LocalDateTime startDate = LocalDateTime.of(2023, 10, 23, 20, 23, 21); // 示例日期时间
LocalDateTime endDate = LocalDateTime.of(2023, 11, 23, 20, 23, 21); // 示例日期时间
System.out.println(getDates(TimeTool.toDateString(startDate), TimeTool.toDateString(endDate), ChronoUnit.DAYS, DateConstants.YYYY_MM_DD));
System.out.println(getDates(TimeTool.toDateString(startDate), TimeTool.toDateString(endDate), ChronoUnit.MONTHS, DateConstants.YYYY_MM));
}
}
public static class DateTool {
/**
* toDateString
*
* @param date date
* @param pattern pattern
* @return {@link String}
*/
public static String toDateString(Date date, String pattern) {
SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
return dateFormat.format(date);
}
/**
* toDate
*
* @param dateStr dateStr
* @param pattern pattern
* @return {@link Date}
*/
public static Date toDate(String dateStr, String pattern) {
SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
try {
return dateFormat.parse(dateStr);
} catch (ParseException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
/**
* longToDate
*
* @param longDate longDate
* @return {@link Date}
*/
public static Date longToDate(Long longDate) {
if (longDate == null) {
return null;
}
return new Date(longDate);
}
}
public static class DateExtTool {
/**
* getFirstTime
*
* @return Date
*/
public static Date getFirstTime(Date date, int field) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
switch (field) {
//1、获取小时的最初时间
case Calendar.HOUR:
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
case Calendar.DATE:
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
case Calendar.MONTH:
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
case Calendar.YEAR:
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_YEAR, cal.getActualMinimum(Calendar.DAY_OF_YEAR));
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
default:
throw new RuntimeException("field 无日期匹配类型");
}
}
/**
* getEndTime
*
* @return Date
*/
public static Date getEndTime(Date date, int field) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
switch (field) {
//1、获取小时的最后时间
case Calendar.HOUR:
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
case Calendar.DATE:
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
case Calendar.MONTH:
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
case Calendar.YEAR:
cal.set(Calendar.MONTH, Calendar.DECEMBER);
cal.set(Calendar.DAY_OF_YEAR, cal.getActualMaximum(Calendar.DAY_OF_YEAR));
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
default:
throw new RuntimeException("field 无日期匹配类型");
}
}
/**
* roll
*
* @param date date
* @param field field
* @param num num
* @return {@link Date}
*/
public static Date roll(Date date, int field, int num) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(field, num);
return cal.getTime();
}
}
}