日期时间工具类
示例代码:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static java.time.temporal.ChronoUnit.WEEKS;
/**
* 日期时间工具类
*/
public final class DateTimeUtil {
private DateTimeUtil() {
}
private static final Logger logger = LoggerFactory.getLogger(DateTimeUtil.class);
/**
* 显示年月日时分秒,例如 2015-08-11 09:51:53.
*/
public static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
/**
* 显示年月日时分秒(无符号),例如 20150811095153.
*/
public static final String UNSIGNED_DATETIME_PATTERN = "yyyyMMddHHmmss";
/**
* 仅显示年月日,例如 2015-08-11.
*/
public static final String DATE_PATTERN = "yyyy-MM-dd";
/**
* 仅显示年月日(无符号),例如 20150811.
*/
public static final String UNSIGNED_DATE_PATTERN = "yyyyMMdd";
/**
* 仅显示年月,例如 2015-08.
*/
public static final String MONTH_PATTERN = "yyyy-MM";
/**
* 仅显示年月(无符号),例如 201508.
*/
public static final String UNSIGNED_MONTH_PATTERN = "yyyyMM";
/**
* 仅显示时分秒,例如 09:51:53.
*/
public static final String TIME_PATTERN = "HH:mm:ss";
/**
* 一天的开始时间, 主要用于拼接日期时间
*/
public static final String DAY_START_TIME_STR = " 00:00:00";
/**
* 一天的结束时间, 主要用于拼接日期时间
*/
public static final String DAY_END_TIME_STR = " 23:59:59";
/**
* 春天;
*/
public static final Integer SPRING = 1;
/**
* 夏天;
*/
public static final Integer SUMMER = 2;
/**
* 秋天;
*/
public static final Integer AUTUMN = 3;
/**
* 冬天;
*/
public static final Integer WINTER = 4;
/**
* 星期日;
*/
public static final String SUNDAY = "星期日";
/**
* 星期一;
*/
public static final String MONDAY = "星期一";
/**
* 星期二;
*/
public static final String TUESDAY = "星期二";
/**
* 星期三;
*/
public static final String WEDNESDAY = "星期三";
/**
* 星期四;
*/
public static final String THURSDAY = "星期四";
/**
* 星期五;
*/
public static final String FRIDAY = "星期五";
/**
* 星期六;
*/
public static final String SATURDAY = "星期六";
/**
* 年
*/
public static final String YEAR = "year";
/**
* 月
*/
public static final String MONTH = "month";
/**
* 周
*/
public static final String WEEK = "week";
/**
* 日
*/
public static final String DAY = "day";
/**
* 时
*/
public static final String HOUR = "hour";
/**
* 分
*/
public static final String MINUTE = "minute";
/**
* 秒
*/
public static final String SECOND = "second";
public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern(DATETIME_PATTERN);
public static final DateTimeFormatter UNSIGNED_DATETIME_FORMATTER = DateTimeFormatter.ofPattern(UNSIGNED_DATETIME_PATTERN);
public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DATE_PATTERN);
public static final DateTimeFormatter UNSIGNED_DATE_FORMATTER = DateTimeFormatter.ofPattern(UNSIGNED_DATE_PATTERN);
public static final DateTimeFormatter MONTH_FORMATTER = DateTimeFormatter.ofPattern(MONTH_PATTERN);
public static final DateTimeFormatter UNSIGNED_MONTH_FORMATTER = DateTimeFormatter.ofPattern(UNSIGNED_MONTH_PATTERN);
public static final DateTimeFormatter TIME_PATTERN_FORMATTER = DateTimeFormatter.ofPattern(TIME_PATTERN);
private static Map<String, ThreadLocal<SimpleDateFormat>> localSimpleDateFormatMap = new ConcurrentHashMap<>();
static {
localSimpleDateFormatMap.put(DATETIME_PATTERN, ThreadLocal.withInitial(() -> new SimpleDateFormat(DATETIME_PATTERN)));
localSimpleDateFormatMap.put(UNSIGNED_DATETIME_PATTERN, ThreadLocal.withInitial(() -> new SimpleDateFormat(UNSIGNED_DATETIME_PATTERN)));
localSimpleDateFormatMap.put(DATE_PATTERN, ThreadLocal.withInitial(() -> new SimpleDateFormat(DATE_PATTERN)));
localSimpleDateFormatMap.put(UNSIGNED_DATE_PATTERN, ThreadLocal.withInitial(() -> new SimpleDateFormat(UNSIGNED_DATE_PATTERN)));
localSimpleDateFormatMap.put(MONTH_PATTERN, ThreadLocal.withInitial(() -> new SimpleDateFormat(MONTH_PATTERN)));
localSimpleDateFormatMap.put(UNSIGNED_MONTH_PATTERN, ThreadLocal.withInitial(() -> new SimpleDateFormat(UNSIGNED_MONTH_PATTERN)));
}
/**
* 获取本地变量ThreadLocal
*
* @param pattern 时间格式
* @return
*/
public static ThreadLocal<SimpleDateFormat> getLocalSimpleDateFormat(String pattern) {
return localSimpleDateFormatMap.get(pattern);
}
/**
* 获取当前日期和时间字符串.
*
* @return String 日期时间字符串,例如 2015-08-11 09:51:53
*/
public static String getLocalDateTimeStr() {
return format(LocalDateTime.now(), DATETIME_PATTERN);
}
/**
* 获取当前日期字符串.
*
* @return String 日期字符串,例如2015-08-11
*/
public static String getLocalDateStr() {
return format(LocalDate.now(), DATE_PATTERN);
}
/**
* 获取当前时间字符串.
*
* @return String 时间字符串,例如 09:51:53
*/
public static String getLocalTimeStr() {
return format(LocalTime.now(), TIME_PATTERN);
}
/**
* 获取当前星期字符串.
*
* @return String 当前星期字符串,例如 星期二
*/
public static String getDayOfWeekStr() {
return format(LocalDate.now(), "E");
}
/**
* 获取指定日期是星期几
*
* @param localDate 日期
* @return String 星期几
*/
public static String getDayOfWeekStr(LocalDate localDate) {
String[] weekOfDays = {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY};
int dayOfWeek = localDate.getDayOfWeek().getValue() - 1;
return weekOfDays[dayOfWeek];
}
/**
* 获取日期时间字符串
*
* @param temporal 需要转化的日期时间
* @param pattern 时间格式
* @return String 日期时间字符串,例如 2015-08-11 09:51:53
*/
public static String format(TemporalAccessor temporal, String pattern) {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
return dateTimeFormatter.format(temporal);
}
/**
* 获取日期时间字符串
*
* @param date 需要转化的日期时间
* @param pattern 时间格式
* @return String 日期时间字符串,例如 2015-08-11 09:51:53
*/
public static String format(Date date, String pattern) {
ThreadLocal<SimpleDateFormat> formatThreadLocal = getLocalSimpleDateFormat(pattern);
String dateStr = formatThreadLocal.get().format(date);
formatThreadLocal.remove();
return dateStr;
}
/**
* 日期时间字符串转换为日期时间(java.time.LocalDateTime)
*
* @param localDateTimeStr 日期时间字符串
* @param pattern 日期时间格式 例如DATETIME_PATTERN
* @return LocalDateTime 日期时间
*/
public static LocalDateTime parseLocalDateTime(String localDateTimeStr, String pattern) {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
return LocalDateTime.parse(localDateTimeStr, dateTimeFormatter);
}
/**
* 日期字符串转换为日期(java.time.LocalDate)
*
* @param localDateStr 日期字符串
* @param pattern 日期格式 例如DATE_PATTERN
* @return LocalDate 日期
*/
public static LocalDate parseLocalDate(String localDateStr, String pattern) {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
return LocalDate.parse(localDateStr, dateTimeFormatter);
}
/**
* 日期时间字符串转换为日期时间
*
* @param dateTimeStr 日期时间字符串
* @param pattern 日期时间格式 例如DATETIME_PATTERN
* @return LocalDateTime 日期时间
*/
public static Date parseDate(String dateTimeStr, String pattern) {
ThreadLocal<SimpleDateFormat> formatThreadLocal = getLocalSimpleDateFormat(pattern);
Date date = null;
try {
date = formatThreadLocal.get().parse(dateTimeStr);
} catch (ParseException e) {
logger.error("DateTimeUtil.parseDate occur exception:{}", e.getMessage(), e);
}
formatThreadLocal.remove();
return date;
}
/**
* 获取指定日期时间加上指定数量日期时间单位之后的日期时间.
*
* @param localDateTime 日期时间
* @param num 数量
* @param chronoUnit 日期时间单位
* @return LocalDateTime 新的日期时间
*/
public static LocalDateTime plus(LocalDateTime localDateTime, int num, ChronoUnit chronoUnit) {
return localDateTime.plus(num, chronoUnit);
}
/**
* 获取指定日期时间减去指定数量日期时间单位之后的日期时间.
*
* @param localDateTime 日期时间
* @param num 数量
* @param chronoUnit 日期时间单位
* @return LocalDateTime 新的日期时间
*/
public static LocalDateTime minus(LocalDateTime localDateTime, int num, ChronoUnit chronoUnit) {
return localDateTime.minus(num, chronoUnit);
}
/**
* 根据ChronoUnit计算两个日期时间之间相隔日期时间
*
* @param start 开始日期时间
* @param end 结束日期时间
* @param chronoUnit 日期时间单位
* @return long 相隔日期时间
*/
public static long getChronoUnitBetween(LocalDateTime start, LocalDateTime end, ChronoUnit chronoUnit) {
return Math.abs(start.until(end, chronoUnit));
}
/**
* 根据ChronoUnit计算两个日期之间相隔年数或月数或天数
*
* @param start 开始日期
* @param end 结束日期
* @param chronoUnit 日期时间单位,(ChronoUnit.YEARS,ChronoUnit.MONTHS,ChronoUnit.WEEKS,ChronoUnit.DAYS)
* @return long 相隔年数或月数或天数
*/
public static long getChronoUnitBetween(LocalDate start, LocalDate end, ChronoUnit chronoUnit) {
return Math.abs(start.until(end, chronoUnit));
}
/**
* 获取本年第一天的日期字符串
*
* @return String 格式:yyyy-MM-dd 00:00:00
*/
public static String getFirstDayOfYearStr() {
return getFirstDayOfYearStr(LocalDateTime.now());
}
/**
* 获取本年最后一天的日期字符串
*
* @return String 格式:yyyy-MM-dd 23:59:59
*/
public static String getLastDayOfYearStr() {
return getLastDayOfYearStr(LocalDateTime.now());
}
/**
* 获取指定日期当年第一天的日期字符串
*
* @param localDateTime 指定日期时间
* @return String 格式:yyyy-MM-dd 00:00:00
*/
public static String getFirstDayOfYearStr(LocalDateTime localDateTime) {
return getFirstDayOfYearStr(localDateTime, DATETIME_PATTERN);
}
/**
* 获取指定日期当年最后一天的日期字符串
*
* @param localDateTime 指定日期时间
* @return String 格式:yyyy-MM-dd 23:59:59
*/
public static String getLastDayOfYearStr(LocalDateTime localDateTime) {
return getLastDayOfYearStr(localDateTime, DATETIME_PATTERN);
}
/**
* 获取指定日期当年第一天的日期字符串,带日期格式化参数
*
* @param localDateTime 指定日期时间
* @param pattern 日期时间格式
* @return String 格式:yyyy-MM-dd 00:00:00
*/
public static String getFirstDayOfYearStr(LocalDateTime localDateTime, String pattern) {
return format(localDateTime.withDayOfYear(1).withHour(0).withMinute(0).withSecond(0), pattern);
}
/**
* 获取指定日期当年最后一天的日期字符串,带日期格式化参数
*
* @param localDateTime 指定日期时间
* @param pattern 日期时间格式
* @return String 格式:yyyy-MM-dd 23:59:59
*/
public static String getLastDayOfYearStr(LocalDateTime localDateTime, String pattern) {
return format(localDateTime.with(TemporalAdjusters.lastDayOfYear()).withHour(23).withMinute(59).withSecond(59), pattern);
}
/**
* 获取本月第一天的日期字符串
*
* @return String 格式:yyyy-MM-dd 00:00:00
*/
public static String getFirstDayOfMonthStr() {
return getFirstDayOfMonthStr(LocalDateTime.now());
}
/**
* 获取本月最后一天的日期字符串
*
* @return String 格式:yyyy-MM-dd 23:59:59
*/
public static String getLastDayOfMonthStr() {
return getLastDayOfMonthStr(LocalDateTime.now());
}
/**
* 获取指定日期当月第一天的日期字符串
*
* @param localDateTime 指定日期时间
* @return String 格式:yyyy-MM-dd 23:59:59
*/
public static String getFirstDayOfMonthStr(LocalDateTime localDateTime) {
return getFirstDayOfMonthStr(localDateTime, DATETIME_PATTERN);
}
/**
* 获取指定日期当月最后一天的日期字符串
*
* @param localDateTime 指定日期时间
* @return String 格式:yyyy-MM-dd 23:59:59
*/
public static String getLastDayOfMonthStr(LocalDateTime localDateTime) {
return getLastDayOfMonthStr(localDateTime, DATETIME_PATTERN);
}
/**
* 获取指定日期当月第一天的日期字符串,带日期格式化参数
*
* @param localDateTime 指定日期时间
* @return String 格式:yyyy-MM-dd 00:00:00
*/
public static String getFirstDayOfMonthStr(LocalDateTime localDateTime, String pattern) {
return format(localDateTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0), pattern);
}
/**
* 获取指定日期当月最后一天的日期字符串,带日期格式化参数
*
* @param localDateTime 指定日期时间
* @param pattern 日期时间格式
* @return String 格式:yyyy-MM-dd 23:59:59
*/
public static String getLastDayOfMonthStr(LocalDateTime localDateTime, String pattern) {
return format(localDateTime.with(TemporalAdjusters.lastDayOfMonth()).withHour(23).withMinute(59).withSecond(59), pattern);
}
/**
* 获取本周第一天的日期字符串
*
* @return String 格式:yyyy-MM-dd 00:00:00
*/
public static String getFirstDayOfWeekStr() {
return getFirstDayOfWeekStr(LocalDateTime.now());
}
/**
* 获取本周最后一天的日期字符串
*
* @return String 格式:yyyy-MM-dd 23:59:59
*/
public static String getLastDayOfWeekStr() {
return getLastDayOfWeekStr(LocalDateTime.now());
}
/**
* 获取指定日期当周第一天的日期字符串,这里第一天为周一
*
* @param localDateTime 指定日期时间
* @return String 格式:yyyy-MM-dd 00:00:00
*/
public static String getFirstDayOfWeekStr(LocalDateTime localDateTime) {
return getFirstDayOfWeekStr(localDateTime, DATETIME_PATTERN);
}
/**
* 获取指定日期当周最后一天的日期字符串,这里最后一天为周日
*
* @param localDateTime 指定日期时间
* @return String 格式:yyyy-MM-dd 23:59:59
*/
public static String getLastDayOfWeekStr(LocalDateTime localDateTime) {
return getLastDayOfWeekStr(localDateTime, DATETIME_PATTERN);
}
/**
* 获取指定日期当周第一天的日期字符串,这里第一天为周一,带日期格式化参数
*
* @param localDateTime 指定日期时间
* @param pattern 日期时间格式
* @return String 格式:yyyy-MM-dd 00:00:00
*/
public static String getFirstDayOfWeekStr(LocalDateTime localDateTime, String pattern) {
return format(localDateTime.with(DayOfWeek.MONDAY).withHour(0).withMinute(0).withSecond(0), pattern);
}
/**
* 获取指定日期当周最后一天的日期字符串,这里最后一天为周日,带日期格式化参数
*
* @param localDateTime 指定日期时间
* @param pattern 日期时间格式
* @return String 格式:yyyy-MM-dd 23:59:59
*/
public static String getLastDayOfWeekStr(LocalDateTime localDateTime, String pattern) {
return format(localDateTime.with(DayOfWeek.SUNDAY).withHour(23).withMinute(59).withSecond(59), pattern);
}
/**
* 获取今天开始时间的日期字符串
*
* @return String 格式:yyyy-MM-dd 00:00:00
*/
public static String getStartTimeOfDayStr() {
return getStartTimeOfDayStr(LocalDateTime.now());
}
/**
* 获取今天结束时间的日期字符串
*
* @return String 格式:yyyy-MM-dd 23:59:59
*/
public static String getEndTimeOfDayStr() {
return getEndTimeOfDayStr(LocalDateTime.now());
}
/**
* 获取指定日期开始时间的日期字符串
*
* @param localDateTime 指定日期时间
* @return String 格式:yyyy-MM-dd 00:00:00
*/
public static String getStartTimeOfDayStr(LocalDateTime localDateTime) {
return getStartTimeOfDayStr(localDateTime, DATETIME_PATTERN);
}
/**
* 获取指定日期结束时间的日期字符串
*
* @param localDateTime 指定日期时间
* @return String 格式:yyyy-MM-dd 23:59:59
*/
public static String getEndTimeOfDayStr(LocalDateTime localDateTime) {
return getEndTimeOfDayStr(localDateTime, DATETIME_PATTERN);
}
/**
* 获取指定日期开始时间的日期字符串,带日期格式化参数
*
* @param localDateTime 指定日期时间
* @param pattern 日期时间格式
* @return String 格式:yyyy-MM-dd HH:mm:ss
*/
public static String getStartTimeOfDayStr(LocalDateTime localDateTime, String pattern) {
return format(localDateTime.withHour(0).withMinute(0).withSecond(0), pattern);
}
/**
* 获取指定日期结束时间的日期字符串,带日期格式化参数
*
* @param localDateTime 指定日期时间
* @param pattern 日期时间格式
* @return String 格式:yyyy-MM-dd 23:59:59
*/
public static String getEndTimeOfDayStr(LocalDateTime localDateTime, String pattern) {
return format(localDateTime.withHour(23).withMinute(59).withSecond(59), pattern);
}
/**
* LocalDate 转 Date
*
* @param localDate
* @return
*/
public static Date asDate(LocalDate localDate) {
return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
}
/**
* LocalDateTime 转 Date
*
* @param localDateTime
* @return
*/
public static Date asDate(LocalDateTime localDateTime) {
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
/**
* Date 转 LocalDate
*
* @param date
* @return
*/
public static LocalDate asLocalDate(Date date) {
return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
}
/**
* Date 转LocalDateTime
*
* @param date
* @return
*/
public static LocalDateTime asLocalDateTime(Date date) {
return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
}
/**
* Timestamp转LocalDateTime(mysql中datetime数据取出时是timestamp类型)
*
* @param timestamp
* @return
*/
public static LocalDateTime asLocalDateTime(Timestamp timestamp) {
return LocalDateTime.ofInstant(timestamp.toInstant(), ZoneId.systemDefault());
}
/**
* LocalDateTime转Timestamp
*
* @param localDateTime
* @return
*/
public static Timestamp asTimestamp(LocalDateTime localDateTime) {
return Timestamp.valueOf(localDateTime);
}
/**
* LocalDate转LocalDateTime
*
* @param localDate
* @return
*/
public static LocalDateTime asLocalDateTime(LocalDate localDate) {
return localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toLocalDateTime();
}
/**
* LocalDateTime转LocalDate
*
* @param localDateTime
* @return
*/
public static LocalDate asLocalDate(LocalDateTime localDateTime) {
return localDateTime.toLocalDate();
}
/**
* 获取最近的几天
*
* @param day yyyy-MM-dd 为空则去当前
* @param number 数量
* @param format 格式,默认是yyyy-MM-dd,支持yyyy-MM-dd和yyyyMMdd
* @param inclusion 是否包含当天
* @return
*/
public static List<String> getLastDayMonths(String day, Integer number, String format, boolean inclusion) {
List<String> dateList = new ArrayList();
LocalDate endDate = LocalDate.now();
if (day != null && !"".equals(day)) {
endDate = LocalDate.parse(day, DATE_FORMATTER);
}
if (UNSIGNED_DATE_PATTERN.equals(format)) {
for (int i = number - 1; i >= 0; i--) {
dateList.add(UNSIGNED_DATE_FORMATTER.format(endDate.minusDays(i)));
}
} else {
for (int i = number - 1; i >= 0; i--) {
dateList.add(DATE_FORMATTER.format(endDate.minusDays(i)));
}
}
if (!inclusion) {
dateList = dateList.subList(0, dateList.size() - 1);
}
return dateList;
}
/**
* 获取最近的几个月
*
* @param yearMonthStr yyyy-MM 为空则取当前月
* @param number 数量
* @param format 格式, 为空则为 yyyy-MM,支持yyyy-MM和yyyyMM
* @param inclusion 是否包含当月
* @return yyyyMM
*/
public static List<String> getLastYearMonths(String yearMonthStr, Integer number, String format, boolean inclusion) {
List<String> monthList = new ArrayList();
YearMonth yearMonth = YearMonth.now();
if (yearMonthStr != null && !"".equals(yearMonthStr)) {
yearMonth = YearMonth.parse(yearMonthStr, MONTH_FORMATTER);
}
if (UNSIGNED_MONTH_PATTERN.equals(format)) {
for (int i = number - 1; i >= 0; i--) {
monthList.add(UNSIGNED_MONTH_FORMATTER.format(yearMonth.minusMonths(i)));
}
} else {
for (int i = number - 1; i >= 0; i--) {
monthList.add(MONTH_FORMATTER.format(yearMonth.minusMonths(i)));
}
}
if (!inclusion) {
monthList = monthList.subList(0, monthList.size() - 1);
}
return monthList;
}
/**
* 获取两个日期之间的所有日期 (yyyy-MM-dd)
*
* @param startTime, 如2022-02-26
* @param endTime, 如2022-03-09
* @return
*/
public static List<String> getBetweenDate(String startTime, String endTime) {
// 声明保存日期集合
List<String> list = new ArrayList();
LocalDate start = LocalDate.parse(startTime, DATE_FORMATTER);
LocalDate end = LocalDate.parse(endTime, DATE_FORMATTER);
while (start.isBefore(end) || start.isEqual(end)) {
list.add(start.toString());
start = start.plusDays(1);
}
return list;
}
/**
* 获取两月之间的所有月份(yyyy-MM)
*
* @param minDate yyyy-MM-dd
* @param maxDate yyyy-MM-dd
* @return
*/
public static List<String> getMonthBetween(String minDate, String maxDate) {
ArrayList<String> result = new ArrayList<String>();
SimpleDateFormat sdf = new SimpleDateFormat(MONTH_PATTERN);//格式化为年月
Calendar min = Calendar.getInstance();
Calendar max = Calendar.getInstance();
try {
min.setTime(sdf.parse(minDate));
min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
max.setTime(sdf.parse(maxDate));
max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
} catch (Exception e) {
logger.error("getMonthBetween occur exception:{}", e.getMessage(), e);
}
Calendar curr = min;
while (curr.before(max)) {
result.add(sdf.format(curr.getTime()));
curr.add(Calendar.MONTH, 1);
}
return result;
}
/**
* 将某个日期的指定时间段按day/1小时/2小时的等划分
*
* @param day yyyy-MM-dd
* @param startTime 00:00
* @param endTime 08:00
* @param type 目前支持one_hour、two_hour, 可以自改造
* @return key:00:00-08:00 value: 2022-07-22 00:00:00,2022-07-22 01:59:59
*/
public static Map<String, Object> getTimeIntervalByDay(String day, String startTime, String endTime, String type) {
String startDateTime = day + " " + startTime + ":00";
String endDateTime = day + " " + endTime + ":00";
LocalDateTime start = LocalDateTime.parse(startDateTime, DATETIME_FORMATTER);
LocalDateTime end = LocalDateTime.parse(endDateTime, DATETIME_FORMATTER);
Map<String, Object> timeIntervalMap = new LinkedHashMap();
int plusSecond;
int checkSecondPoint;
switch (type) {
case "one_hour":
plusSecond = 60 * 60;
checkSecondPoint = 60 * 60;
break;
case "two_hour":
plusSecond = 2 * 60 * 60;
checkSecondPoint = 2 * 60 * 60;
break;
default:
plusSecond = 24 * 60 * 60;
checkSecondPoint = 24 * 60 * 60;
}
LocalDateTime tempEndDateTime = null;
while (start.isBefore(end)) {
String dateTimeValueStart = DATETIME_FORMATTER.format(start);
String timeKeyStart = dateTimeValueStart.substring(11, 16);
//判断是否满足条件
if (ChronoUnit.SECONDS.between(start, end) <= checkSecondPoint) {
tempEndDateTime = end;
} else {
tempEndDateTime = start.plusSeconds(plusSecond);
}
String timeKeyEnd = DATETIME_FORMATTER.format(tempEndDateTime).substring(11, 16);
if (ChronoUnit.SECONDS.between(tempEndDateTime, end) == 0) { //临界值
if ("00:00".equals(timeKeyEnd)) {
timeKeyEnd = "24:00";
}
}
String dateTimeValueEnd = DATETIME_FORMATTER.format(tempEndDateTime.minusSeconds(1));
timeIntervalMap.put(timeKeyStart + "-" + timeKeyEnd, dateTimeValueStart + "," + dateTimeValueEnd);
start = tempEndDateTime;
}
return timeIntervalMap;
}
/**
* 获取两个时间段的时间段值
*
* @param startTime 开始时间戳
* @param endTime 结束时间戳
* @param timeType 时间类型, YEAR、MONTH、DAY
* @return
*/
public static List<String> getTimePeriodFromTwoTime(Long startTime, Long endTime, String timeType) {
LocalDate start = Instant.ofEpochMilli(startTime).atZone(ZoneOffset.ofHours(8)).toLocalDate();
LocalDate end = Instant.ofEpochMilli(endTime).atZone(ZoneOffset.ofHours(8)).toLocalDate();
List<String> result = new ArrayList<>();
// 年
if ("YEAR".equals(timeType)) {
Year startYear = Year.from(start);
Year endYear = Year.from(end);
// 包含最后一个时间
for (long i = 0; i <= ChronoUnit.YEARS.between(startYear, endYear); i++) {
result.add(startYear.plusYears(i).toString());
}
}
// 月
else if ("MONTH".equals(timeType)) {
YearMonth from = YearMonth.from(start);
YearMonth to = YearMonth.from(end);
for (long i = 0; i <= ChronoUnit.MONTHS.between(from, to); i++) {
result.add(from.plusMonths(i).toString());
}
}
// 日
else {
for (long i = 0; i <= ChronoUnit.DAYS.between(start, end); i++) {
result.add(start.plus(i, ChronoUnit.DAYS).toString());
}
}
return result;
}
/**
* 两个日期之间的周数
*
* @param startDate
* @param endDate
* @return
*/
public static List<String> numberOfWeeks(LocalDateTime startDate, LocalDateTime endDate) {
int addWeek = 0;
TemporalField tf = WeekFields.SUNDAY_START.weekOfYear();
if (startDate.get(tf) < endDate.get(tf)) {
addWeek = 1;
}
long weeks = WEEKS.between(startDate, endDate) + addWeek;
List<String> numberWeeks = new ArrayList<>();
if (weeks >= 0) {
int week = 0;
do {
//Get the number of week
LocalDateTime dt = startDate.plusWeeks(week);
int weekNumber = dt.get(tf);
numberWeeks.add(String.format("%d-W%d", dt.getYear(), weekNumber)); //2018-W34
week++;
} while (week <= weeks);
}
return numberWeeks;
}
/**
* 获取昨天日期字符串
*
* @param format 不传则是 yyyy-MM-dd
* @return
**/
public static String getYesterdayDateStr(String format) {
if (format == null || "".equals(format)) {
format = DATE_PATTERN;
}
return format(LocalDate.now().minusDays(1), format);
}
/**
* 获取形如时间轴的格式:xx秒前, xx分钟前, xxx小时前, 1年前
**/
public static String getFormatDateLine(Date datetime) {
String timeText = "";
YearMonth yearMonth = YearMonth.now();
LocalDate localDate = asLocalDate(datetime);
LocalDateTime localDateTime = asLocalDateTime(datetime);
LocalDateTime currentDateTime = LocalDateTime.now();
if (localDate.isEqual(LocalDate.now())) {
//当天
if (ChronoUnit.SECONDS.between(localDateTime, currentDateTime) < 60) {
timeText = (ChronoUnit.SECONDS.between(localDateTime, currentDateTime)) + "秒前";
} else if (ChronoUnit.SECONDS.between(localDateTime, currentDateTime) >= 60
&& ChronoUnit.MINUTES.between(localDateTime, currentDateTime) < 60) {
timeText = (ChronoUnit.MINUTES.between(localDateTime, currentDateTime)) + "分钟前";
} else if (ChronoUnit.MINUTES.between(localDateTime, currentDateTime) >= 60
&& ChronoUnit.HOURS.between(localDateTime, currentDateTime) < 24) {
timeText = (ChronoUnit.HOURS.between(localDateTime, currentDateTime)) + "小时前";
}
} else if (localDate.getYear() == yearMonth.getYear()
&& localDate.getMonthValue() == yearMonth.getMonthValue()
&& localDate.isBefore(LocalDate.now())) {
//当月(不包含当天)
timeText = (LocalDate.now().getDayOfMonth() - localDate.getDayOfMonth()) + "天前";
} else if (localDate.getYear() == yearMonth.getYear()
&& localDate.getMonthValue() < yearMonth.getMonthValue()) {
//当年(不包含当月)
timeText = (yearMonth.getMonthValue() - localDate.getMonthValue()) + "月前";
} else if (localDate.getYear() < yearMonth.getYear()) {
//去年和去年以前的
timeText = (yearMonth.getYear() - localDate.getYear()) + "年前";
} else {
//其他
timeText = localDateTime.format(DATETIME_FORMATTER);
}
return timeText;
}
/**
* 是否是闰年
*
* @param year
* @return
*/
public static boolean isLeapYear(int year) {
return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
}
/**
* 切割日期。按照周期切割成小段日期段。例如: <br>
*
* @param startDate 开始日期(yyyy-MM-dd)
* @param endDate 结束日期(yyyy-MM-dd)
* @param period 周期(天,周,月,年)
* @return 切割之后的日期集合
* <li>startDate="2019-02-28",endDate="2019-03-05",period="day"</li>
* <li>结果为:[2019-02-28, 2019-03-01, 2019-03-02, 2019-03-03, 2019-03-04, 2019-03-05]</li><br>
* <li>startDate="2019-02-28",endDate="2019-03-25",period="week"</li>
* <li>结果为:[2019-02-28,2019-03-06, 2019-03-07,2019-03-13, 2019-03-14,2019-03-20,
* 2019-03-21,2019-03-25]</li><br>
* <li>startDate="2019-02-28",endDate="2019-05-25",period="month"</li>
* <li>结果为:[2019-02-28,2019-02-28, 2019-03-01,2019-03-31, 2019-04-01,2019-04-30,
* 2019-05-01,2019-05-25]</li><br>
* <li>startDate="2019-02-28",endDate="2020-05-25",period="year"</li>
* <li>结果为:[2019-02-28,2019-12-31, 2020-01-01,2020-05-25]</li><br>
*/
public static List<String> listDateStrs(String startDate, String endDate, String period) {
List<String> result = new ArrayList<>();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_PATTERN);
LocalDate end = LocalDate.parse(endDate, dateTimeFormatter);
LocalDate start = LocalDate.parse(startDate, dateTimeFormatter);
LocalDate tmp = start;
switch (period) {
case DAY:
while (start.isBefore(end) || start.isEqual(end)) {
result.add(start.toString());
start = start.plusDays(1);
}
break;
case WEEK:
while (tmp.isBefore(end) || tmp.isEqual(end)) {
if (tmp.plusDays(6).isAfter(end)) {
result.add(tmp.toString() + "," + end);
} else {
result.add(tmp.toString() + "," + tmp.plusDays(6));
}
tmp = tmp.plusDays(7);
}
break;
case MONTH:
while (tmp.isBefore(end) || tmp.isEqual(end)) {
LocalDate lastDayOfMonth = tmp.with(TemporalAdjusters.lastDayOfMonth());
if (lastDayOfMonth.isAfter(end)) {
result.add(tmp.toString() + "," + end);
} else {
result.add(tmp.toString() + "," + lastDayOfMonth);
}
tmp = lastDayOfMonth.plusDays(1);
}
break;
case YEAR:
while (tmp.isBefore(end) || tmp.isEqual(end)) {
LocalDate lastDayOfYear = tmp.with(TemporalAdjusters.lastDayOfYear());
if (lastDayOfYear.isAfter(end)) {
result.add(tmp.toString() + "," + end);
} else {
result.add(tmp.toString() + "," + lastDayOfYear);
}
tmp = lastDayOfYear.plusDays(1);
}
break;
default:
break;
}
return result;
}
public static void main(String[] args) {
System.out.println(getLocalDateTimeStr());
System.out.println(getLocalDateStr());
System.out.println(getLocalTimeStr());
System.out.println("星期:" + getDayOfWeekStr());
System.out.println(getDayOfWeekStr(LocalDate.now()));
System.out.println("========");
System.out.println(format(LocalDate.now(), UNSIGNED_DATE_PATTERN));
System.out.println("========");
System.out.println(parseLocalDateTime("2020-12-13 11:14:12", DATETIME_PATTERN));
System.out.println(parseLocalDate("2020-12-13", DATE_PATTERN));
System.out.println("========");
System.out.println(plus(LocalDateTime.now(), 3, ChronoUnit.HOURS));
System.out.println(minus(LocalDateTime.now(), 4, ChronoUnit.DAYS));
System.out.println("========");
System.out.println(getChronoUnitBetween(LocalDateTime.now(), parseLocalDateTime("2020-12-12 12:03:12", DATETIME_PATTERN), ChronoUnit.MINUTES));
System.out.println(getChronoUnitBetween(LocalDate.now(), parseLocalDate("2021-12-12", DATE_PATTERN), WEEKS));
System.out.println("========");
System.out.println(getFirstDayOfYearStr());
System.out.println(getFirstDayOfYearStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN)));
System.out.println(getFirstDayOfYearStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN), UNSIGNED_DATETIME_PATTERN));
System.out.println(getLastDayOfYearStr());
System.out.println(getLastDayOfYearStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN)));
System.out.println(getLastDayOfYearStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN), UNSIGNED_DATETIME_PATTERN));
System.out.println("========");
System.out.println(getFirstDayOfMonthStr());
System.out.println(getFirstDayOfMonthStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN)));
System.out.println(getFirstDayOfMonthStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN), UNSIGNED_DATETIME_PATTERN));
System.out.println(getLastDayOfMonthStr());
System.out.println(getLastDayOfMonthStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN)));
System.out.println(getLastDayOfMonthStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN), UNSIGNED_DATETIME_PATTERN));
System.out.println("========");
System.out.println(getFirstDayOfWeekStr());
System.out.println(getFirstDayOfWeekStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN)));
System.out.println(getFirstDayOfWeekStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN), UNSIGNED_DATETIME_PATTERN));
System.out.println(getLastDayOfWeekStr());
System.out.println(getLastDayOfWeekStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN)));
System.out.println(getLastDayOfWeekStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN), UNSIGNED_DATETIME_PATTERN));
System.out.println("========");
System.out.println(getStartTimeOfDayStr());
System.out.println(getStartTimeOfDayStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN)));
System.out.println(getStartTimeOfDayStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN), UNSIGNED_DATETIME_PATTERN));
System.out.println(getEndTimeOfDayStr());
System.out.println(getEndTimeOfDayStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN)));
System.out.println(getEndTimeOfDayStr(parseLocalDateTime("2021-12-12 12:03:12", DATETIME_PATTERN), UNSIGNED_DATETIME_PATTERN));
System.out.println("========");
List<String> dateStrs = listDateStrs("2019-01-30", "2020-12-13", YEAR);
for (String dateStr : dateStrs) {
System.out.println(dateStr);
}
System.out.println("========");
List<String> dateStrs1 = listDateStrs("2019-01-30", "2020-12-13", MONTH);
for (String dateStr : dateStrs1) {
System.out.println(dateStr);
}
System.out.println("========");
List<String> dateStrs2 = listDateStrs("2020-12-01", "2020-12-13", DAY);
for (String dateStr : dateStrs2) {
System.out.println(dateStr);
}
System.out.println("========");
LocalDate start = LocalDate.of(2022, 1, 1);
LocalDate end = LocalDate.of(2022, 1, 15);
long timstrap = start.atStartOfDay(ZoneOffset.ofHours(8)).toInstant().toEpochMilli();
long endtime = end.atStartOfDay(ZoneOffset.ofHours(8)).toInstant().toEpochMilli();
for (String s : getTimePeriodFromTwoTime(timstrap, endtime, "DAY")) {
System.out.println(s);
}
System.out.println("========");
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss','SSS");
LocalDateTime startDate = LocalDateTime.parse("2018-08-24T12:18:06,166", format);
LocalDateTime endDate = LocalDateTime.parse("2018-09-12T12:19:06,188", format);
List<String> numberOfWeeks = numberOfWeeks(startDate, endDate);
System.out.println("numberOfWeeks:" + numberOfWeeks);
System.out.println("========");
List<String> monthBetween = getMonthBetween("2022-01-01", "2022-06-09");
System.out.println(monthBetween);
System.out.println("========");
String format1 = format(new Date(), "yyyy-MM-dd");
System.out.println(format1);
System.out.println("========");
Date date = parseDate("2021-12-10 12:10:10", "yyyy-MM-dd HH:mm:ss");
System.out.println(date);
System.out.println("========");
Map<String, Object> timeIntervalMap = getTimeIntervalByDay("2022-07-22", "00:00", "24:00", "two_hour");
System.out.println("timeIntervalMap-keySet" + timeIntervalMap.keySet().toString());
System.out.println("timeIntervalMap-ValueSet" + timeIntervalMap.values().toString());
System.out.println("========");
List<String> dayMonths = getLastDayMonths("2022-07-15", 5, "yyyy-MM-dd", true);
System.out.println("dayMonths:" + dayMonths);
System.out.println("========");
List<String> yearMonths = getLastYearMonths("2022-05", 5, "yyyy-MM", true);
System.out.println("yearMonths:" + yearMonths);
}
}
常用的日期和时间类:
- Clock:用于获取指定时区当前日期时间
- DayOfWeek:枚举类,定义周一到周日的枚举值
- Duration:表示持续时间。OfXxx()用于获取时间的小时分钟秒
- Instant:表示一个具体的时刻,可以精确到纳秒。提供了now()方法获取当前时刻,now(Clock clock)用于获取clock对应时刻,plusXxx()当前时间基础加时间,minusXxx减时间
- LocalDate:表示不带时区的日期,now(Clock clock)用于获取clock对应日期,plusXxx()当前时间基础加年月日,minusXxx()减年月日
- LocalTime:表示不带时区的时间,now(Clock clock)用于获取clock对应时间,plusXxx()当前时间基础加上时分秒,minusXxx()减时分秒
- LocalDateTime:代表不带时区的日期时间,提供了now()方法获取当前日期时间,now(Clock clock)用于获取clock对应日期时间,plusXxx()当前时间基础加几年几月几日几时几分几秒,minusXxx减时间
- Month:枚举类,定义了一月到十二月的枚举值
- MonthDay:表示月日,该类提供了静态now()方法获取当前月日now(Clock clock)获取clock对应的月日
- Year:表示年,now()获取年份
- YearMonth:表示年月
- ZoneId:表示一个时区
- ZoneDateTime:表示一个时区化的日期和时间