package com.persagy.dmp.common.utils; import cn.hutool.core.util.StrUtil; import com.persagy.dmp.common.constant.DateStyle; import lombok.extern.slf4j.Slf4j; import java.math.BigDecimal; import java.text.ParseException; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.*; /** * 日期助手 * @author Charlie Yu * @date 2021-09-02 */ @Slf4j public class DateHelper { private static final ThreadLocal THREAD_LOCAL = new ThreadLocal<>(); private static final Object INSTANCE = new Object(); /** * 获取SimpleDateFormat * * @param pattern 日期格式 * @return SimpleDateFormat对象 * @throws RuntimeException 异常:非法日期格式 */ private static SimpleDateFormat getDateFormat(String pattern) throws RuntimeException { SimpleDateFormat dateFormat = THREAD_LOCAL.get(); if (dateFormat == null) { synchronized (INSTANCE) { if (dateFormat == null) { dateFormat = new SimpleDateFormat(pattern); dateFormat.setLenient(false); THREAD_LOCAL.set(dateFormat); } } } dateFormat.applyPattern(pattern); return dateFormat; } /** * 获取日期中的某数值。如获取月份 * * @param date 日期 * @param dateType 日期格式 * @return 数值 */ private static int getInteger(Date date, int dateType) { int num = 0; Calendar calendar = Calendar.getInstance(); if (date != null) { calendar.setTime(date); num = calendar.get(dateType); } return num; } /** * 增加日期中某类型的某数值。如增加日期 * * @param date 日期字符串 * @param dateType 类型 * @param amount 数值 * @return 计算后日期字符串 */ private static String addInteger(String date, int dateType, int amount) { String dateString = null; DateStyle dateStyle = getDateStyle(date); if (dateStyle != null) { Date myDate = stringToDate(date, dateStyle); myDate = addInteger(myDate, dateType, amount); dateString = dateToString(myDate, dateStyle); } return dateString; } /** * 增加日期中某类型的某数值。如增加日期 * * @param date 日期 * @param dateType 类型 * @param amount 数值 * @return 计算后日期 */ private static Date addInteger(Date date, int dateType, int amount) { Date myDate = null; if (date != null) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(dateType, amount); myDate = calendar.getTime(); } return myDate; } /** * 将时间戳转换为时间 */ public static String stampToDate(String s){ if (StrUtil.isEmpty(s)) { return null; } String res; SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); long lt = new Long(s); Date date = new Date(lt); res = simpleDateFormat.format(date); return res; } /** * 获取精确的日期 * * @param timestamps 时间long集合 * @return 日期 */ private static Date getAccurateDate(List timestamps) { Date date = null; long timestamp = 0; Map map = new HashMap<>(16); List absoluteValues = new ArrayList(); if (timestamps != null && timestamps.size() > 0) { if (timestamps.size() > 1) { for (int i = 0; i < timestamps.size(); i++) { for (int j = i + 1; j < timestamps.size(); j++) { long absoluteValue = Math.abs(timestamps.get(i) - timestamps.get(j)); absoluteValues.add(absoluteValue); long[] timestampTmp = { timestamps.get(i), timestamps.get(j) }; map.put(absoluteValue, timestampTmp); } } // 有可能有相等的情况。如2012-11和2012-11-01。时间戳是相等的。此时minAbsoluteValue为0 // 因此不能将minAbsoluteValue取默认值0 long minAbsoluteValue = -1; if (!absoluteValues.isEmpty()) { minAbsoluteValue = absoluteValues.get(0); for (int i = 1; i < absoluteValues.size(); i++) { if (minAbsoluteValue > absoluteValues.get(i)) { minAbsoluteValue = absoluteValues.get(i); } } } if (minAbsoluteValue != -1) { long[] timestampsLastTmp = map.get(minAbsoluteValue); long dateOne = timestampsLastTmp[0]; long dateTwo = timestampsLastTmp[1]; if (absoluteValues.size() > 1) { timestamp = Math.abs(dateOne) > Math.abs(dateTwo) ? dateOne : dateTwo; } } } else { timestamp = timestamps.get(0); } } if (timestamp != 0) { date = new Date(timestamp); } return date; } /** * 判断字符串是否为日期字符串 * * @param date 日期字符串 * @return true or false */ public static boolean isDate(String date) { boolean isDate = false; if (date != null) { if (getDateStyle(date) != null) { isDate = true; } } return isDate; } /** * 获取日期字符串的日期风格。失敗返回null。 * * @param date 日期字符串 * @return 日期风格 */ public static DateStyle getDateStyle(String date) { DateStyle dateStyle = null; Map map = new HashMap<>(16); List timestamps = new ArrayList<>(); for (DateStyle style : DateStyle.values()) { if (style.isShowOnly()) { continue; } Date dateTmp = null; if (date != null) { try { ParsePosition pos = new ParsePosition(0); dateTmp = getDateFormat(style.getValue()).parse(date, pos); if (pos.getIndex() != date.length()) { dateTmp = null; } } catch (Exception e) { } } if (dateTmp != null) { timestamps.add(dateTmp.getTime()); map.put(dateTmp.getTime(), style); } } Date accurateDate = getAccurateDate(timestamps); if (accurateDate != null) { dateStyle = map.get(accurateDate.getTime()); } return dateStyle; } /** * 将日期字符串转化为日期。失败返回null。 * * @param date 日期字符串 * @return 日期 */ public static Date stringToDate(String date) { DateStyle dateStyle = getDateStyle(date); return stringToDate(date, dateStyle); } /** * 将日期字符串转化为日期。失败返回null。 * * @param date 日期字符串 * @param pattern 日期格式 * @return 日期 */ public static Date stringToDate(String date, String pattern) { Date myDate = null; if (date != null) { try { myDate = getDateFormat(pattern).parse(date); } catch (Exception e) { } } return myDate; } /** * 将日期字符串转化为日期。失败返回null。 * * @param date 日期字符串 * @param dateStyle 日期风格 * @return 日期 */ public static Date stringToDate(String date, DateStyle dateStyle) { Date myDate = null; if (dateStyle != null) { myDate = stringToDate(date, dateStyle.getValue()); } return myDate; } /** * 将日期转化为日期字符串。失败返回null。 * * @param date 日期 * @param pattern 日期格式 * @return 日期字符串 */ public static String dateToString(Date date, String pattern) { String dateString = null; if (date != null) { try { dateString = getDateFormat(pattern).format(date); } catch (Exception e) { } } return dateString; } /** * 将日期转化为日期字符串。失败返回null。 * * @param date 日期 * @param dateStyle 日期风格 * @return 日期字符串 */ public static String dateToString(Date date, DateStyle dateStyle) { String dateString = null; if (dateStyle != null) { dateString = dateToString(date, dateStyle.getValue()); } return dateString; } /** * 将日期字符串转化为另一日期字符串。失败返回null。 * * @param date 旧日期字符串 * @param newPattern 新日期格式 * @return 新日期字符串 */ public static String stringToString(String date, String newPattern) { DateStyle oldDateStyle = getDateStyle(date); return stringToString(date, oldDateStyle, newPattern); } /** * 将日期字符串转化为另一日期字符串。失败返回null。 * * @param date 旧日期字符串 * @param newDateStyle 新日期风格 * @return 新日期字符串 */ public static String stringToString(String date, DateStyle newDateStyle) { DateStyle oldDateStyle = getDateStyle(date); return stringToString(date, oldDateStyle, newDateStyle); } /** * 将日期字符串转化为另一日期字符串。失败返回null。 * * @param date 旧日期字符串 * @param olddPattern 旧日期格式 * @param newPattern 新日期格式 * @return 新日期字符串 */ public static String stringToString(String date, String olddPattern, String newPattern) { return dateToString(stringToDate(date, olddPattern), newPattern); } /** * 将日期字符串转化为另一日期字符串。失败返回null。 * * @param date 旧日期字符串 * @param olddDteStyle 旧日期风格 * @param newParttern 新日期格式 * @return 新日期字符串 */ public static String stringToString(String date, DateStyle olddDteStyle, String newParttern) { String dateString = null; if (olddDteStyle != null) { dateString = stringToString(date, olddDteStyle.getValue(), newParttern); } return dateString; } /** * 将日期字符串转化为另一日期字符串。失败返回null。 * * @param date 旧日期字符串 * @param olddPattern 旧日期格式 * @param newDateStyle 新日期风格 * @return 新日期字符串 */ public static String stringToString(String date, String olddPattern, DateStyle newDateStyle) { String dateString = null; if (newDateStyle != null) { dateString = stringToString(date, olddPattern, newDateStyle.getValue()); } return dateString; } /** * 将日期字符串转化为另一日期字符串。失败返回null。 * * @param date 旧日期字符串 * @param olddDteStyle 旧日期风格 * @param newDateStyle 新日期风格 * @return 新日期字符串 */ public static String stringToString(String date, DateStyle olddDteStyle, DateStyle newDateStyle) { String dateString = null; if (olddDteStyle != null && newDateStyle != null) { dateString = stringToString(date, olddDteStyle.getValue(), newDateStyle.getValue()); } return dateString; } /** * 增加日期的年份。失败返回null。 * * @param date 日期 * @param yearAmount 增加数量。可为负数 * @return 增加年份后的日期字符串 */ public static String addYear(String date, int yearAmount) { return addInteger(date, Calendar.YEAR, yearAmount); } /** * 增加日期的年份。失败返回null。 * * @param date 日期 * @param yearAmount 增加数量。可为负数 * @return 增加年份后的日期 */ public static Date addYear(Date date, int yearAmount) { return addInteger(date, Calendar.YEAR, yearAmount); } /** * 增加日期的月份。失败返回null。 * * @param date 日期 * @param monthAmount 增加数量。可为负数 * @return 增加月份后的日期字符串 */ public static String addMonth(String date, int monthAmount) { return addInteger(date, Calendar.MONTH, monthAmount); } /** * 增加日期的月份。失败返回null。 * * @param date 日期 * @param monthAmount 增加数量。可为负数 * @return 增加月份后的日期 */ public static Date addMonth(Date date, int monthAmount) { return addInteger(date, Calendar.MONTH, monthAmount); } /** * 增加日期的天数。失败返回null。 * * @param date 日期字符串 * @param dayAmount 增加数量。可为负数 * @return 增加天数后的日期字符串 */ public static String addDay(String date, int dayAmount) { return addInteger(date, Calendar.DATE, dayAmount); } /** * 增加日期的天数。失败返回null。 * * @param date 日期 * @param dayAmount 增加数量。可为负数 * @return 增加天数后的日期 */ public static Date addDay(Date date, int dayAmount) { return addInteger(date, Calendar.DATE, dayAmount); } /** * 增加日期的小时。失败返回null。 * * @param date 日期字符串 * @param hourAmount 增加数量。可为负数 * @return 增加小时后的日期字符串 */ public static String addHour(String date, int hourAmount) { return addInteger(date, Calendar.HOUR_OF_DAY, hourAmount); } /** * 增加日期的小时。失败返回null。 * * @param date 日期 * @param hourAmount 增加数量。可为负数 * @return 增加小时后的日期 */ public static Date addHour(Date date, int hourAmount) { return addInteger(date, Calendar.HOUR_OF_DAY, hourAmount); } /** * 增加日期的分钟。失败返回null。 * * @param date 日期字符串 * @param minuteAmount 增加数量。可为负数 * @return 增加分钟后的日期字符串 */ public static String addMinute(String date, int minuteAmount) { return addInteger(date, Calendar.MINUTE, minuteAmount); } /** * 增加日期的分钟。失败返回null。 * * @param date 日期 * @param minuteAmount 增加数量。可为负数 * @return 增加分钟后的日期 */ public static Date addMinute(Date date, int minuteAmount) { return addInteger(date, Calendar.MINUTE, minuteAmount); } /** * 增加日期的秒钟。失败返回null。 * * @param date 日期字符串 * @param secondAmount 增加数量。可为负数 * @return 增加秒钟后的日期字符串 */ public static String addSecond(String date, int secondAmount) { return addInteger(date, Calendar.SECOND, secondAmount); } /** * 增加日期的秒钟。失败返回null。 * * @param date 日期 * @param secondAmount 增加数量。可为负数 * @return 增加秒钟后的日期 */ public static Date addSecond(Date date, int secondAmount) { return addInteger(date, Calendar.SECOND, secondAmount); } /** * 获取日期的年份。失败返回0。 * * @param date 日期字符串 * @return 年份 */ public static int getYear(String date) { return getYear(stringToDate(date)); } /** * 获取日期的年份。失败返回0。 * * @param date 日期 * @return 年份 */ public static int getYear(Date date) { return getInteger(date, Calendar.YEAR); } /** * 获取日期的月份。失败返回0。 * * @param date 日期字符串 * @return 月份 */ public static int getMonth(String date) { return getMonth(stringToDate(date)); } /** * 获取日期的月份。失败返回0。 * * @param date 日期 * @return 月份 */ public static int getMonth(Date date) { return getInteger(date, Calendar.MONTH) + 1; } /** * 获取日期的天数。失败返回0。 * * @param date 日期字符串 * @return 天 */ public static int getDay(String date) { return getDay(stringToDate(date)); } /** * 获取日期的天数。失败返回0。 * * @param date 日期 * @return 天 */ public static int getDay(Date date) { return getInteger(date, Calendar.DATE); } /** * 获取日期的小时。失败返回0。 * * @param date 日期字符串 * @return 小时 */ public static int getHour(String date) { return getHour(stringToDate(date)); } /** * 获取日期的小时。失败返回0。 * * @param date 日期 * @return 小时 */ public static int getHour(Date date) { return getInteger(date, Calendar.HOUR_OF_DAY); } /** * 获取日期的分钟。失败返回0。 * * @param date 日期字符串 * @return 分钟 */ public static int getMinute(String date) { return getMinute(stringToDate(date)); } /** * 获取日期的分钟。失败返回0。 * * @param date 日期 * @return 分钟 */ public static int getMinute(Date date) { return getInteger(date, Calendar.MINUTE); } /** * 获取日期的秒钟。失败返回0。 * * @param date 日期字符串 * @return 秒钟 */ public static int getSecond(String date) { return getSecond(stringToDate(date)); } /** * 获取日期的秒钟。失败返回0。 * * @param date 日期 * @return 秒钟 */ public static int getSecond(Date date) { return getInteger(date, Calendar.SECOND); } /** * 获取日期 。默认yyyy-MM-dd格式。失败返回null。 * * @param date 日期字符串 * @return 日期 */ public static String getDate(String date) { return stringToString(date, DateStyle.YYYY_MM_DD); } /** * 获取日期。默认yyyy-MM-dd格式。失败返回null。 * * @param date 日期 * @return 日期 */ public static String getDate(Date date) { return dateToString(date, DateStyle.YYYY_MM_DD); } /** * 获取日期的时间。默认HH:mm:ss格式。失败返回null。 * * @param date 日期字符串 * @return 时间 */ public static String getTime(String date) { return stringToString(date, DateStyle.HH_MM_SS); } /** * 获取日期的时间。默认HH:mm:ss格式。失败返回null。 * * @param date 日期 * @return 时间 */ public static String getTime(Date date) { return dateToString(date, DateStyle.HH_MM_SS); } /** * 获取两个日期相差的天数 * * @param date 日期字符串 * @param otherDate 另一个日期字符串 * @return 相差天数。如果失败则返回-1 */ public static int getIntervalDays(String date, String otherDate) { return getIntervalDays(stringToDate(date), stringToDate(otherDate)); } /** * @param date 日期 * @param otherDate 另一个日期 * @return 相差天数。如果失败则返回-1 */ public static int getIntervalDays(Date date, Date otherDate) { int num = -1; Date dateTmp = DateHelper.stringToDate(DateHelper.getDate(date), DateStyle.YYYY_MM_DD); Date otherDateTmp = DateHelper.stringToDate(DateHelper.getDate(otherDate), DateStyle.YYYY_MM_DD); if (dateTmp != null && otherDateTmp != null) { long time = Math.abs(dateTmp.getTime() - otherDateTmp.getTime()); num = (int) (time / (24 * 60 * 60 * 1000)); } return num; } /** * 获得某天的开始时间 * * @param date * @return */ public static Date getDayStart(Date date) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00"); return stringToDate(sdf.format(date)); } /** * 获得某天的结束时间 * * @param date * @return */ public static Date getDayEnd(Date date) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59"); return stringToDate(sdf.format(date)); } /** * 或者本周开始时间 * * @return */ public static Date getCurrentWeekStart(Date date) { Map map = new HashMap<>(16); Calendar cal = Calendar.getInstance(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd 00:00:00"); // 获取本周一的日期 cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); return stringToDate(df.format(cal.getTime())); } /** * 获取本周结束日期 * * @return */ public static Date getCurrentWeekEnd() { Map map = new HashMap<>(16); Calendar cal = Calendar.getInstance(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd 23:59:59"); cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); // 增加一个星期,才是我们中国人理解的本周日的日期 cal.add(Calendar.WEEK_OF_YEAR, 1); return stringToDate(df.format(cal.getTime())); } /** * 或者本月开始时间 * * @return */ public static Date getCurrentMonthStart() { // 获取当前日期 Calendar cal = Calendar.getInstance(); cal.add(Calendar.MONTH, 0); // 设置为1号,当前日期既为本月第一天 cal.set(Calendar.DAY_OF_MONTH, 1); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd 00:00:00"); return stringToDate(df.format(cal.getTime())); } /** * 获取本月结束日期 * * @return */ public static Date getCurrentMonthEnd() { Calendar cal = Calendar.getInstance(); // 设置为1号,当前日期既为本月第一天 cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd 23:59:59"); return stringToDate(df.format(cal.getTime())); } /** * 获得某年某月的开始时间 * * @param strYear * @param strMonth * @return */ public static Date getMonthStart(String strYear, String strMonth) { // 获取当前日期 Calendar cal = Calendar.getInstance(); cal.set(Calendar.YEAR, Integer.parseInt(strYear)); cal.set(Calendar.MONTH, Integer.parseInt(strMonth)); // 设置为1号,当前日期既为本月第一天 cal.set(Calendar.DAY_OF_MONTH, 1); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd 00:00:00"); cal.set(Calendar.DAY_OF_MONTH, 1); cal.add(Calendar.DAY_OF_MONTH, -1); cal.set(Calendar.DAY_OF_MONTH, 1); Date firstDate = cal.getTime(); return stringToDate(df.format(firstDate)); } /** * 获得某年某月的最后的时间 * * @param strYear * @param strMonth * @return */ public static Date getMonthEnd(String strYear, String strMonth) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd 23:59:59"); Calendar cal = Calendar.getInstance(); // 不加下面2行,就是取当前时间前一个月的第一天及最后一天 cal.set(Calendar.YEAR, Integer.parseInt(strYear)); cal.set(Calendar.MONTH, Integer.parseInt(strMonth)); cal.set(Calendar.DAY_OF_MONTH, 1); cal.add(Calendar.DAY_OF_MONTH, -1); Date lastDate = cal.getTime(); return stringToDate(df.format(lastDate)); } /** * 得到某天是周几 * * @param “2013-06-03”格式的日期 * @return 返回1是星期日、2是星期一、3是星期二、4是星期三、5是星期四、6是星期五、7是星期六 */ public static int getDayofweek(String date) { Calendar cal = Calendar.getInstance(); if (date.equals(StrUtil.EMPTY)) { cal.setTime(new Date(System.currentTimeMillis())); } else { cal.setTime(new Date(getDateByStr2(date).getTime())); } // cal.setFirstDayOfWeek(Calendar.MONDAY); return cal.get(Calendar.DAY_OF_WEEK); } private static Date getDateByStr2(String dd) { SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd"); Date date; try { date = sd.parse(dd); } catch (ParseException e) { date = null; //log.error(e.getMessage(),e); } return date; } /** * 得到某个月的周数 * * @param date * @throws Exception */ public static int getMonthWeek(String date) throws Exception { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); Date s = sdf.parse(date); Calendar ca = Calendar.getInstance(); ca.setTime(s); ca.setFirstDayOfWeek(Calendar.MONDAY); System.out.println(ca.getActualMaximum(Calendar.WEEK_OF_MONTH)); return ca.getActualMaximum(Calendar.WEEK_OF_MONTH); } public static List getMonthWithOffset(String month, int offset) { List list = null; try { list = new ArrayList(); String firstDay = StrUtil.EMPTY; // 定义起始日期 Date date = new SimpleDateFormat("yyyy-MM").parse(month); Date now = new Date(); if (date.after(now)) { date = now; } List mlist = getYearMonthBetweenDate(dateToString(date, "yyyy-MM"), dateToString(now, "yyyy-MM")); if (mlist.size() <= offset) { int preOffSet = offset * 2 + 1 - mlist.size(); for (int i = preOffSet; i >= 1; i--) { Date d = addMonth(date, i * -1); list.add(dateToString(d, "yyyy-MM")); } list.addAll(mlist); return list; } // 往前数n月 for (int i = offset; i >= 1; i--) { Date d = addMonth(date, i * -1); list.add(dateToString(d, "yyyy-MM")); } list.add(month); // 往后数n月 for (int i = 1; i <= offset; i++) { Date d = addMonth(date, i); list.add(dateToString(d, "yyyy-MM")); } } catch (ParseException e) { return null; } return list; } /** * 获取两个日期间的年月 * @param startDate * @param endDate * @return */ public static List getYearMonthBetweenDate(String startDate, String endDate) { List list = new ArrayList<>(); try { Date d1 = new SimpleDateFormat("yyyy-MM").parse(startDate); Date d2 = new SimpleDateFormat("yyyy-MM").parse(endDate); Calendar calendar1 = Calendar.getInstance(); calendar1.setTime(d1); Calendar calendar2 = Calendar.getInstance(); calendar2.setTime(d2); Calendar cale = Calendar.getInstance(); int startDay = calendar1.get(Calendar.DAY_OF_MONTH); int endDay = calendar2.get(Calendar.DAY_OF_MONTH); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); // 判断是否到结束日期 while (calendar1.compareTo(calendar2) <= 0) { cale.setTime(calendar1.getTime()); // 如果是同一天 if (calendar1.equals(calendar2)) { cale.set(Calendar.DAY_OF_MONTH, calendar1.getActualMaximum(Calendar.DAY_OF_MONTH)); list.add(sdf.format(d1)); } else if (calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH) && calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR)) { // 如果是同月 - 取第一天 cale.set(Calendar.DAY_OF_MONTH, 1); list.add(sdf.format(cale.getTime())); } else { // 非同月 - 取第一天 cale.set(Calendar.DAY_OF_MONTH, 1); list.add(sdf.format(cale.getTime())); cale.set(Calendar.DAY_OF_MONTH, calendar1.getActualMaximum(Calendar.DAY_OF_MONTH)); } // 进行当前日期月份加1 calendar1.add(Calendar.MONTH, 1); } if (endDay < startDay) { cale.setTime(d2); // 取第一天 cale.set(Calendar.DAY_OF_MONTH, 1); list.add(sdf.format(cale.getTime())); } } catch (ParseException e) { return null; } return list; } public static Calendar getMonthStartTime(Integer year, Integer month){ Calendar startDate= Calendar.getInstance(); startDate.set(Calendar.YEAR, year); startDate.set(Calendar.MONTH, month-1); startDate.set(Calendar.DAY_OF_MONTH,1); //HOUR是12小时制 startDate.set(Calendar.HOUR_OF_DAY, 0); startDate.set(Calendar.MINUTE, 0); startDate.set(Calendar.SECOND, 0); startDate.set(Calendar.MILLISECOND, 0); return startDate; } public static Calendar getMonthEndTime(Integer year, Integer month){ Calendar endDate= Calendar.getInstance(); endDate.set(Calendar.YEAR, year); endDate.set(Calendar.MONTH, month); //endDate.set(Calendar.DAY_OF_MONTH,endDate.getActualMaximum(Calendar.DATE)); endDate.set(Calendar.DAY_OF_MONTH, 1); endDate.add(Calendar.DAY_OF_MONTH, -1); endDate.set(Calendar.HOUR_OF_DAY , 0); endDate.set(Calendar.MINUTE, 0); endDate.set(Calendar.SECOND, 0); endDate.set(Calendar.MILLISECOND, 0); return endDate; } /** * 获得两个时间的小时差 * @param beginTime * @param endDate * @return */ public static BigDecimal getDateTimeDifferenceHours(Date beginTime, Date endDate) { double nh = 1000.00 * 60.00 * 60.00; // long ns = 1000; // 获得两个时间的毫秒时间差异 long diff = endDate.getTime() - beginTime.getTime(); return new BigDecimal(diff / nh).setScale(2, BigDecimal.ROUND_HALF_UP); } /** * 清理缓存 */ public static void clear() { THREAD_LOCAL.remove(); } public static void main(String[] args) { //getMonthWithOffset("2017-03", 3); // System.out.println(getDateTimeDifferenceHours( // DateHelper.StringToDate("2017-10-11 20:09:09", DateStyle.YYYY_MM_DD_HH_MM_SS), // DateHelper.StringToDate("2017-10-11 23:41:11", DateStyle.YYYY_MM_DD_HH_MM_SS))); } }