日期处理工具类
package com.tools.common.utils;
import com.craftsman.common.exception.RRException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Stream;
/**
* 日期处理
*
* @author chenshun
* @email sunlightcs@gmail.com
* @date 2016年12月21日 下午12:53:33
*/
public class DateUtils {
/**
* 时间格式(yyyy-MM)
*/
public final static String DATE_MONTH_PATTERN = "yyyy-MM";
/**
* 时间格式(yyyy-MM-dd)
*/
public final static String DATE_PATTERN = "yyyy-MM-dd";
/**
* 时间格式(yyyy-MM-dd HH:mm:ss)
*/
public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
/**
* 日期格式化 日期格式为:yyyy-MM-dd
*
* @param date 日期
* @return 返回yyyy-MM-dd格式日期
*/
public static String format(Date date) {
return format(date, DATE_PATTERN);
}
/**
* 获取某年第一天日期
*
* @param year 年份
* @return Date
*/
public static Date getCurrYearFirst(int year) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.YEAR, year);
Date currYearFirst = calendar.getTime();
return currYearFirst;
}
/**
* 获取某年最后一天日期
*
* @param year 年份
* @return Date
*/
public static Date getCurrYearLast(int year) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.YEAR, year);
calendar.roll(Calendar.DAY_OF_YEAR, -1);
Date currYearLast = calendar.getTime();
return currYearLast;
}
/**
* 获得当前系统时间
*/
public static String getNowDate() {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return df.format(new Date());
}
/**
* 得到当前时间的前N小时
*
* @param ihour
* @return
*/
public static String getBeforeByHourTime(int ihour) {
String returnstr = "";
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - ihour);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
returnstr = df.format(calendar.getTime());
return returnstr;
}
//获取两个时间之间的小时数
public static int getDayNum(String stime, String etime) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = null;
Date date = null;
try {
now = df.parse(etime);
date = df.parse(stime);
} catch (ParseException e) {
e.printStackTrace();
}
long l = now.getTime() - date.getTime();
int day = (int) l / (24 * 60 * 60 * 1000);
int hour = (int) (l / (60 * 60 * 1000));
int min = (int) ((l / (60 * 1000)));
int s = (int) (l / 1000);
// System.out.println(""+day+"天"+hour+"小时"+min+"分"+s+"秒");
return hour;
}
//获取两个时间之间的天数
public static int getDaysNum(String stime, String etime) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = null;
Date date = null;
try {
now = df.parse(etime);
date = df.parse(stime);
} catch (ParseException e) {
e.printStackTrace();
}
long l = now.getTime() - date.getTime();
int day = (int) (l / (24 * 60 * 60 * 1000));
int hour = (int) (l / (60 * 60 * 1000));
int min = (int) ((l / (60 * 1000)));
int s = (int) (l / 1000);
// System.out.println(""+day+"天"+hour+"小时"+min+"分"+s+"秒");
return day;
}
// 获取当前时间和6小时前的时间
public static Map<String, Object> dealTime(int hour) {
Calendar calendar = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
calendar2.add(Calendar.MINUTE, 1); //往前1分钟
String etime = simpleDateFormat2.format(calendar2.getTime());
int a = Calendar.HOUR_OF_DAY;
calendar.set(Calendar.HOUR_OF_DAY, calendar.get((Calendar.HOUR_OF_DAY)) - hour);
String stime = simpleDateFormat.format(calendar.getTime());
Map<String, Object> map = new HashMap<String, Object>();
map.put("stime", stime);
map.put("etime", etime);
return map;
}
/**
* 得到当前日期字符串 格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
*/
public static String getDate(String pattern) {
return DateFormatUtils.format(new Date(), pattern);
}
/**
* 日期格式化 日期格式为:yyyy-MM-dd
*
* @param date 日期
* @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN
* @return 返回yyyy-MM-dd格式日期
*/
public static String format(Date date, String pattern) {
if (date != null) {
SimpleDateFormat df = new SimpleDateFormat(pattern);
return df.format(date);
}
return null;
}
/**
* 字符串转换成日期
*
* @param strDate 日期字符串
* @param pattern 日期的格式,如:DateUtils.DATE_TIME_PATTERN
*/
public static Date stringToDate(String strDate, String pattern) {
if (StringUtils.isBlank(strDate)) {
return null;
}
DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern);
return fmt.parseLocalDateTime(strDate).toDate();
}
/**
* 根据周数,获取开始日期、结束日期
*
* @param week 周期 0本周,-1上周,-2上上周,1下周,2下下周
* @return 返回date[0]开始日期、date[1]结束日期
*/
public static Date[] getWeekStartAndEnd(int week) {
DateTime dateTime = new DateTime();
LocalDate date = new LocalDate(dateTime.plusWeeks(week));
date = date.dayOfWeek().withMinimumValue();
Date beginDate = date.toDate();
Date endDate = date.plusDays(6).toDate();
return new Date[]{beginDate, endDate};
}
/**
* 对日期的【秒】进行加/减
*
* @param date 日期
* @param seconds 秒数,负数为减
* @return 加/减几秒后的日期
*/
public static Date addDateSeconds(Date date, int seconds) {
DateTime dateTime = new DateTime(date);
return dateTime.plusSeconds(seconds).toDate();
}
/**
* 对日期的【分钟】进行加/减
*
* @param date 日期
* @param minutes 分钟数,负数为减
* @return 加/减几分钟后的日期
*/
public static Date addDateMinutes(Date date, int minutes) {
DateTime dateTime = new DateTime(date);
return dateTime.plusMinutes(minutes).toDate();
}
/**
* 对日期的【小时】进行加/减
*
* @param date 日期
* @param hours 小时数,负数为减
* @return 加/减几小时后的日期
*/
public static Date addDateHours(Date date, int hours) {
DateTime dateTime = new DateTime(date);
return dateTime.plusHours(hours).toDate();
}
/**
* 对日期的【天】进行加/减
*
* @param date 日期
* @param days 天数,负数为减
* @return 加/减几天后的日期
*/
public static Date addDateDays(Date date, int days) {
DateTime dateTime = new DateTime(date);
return dateTime.plusDays(days).toDate();
}
/**
* 对日期的【周】进行加/减
*
* @param date 日期
* @param weeks 周数,负数为减
* @return 加/减几周后的日期
*/
public static Date addDateWeeks(Date date, int weeks) {
DateTime dateTime = new DateTime(date);
return dateTime.plusWeeks(weeks).toDate();
}
/**
* 对日期的【月】进行加/减
*
* @param date 日期
* @param months 月数,负数为减
* @return 加/减几月后的日期
*/
public static Date addDateMonths(Date date, int months) {
DateTime dateTime = new DateTime(date);
return dateTime.plusMonths(months).toDate();
}
/**
* 对日期的【年】进行加/减
*
* @param date 日期
* @param years 年数,负数为减
* @return 加/减几年后的日期
*/
public static Date addDateYears(Date date, int years) {
DateTime dateTime = new DateTime(date);
return dateTime.plusYears(years).toDate();
}
/**
* 得到日期字符串 默认格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
*/
public static String formatDate(Date date, Object... pattern) {
String formatDate = null;
if (pattern != null && pattern.length > 0) {
formatDate = DateFormatUtils.format(date, pattern[0].toString());
} else {
formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
}
return formatDate;
}
/**
* 得到当前年份字符串 格式(yyyy)
*/
public static String getYear() {
return formatDate(new Date(), "yyyy");
}
/**
* 得到当前月份字符串 格式(MM)
*/
public static String getMonth() {
return formatDate(new Date(), "MM");
}
/**
* 得到当天字符串 格式(dd)
*/
public static String getDay() {
return formatDate(new Date(), "dd");
}
public static List<String> getBetweenDate(String start, String end) {
List<String> list = new ArrayList<>();
java.time.LocalDate startDate = null;
java.time.LocalDate endDate = null;
try {
startDate = java.time.LocalDate.parse(start);
endDate = java.time.LocalDate.parse(end);
} catch (Exception e) {
throw new RRException("日期格式不正确。(日期示例:2019-12-26)");
}
if (start.equals(end)) {
list.add(start);
return list;
}
long distance = ChronoUnit.DAYS.between(startDate, endDate);
if (distance < 1) {
return list;
}
Stream.iterate(startDate, d -> {
return d.plusDays(1);
}).limit(distance + 1).forEach(f -> {
list.add(f.toString());
});
return list;
}
public static List<String> getBetweenMonth(String start, String end) {
java.time.format.DateTimeFormatter format = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd");
java.time.format.DateTimeFormatter format2 = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM");
java.time.LocalDate s = java.time.LocalDate.parse(start + "-01", format);
java.time.LocalDate e = java.time.LocalDate.parse(end + "-01", format);
long i = ChronoUnit.MONTHS.between(s, e);
List<String> result = new ArrayList<>();
for (int j = 0; j <= i; j++) {
java.time.LocalDate d = s.plusMonths(j);
result.add(d.format(format2));
}
return result;
}
/**
* 补全开始到结束时间的工具方法
*/
public static List<String> completionTime(String startTime, String endTime) throws Exception {
/*startTime="2021-02-03";
endTime="2021-02-06";*/
if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
throw new Exception("开始日期和截止日期都不能为空!");
}
//compareTo 当两者相等时为0,当前者小于后者时返回-1,大于时返回1。具体查看源码。
if (startTime.compareTo(endTime) > 0) {
throw new Exception("开始日期必须小于等于截止日期!");
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date startDate = simpleDateFormat.parse(startTime);
Date endDate = simpleDateFormat.parse(endTime);
Calendar startCal = Calendar.getInstance();
Calendar endCal = Calendar.getInstance();
startCal.setTime(startDate);
endCal.setTime(endDate);
List<String> days = new ArrayList<>();
//当开始时间大于结束时间时则返回
while (startCal.compareTo(endCal) <= 0) {
days.add(simpleDateFormat.format(startCal.getTime()));
//Date本身加减日期过于麻烦,使用Calendar操纵日期;开始时间+1;
startCal.add(Calendar.DATE, 1);
}
return days;
}
/**
* 返回两个时间段之间的所有日期(不包含endDate)
* 动态设置时间格式
* simpleFormat 0 分钟 1 小时 2 天 3 月 4 年
*
* @param beginDate
* @param endDate
*/
public static List<String> getDatesBetweenNotEndTime(String beginDate, String endDate, int simpleFormat)
throws ParseException, ParseException {
SimpleDateFormat sdf = null;
if (simpleFormat == 0) {
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
} else if (simpleFormat == 1) {
sdf = new SimpleDateFormat("yyyy-MM-dd HH");
} else if (simpleFormat == 2) {
sdf = new SimpleDateFormat("yyyy-MM-dd");
} else if (simpleFormat == 3) {
sdf = new SimpleDateFormat("yyyy-MM");
} else if (simpleFormat == 4) {
sdf = new SimpleDateFormat("yyyy");
}
List<String> lDate = new ArrayList<String>();
Date date = null;
try {
date = sdf.parse(beginDate);
} catch (ParseException e) {
e.printStackTrace();
}
String dateString = sdf.format(date);
lDate.add(dateString);
Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse(beginDate));
boolean bContinue = true;
while (bContinue) {
if (simpleFormat == 0) {
cal.add(Calendar.MINUTE, 1);
} else if (simpleFormat == 1) {
cal.add(Calendar.HOUR, 1);
} else if (simpleFormat == 2) {
cal.add(Calendar.DAY_OF_MONTH, 1);
} else if (simpleFormat == 3) {
cal.add(Calendar.MONTH, 1);
} else if (simpleFormat == 4) {
cal.add(Calendar.YEAR, 1);
}
if (sdf.parse(endDate).after(cal.getTime())) {
lDate.add(sdf.format(cal.getTime()));
} else {
break;
}
}
return lDate;
}
/**
* 返回两个时间段之间的所有日期(包含endDate)
* 动态设置时间格式
* simpleFormat 0 分钟 1 小时 2 天 3 月 4 年
*
* @param beginDate
* @param endDate
*/
public static List<String> getDatesBetweenContainEndTime(String beginDate, String endDate, int simpleFormat)
throws ParseException, ParseException {
SimpleDateFormat sdf = null;
if (simpleFormat == 0) {
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
} else if (simpleFormat == 1) {
sdf = new SimpleDateFormat("yyyy-MM-dd HH");
} else if (simpleFormat == 2) {
sdf = new SimpleDateFormat("yyyy-MM-dd");
} else if (simpleFormat == 3) {
sdf = new SimpleDateFormat("yyyy-MM");
} else if (simpleFormat == 4) {
sdf = new SimpleDateFormat("yyyy");
}
List<String> lDate = new ArrayList<String>();
Date date = null;
try {
date = sdf.parse(beginDate);
} catch (ParseException e) {
e.printStackTrace();
}
String dateString = sdf.format(date);
lDate.add(dateString);
Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse(beginDate));
boolean bContinue = true;
while (bContinue) {
if (simpleFormat == 0) {
cal.add(Calendar.MINUTE, 1);
} else if (simpleFormat == 1) {
cal.add(Calendar.HOUR, 1);
} else if (simpleFormat == 2) {
cal.add(Calendar.DAY_OF_MONTH, 1);
} else if (simpleFormat == 3) {
cal.add(Calendar.MONTH, 1);
} else if (simpleFormat == 4) {
cal.add(Calendar.YEAR, 1);
}
if (sdf.parse(endDate).after(cal.getTime())) {
lDate.add(sdf.format(cal.getTime()));
} else {
break;
}
}
try {
date = sdf.parse(endDate);
} catch (ParseException e) {
e.printStackTrace();
}
String entrs = sdf.format(date);
if (!dateString.equals(entrs)) {
lDate.add(entrs);
}
return lDate;
}
//获取月份每一天
public static Map<String, Object> getDayByMonth(String yearParam, String monthParam) {
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
Calendar calendar = Calendar.getInstance(Locale.CHINA);
calendar.set(Integer.valueOf(yearParam), Integer.valueOf(monthParam) - 1, 1);
int year = calendar.get(Calendar.YEAR);//年份
int month = calendar.get(Calendar.MONTH) + 1;//月份
int day = calendar.getActualMaximum(Calendar.DATE);
for (int i = 1; i <= day; i++) {
String date = null;
if (month < 10 && i < 10) {
date = String.valueOf(year) + "-0" + month + "-0" + i;
}
if (month < 10 && i >= 10) {
date = String.valueOf(year) + "-0" + month + "-" + i;
}
if (month >= 10 && i < 10) {
date = String.valueOf(year) + "-" + month + "-0" + i;
}
if (month >= 10 && i >= 10) {
date = String.valueOf(year) + "-" + month + "-" + i;
}
map.put(date, 0);
}
return map;
}
/**
* 传入年月,遍历中间所有的月份(包含起始月和结尾月份)
*
* @param startDate 起始月 yyyy-mm
* @param endDate 结束月 yyyy-mm
* @return
*/
public static List<String> getBetweenYearMonth(String startDate, String endDate) {
Integer startY = Integer.valueOf(startDate.split("-")[0]);
Integer startM = Integer.valueOf(startDate.split("-")[1]);
Integer endY = Integer.valueOf(endDate.split("-")[0]);
Integer endM = Integer.valueOf(endDate.split("-")[1]);
//用来格式化
DecimalFormat decimalFormat = new DecimalFormat("00");
List<String> list = new ArrayList<>();
if (startY > endY) {
throw new RRException("日期格式不正确不对");
}
//年份相同的时候
if (startY.equals(endY) && endM - startM >= 0) {
int count = startM;
while (endM - count >= 0) {
list.add(startY + "-" + decimalFormat.format(count));
count++;
}
} else {
int year = startY;
int month = startM;
//年份不同
while (endY - year > 0) {
for (int i = month; i <= 12; i++) {
list.add(year + "-" + decimalFormat.format(i));
}
year++;
month = 1;
if (year == endY) {
for (int i = 1; i <= endM; i++) {
list.add(year + "-" + decimalFormat.format(i));
}
}
}
}
return list;
}
public static List getBetweenDates(String dBegin, String dEnd) throws ParseException {
//日期工具类准备
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//设置开始时间
Calendar calBegin = Calendar.getInstance();
calBegin.setTime(format.parse(dBegin));
//设置结束时间
Calendar calEnd = Calendar.getInstance();
calEnd.setTime(format.parse(dEnd));
//装返回的日期集合容器
List datelist = new ArrayList();
//将第一个月添加里面去
datelist.add(format.format(calBegin.getTime()));
// 每次循环给calBegin日期加一天,直到calBegin.getTime()时间等于dEnd
while (format.parse(dEnd).after(calBegin.getTime())) {
// 根据日历的规则,为给定的日历字段添加或减去指定的时间量
calBegin.add(Calendar.DAY_OF_MONTH, 1);
datelist.add(format.format(calBegin.getTime()));
}
return datelist;
}
/**
* 获取年-月的第一天
* @param year
* @param month
* @return
*/
public static Date getFirstDay(int year, int month) {
// 获取Calendar类的实例
Calendar c = Calendar.getInstance();
// 设置年份
c.set(Calendar.YEAR, year);
// 设置月份,因为月份从0开始,所以用month - 1
c.set(Calendar.MONTH, month - 1);
// 设置日期
c.set(Calendar.DAY_OF_MONTH, 1);
return c.getTime();
}
/**
* 获取年月的最后一天
* @param year
* @param month
* @return
*/
public static Date getLastDay(int year, int month) {
// 获取Calendar类的实例
Calendar c = Calendar.getInstance();
// 设置年份
c.set(Calendar.YEAR, year);
// 设置月份,因为月份从0开始,所以用month - 1
c.set(Calendar.MONTH, month - 1);
// 获取当前时间下,该月的最大日期的数字
int lastDay = c.getActualMaximum(Calendar.DAY_OF_MONTH);
// 将获取的最大日期数设置为Calendar实例的日期数
c.set(Calendar.DAY_OF_MONTH, lastDay);
return c.getTime();
}
/**
* date转字符串
*
* @param date 时间
* @param dateFormat 时间格式
* @return
*/
public static String dateToStr(Date date, String dateFormat) {
//date为null时返回空字符串
if (date==null) {
return "";
}
//传入的时间格式不为空时
if (!StringUtils.isEmpty(dateFormat)) {
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
return sdf.format(date);
} else {
//传入的时间格式为空时默认格式为yyyy-MM-dd
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(date);
}
}