package net.baiqu.shop.data.core.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.Assert;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author by ericzhang on 2018-01-22.
* 日期工具类。
*/
@Slf4j
public class DateUtils {
public static final long MILLIS_PER_SECOND = 1000;
public static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND;
public static final long MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE;
public static final long MILLIS_PER_DAY = 24 * MILLIS_PER_HOUR;
public static final Date MAX_DATE = new Date(253370814513298L);
private static final String DEFAULT_FORMAT = "yyyy-MM-dd";
private static final Map<String, DateFormat> DATEFORMATMAP = new ConcurrentHashMap<>();
static {
DATEFORMATMAP.put("yyyy-MM-dd", new SimpleDateFormat("yyyy-MM-dd"));
DATEFORMATMAP.put("yyyy-MM-dd HH:mm:ss", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
DATEFORMATMAP.put("yyyy-MM-dd hh:mm:ss", new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"));
DATEFORMATMAP.put("yyyy/MM/dd", new SimpleDateFormat("yyyy/MM/dd"));
DATEFORMATMAP.put("yyyy/MM/dd hh:mm:ss", new SimpleDateFormat("yyyy/MM/dd hh:mm:ss"));
DATEFORMATMAP.put("yyyy/MM/dd HH:mm:ss", new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"));
DATEFORMATMAP.put("yyyyMMdd", new SimpleDateFormat("yyyyMMdd"));
DATEFORMATMAP.put("yyyyMMddhhmmss", new SimpleDateFormat("yyyyMMddhhmmss"));
}
private DateUtils() {
}
/**
* 时间搓转日期
*
* @param seconds
* @param pattern
* @return
*/
public static String timeStamp2Date(String seconds, String pattern) {
Assert.hasLength(seconds, "no seconds parameter");
DateFormat dateFormat = getFormat(pattern);
return dateFormat.format(new Date(Long.valueOf(seconds + "000")));
}
public static String stampToDate(String s, String pattern) {
String res;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
long lt = new Long(s);
Date date = new Date(lt);
res = simpleDateFormat.format(date);
return res;
}
/**
* 获取此日期的同一天凌晨零点的Date
*/
public static Date getMorning(Date date) {
String dateStr = formatToString(date, "yyyyMMdd");
return fromString(dateStr, "yyyyMMdd");
}
/**
* 获取此日期的同一天第二天凌晨零点的Date
*/
public static Date getNight(Date date) {
long time = getMorning(date).getTime();
long night = time + MILLIS_PER_DAY;
return new Date(night);
}
/**
* 获取当前日期的同一天凌晨零点的时间戳
*/
public static Long getMorningTimestamp() {
return getMorning(new Date()).getTime();
}
/**
* 获取此日期的同一天凌晨零点的时间戳
*/
public static Long getMorningTimestamp(Date date) {
return getMorning(date).getTime();
}
/**
* 获取2日期相差天数 ,包含头尾
* pattern yyyy-MM-dd
*
* @param beg
* @param end
* @return
*/
public static int getBetDays(String beg, String end) throws ParseException {
DateFormat sdf = getFormat("yyyy-MM-dd");
//new SimpleDateFormat("yyyy-MM-dd");
//跨年不会出现问题
//如果时间为:2016-03-18 11:59:59 和 2016-03-19 00:00:01的话差值为 0
Date fDate = sdf.parse(beg);
Date oDate = sdf.parse(end);
return (int) ((oDate.getTime() - fDate.getTime()) / (1000 * 3600 * 24)) + 1;
}
/**
* 判断两个日期是否为同一天。
*/
public static boolean isOneDay(Date date1, Date date2) {
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(date1);
c2.setTime(date2);
return c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR) && (c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH)) && c1.get(Calendar.DAY_OF_MONTH) == c2.get(Calendar.DAY_OF_MONTH);
}
/**
* Date==>String
*/
public static String formatToString(Date date, String pattern) {
Assert.notNull(date, "date not be null");
DateFormat dateFormat = getFormat(pattern);
return dateFormat.format(date);
}
/**
* Date==>String
*/
public static int formatToInt(Date date, String pattern) {
Assert.notNull(date, "date not be null");
DateFormat dateFormat = getFormat(pattern);
return Integer.parseInt(dateFormat.format(date));
}
/**
* String==>Date
*/
public static Date fromString(String dateString, String pattern) {
Assert.hasLength(dateString, "dateString must have length");
DateFormat dateFormat = getFormat(pattern);
try {
return dateFormat.parse(dateString);
} catch (ParseException e) {
throw new IllegalArgumentException("日期解析错误。");
}
}
/**
* 是否是周末。
*/
public static boolean isWeekEnd(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
return dayOfWeek < 1 || dayOfWeek > 5;
}
/**
* 以天为单位拨动时间。
*
* @param date 要修改的日期
* @param day 修改的数量
*/
public static Date addDay(Date date, int day) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DATE, day);
return calendar.getTime();
}
/**
* 以月为单位拨动时间。
*
* @param date 要修改的日期
* @param month 修改的数量
*/
public static Date addMonth(Date date, int month) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MONTH, month);
return calendar.getTime();
}
/**
* 以年为单位拨动时间。
*
* @param date 要修改的日期
* @param year 修改的数量
*/
public static Date addYear(Date date, int year) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MONTH, year);
return calendar.getTime();
}
/**
* 此日期的当月第一天。
*/
public static Date monthFirstDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_MONTH, 1);
return calendar.getTime();
}
private static DateFormat getFormat(String pattern) {
DateFormat dateFormat;
if (StringUtils.isBlank(pattern)) {
dateFormat = DATEFORMATMAP.get(DEFAULT_FORMAT);
} else {
dateFormat = DATEFORMATMAP.get(pattern);
if (dateFormat == null) {
dateFormat = new SimpleDateFormat(pattern);
DATEFORMATMAP.put(pattern, dateFormat);
}
}
return dateFormat;
}
/**
* 给定时间的前/后sencodes秒时间
*
* @param now 时间
* @param second 前/后秒数,负数为前X秒
* @return
*/
public static Date getAddSeconds(Date now, Integer second) {
if (null == now) {
return null;
}
Calendar c = Calendar.getInstance();
c.setTime(now);
c.add(Calendar.SECOND, second);
return c.getTime();
}
public static boolean isValidDate(String date, String pattern) {
boolean convertSuccess = true;
//指定日期格式为四位年/两位月份/两位日期,注意yyyy/MM/dd区分大小写;
SimpleDateFormat format = new SimpleDateFormat(pattern);
try {
//设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01
format.setLenient(false);
format.parse(date);
} catch (ParseException e) {
// 如果throw java.text.ParseException或者NullPointerException,就说明格式不对
convertSuccess = false;
}
return convertSuccess;
}
/**
* 获取当天的开始时间
*/
public static Date getDayBegin() {
Calendar cal = new GregorianCalendar();
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();
}
/**
* 获取指定日期的开始时间 以00:00:00结尾
*/
public static Date getAppointDayBegin(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTime(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();
}
/**
* 获取当月的起始时间
*/
public static Date getCurrentMonthStartTime() {
Calendar c = Calendar.getInstance();
c.set(Calendar.DATE, 1);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
return c.getTime();
}
/**
* 获取当年的起始时间
*/
public static Date getCurrentYearStartTime() {
Calendar yearStart = Calendar.getInstance();
yearStart.set(Calendar.MONTH, 0);
yearStart.set(Calendar.DATE, 1);
yearStart.set(Calendar.HOUR_OF_DAY, 0);
yearStart.set(Calendar.MINUTE, 0);
yearStart.set(Calendar.SECOND, 0);
yearStart.set(Calendar.MILLISECOND, 0);
return yearStart.getTime();
}
/**
* 获取今天最后一秒
*
* @return 当天最后一秒
*/
public static Long getTodaySurplusSecond() {
Calendar cal = new GregorianCalendar();
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
long end = cal.getTime().getTime();
long star = System.currentTimeMillis();
return (end - star) / 1000;
}
/**
* 获取 类似:2018.02.01 20:11:11 的日期格式
*
* @param date 日期
* @return 日期
*/
public static String getPointDate(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTime(date);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;
int day = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
return year + "." + month + "." + day + " " + (hour < 10 ? "0" + hour : hour) + ":" + (minute < 10 ? "0" + minute : minute) + ":" + (second < 10 ? "0" + second : second);
}
public static String getMMDDHHMMDate(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm");
return sdf.format(date);
}
/**
* 获取指定日期所在月第一天
*
* @param date 指定日期
* @return
*/
public static String getMonthFirstDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MONTH, 0);
calendar.set(Calendar.DAY_OF_MONTH, 1);
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
return sf.format(calendar.getTime());
}
/**
* 获取指定日期所在月最后一天
*
* @param date 指定日期
* @return
*/
public static String getMonthLastDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MONTH, 1);
calendar.set(Calendar.DAY_OF_MONTH, 0);
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
return sf.format(calendar.getTime());
}
/**
* 根据指定日期获取当月包含的天数数组
*
* @return
*/
public static String[] getDaysByDate(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DATE, 1);
calendar.roll(Calendar.DATE, -1);
int maxDate = calendar.get(Calendar.DATE);
log.info("maxDate:{}", maxDate);
String[] str = new String[maxDate];
for (int i = 1; i <= maxDate; i++) {
if (i < 10) {
str[i - 1] = "0" + i;
} else {
str[i - 1] = i + "";
}
}
return str;
}
/**
* 获取过去第几天的日期
*
* @param past
* @return
*/
public static String getPastDate(int past) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);
Date today = calendar.getTime();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String result = format.format(today);
return result;
}
/**
* 获取近7天日期
*
* @return
*/
public static List<String> getSevenDays() {
List<String> list = new ArrayList<>();
for (int i = 0; i < 7; i++) {
list.add(getPastDate(i));
}
return list;
}
/**
* 获取近n天日期
*
* @return
*/
public static List<String> getNDays(int n) {
List<String> list = new ArrayList<>();
for (int i = 0; i < n; i++) {
list.add(getPastDate(i));
}
return list;
}
/**
* 获取过去第几个月
*
* @param i
* @return
*/
public static String getLastMonths(int i) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
Calendar c = Calendar.getInstance();
c.setTime(new Date());
c.add(Calendar.MONTH, -i);
Date m = c.getTime();
return sdf.format(m);
}
/**
* 获取近6个月日期
*
* @return
*/
public static List<String> getSixMonths() {
List<String> list = new ArrayList<>();
for (int i = 0; i < 6; i++) {
list.add(getLastMonths(i));
}
return list;
}
/**
* 通过时间秒毫秒数判断两个时间的间隔
*
* @param date1 较小时间
* @param date2 较大时间
* @return
*/
public static int differentDays(Date date1, Date date2) {
int days = (int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24));
return days;
}
}