package com.cloud.common.utils;
|
|
import org.apache.commons.lang3.StringUtils;
|
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.format.DateTimeParseException;
|
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.TemporalAdjuster;
|
import java.time.temporal.TemporalAdjusters;
|
import java.util.Calendar;
|
import java.util.Date;
|
import java.util.GregorianCalendar;
|
|
|
/**
|
* 日期工具类
|
* @author lp
|
* @date 2018-08-05
|
*/
|
public class DateUtil
|
{
|
|
/**
|
* the milli second of a day
|
*/
|
public static final long DAYMILLI = 24 * 60 * 60 * 1000;
|
/**
|
* the milli seconds of an hour
|
*/
|
public static final long HOURMILLI = 60 * 60 * 1000;
|
/**
|
* the milli seconds of a minute
|
*/
|
public static final long MINUTEMILLI = 60 * 1000;
|
/**
|
* the milli seconds of a second
|
*/
|
public static final long SECONDMILLI = 1000;
|
/**
|
* added time
|
*/
|
public static final String TIMETO = " 23:59:59";
|
/**
|
* flag before
|
*/
|
public static final transient int BEFORE = 1;
|
/**
|
* flag after
|
*/
|
public static final transient int AFTER = 2;
|
/**
|
* flag equal
|
*/
|
public static final transient int EQUAL = 3;
|
/**
|
* date format dd/MMM/yyyy:HH:mm:ss +0900
|
*/
|
public static final String TIME_PATTERN_LONG = "dd/MMM/yyyy:HH:mm:ss +0900";
|
/**
|
* date format dd/MM/yyyy:HH:mm:ss +0900
|
*/
|
public static final String TIME_PATTERN_LONG2 = "dd/MM/yyyy:HH:mm:ss +0900";
|
/**
|
* date format YYYY-MM-DD HH24:MI:SS
|
*/
|
public static final String DB_TIME_PATTERN = "YYYY-MM-DD HH24:MI:SS";
|
/**
|
* date format YYYYMMDDHH24MISS
|
*/
|
public static final String DB_TIME_PATTERN_1 = "YYYYMMDDHH24MISS";
|
/**
|
* date format dd/MM/yy HH:mm:ss
|
*/
|
public static final String TIME_PATTERN_SHORT = "dd/MM/yy HH:mm:ss";
|
/**
|
* date format dd/MM/yy HH24:mm
|
*/
|
public static final String TIME_PATTERN_SHORT_1 = "yyyy/MM/dd HH:mm";
|
/**
|
* date format yyyy年MM月dd日 HH:mm:ss
|
*/
|
public static final String TIME_PATTERN_SHORT_2 = "yyyy年MM月dd日 HH:mm:ss";
|
/**
|
* date format yyyyMMddHHmmss
|
*/
|
public static final String TIME_PATTERN_SESSION = "yyyyMMddHHmmss";
|
/**
|
* date format yyyyMMddHHmmssSSS
|
*/
|
public static final String TIME_PATTERN_MILLISECOND = "yyyyMMddHHmmssSSS";
|
/**
|
* date format yyyyMMdd
|
*/
|
public static final String DATE_FMT_0 = "yyyyMMdd";
|
/**
|
* date format yyyy/MM/dd
|
*/
|
public static final String DATE_FMT_1 = "yyyy/MM/dd";
|
/**
|
* date format yyyy/MM/dd hh:mm:ss
|
*/
|
public static final String DATE_FMT_2 = "yyyy/MM/dd hh:mm:ss";
|
/**
|
* date format yyyy-MM-dd
|
*/
|
public static final String DATE_FMT_3 = "yyyy-MM-dd";
|
/**
|
* date format yyyy年MM月dd日
|
*/
|
public static final String DATE_FMT_4 = "yyyy年MM月dd日";
|
/**
|
* date format yyyy-MM-dd HH
|
*/
|
public static final String DATE_FMT_5 = "yyyy-MM-dd HH";
|
/**
|
* date format yyyy-MM
|
*/
|
public static final String DATE_FMT_6 = "yyyy-MM";
|
/**
|
* date format MM月dd日 HH:mm
|
*/
|
public static final String DATE_FMT_7 = "MM月dd日 HH:mm";
|
/**
|
* date format MM月dd日 HH:mm
|
*/
|
public static final String DATE_FMT_8 = "HH:mm:ss";
|
/**
|
* date format MM月dd日 HH:mm
|
*/
|
public static final String DATE_FMT_9 = "yyyy.MM.dd";
|
public static final String DATE_FMT_10 = "HH:mm";
|
public static final String DATE_FMT_11 = "yyyy.MM.dd HH:mm:ss";
|
/**
|
* date format yyyy年MM月dd日
|
*/
|
public static final String DATE_FMT_12 = "MM月dd日";
|
public static final String DATE_FMT_13 = "yyyy年MM月dd日HH时mm分";
|
public static final String DATE_FMT_14 = "yyyyMM";
|
public static final String DATE_FMT_15 = "MM-dd HH:mm:ss";
|
public static final String DATE_FMT_16 = "yyyyMMddHHmm";
|
public static final String DATE_FMT_17 = "HHmmss";
|
public static final String DATE_FMT_18 = "yyyy";
|
/**
|
* date format yyyy-MM-dd HH:mm:ss
|
*/
|
public static final String TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
private static final Logger logger = LoggerFactory.getLogger(DateUtil.class);
|
|
/**
|
* 得到当前日期的字符串表示
|
*
|
* @return
|
*/
|
public static String getCurrentDateStr()
|
{
|
SimpleDateFormat sdf = new SimpleDateFormat(TIME_PATTERN);
|
try
|
{
|
return sdf.format(new Date());
|
} catch (Exception e)
|
{
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
/**
|
* 等得到当前日期 - 指定格式
|
* @param format
|
* @return
|
*/
|
public static String getCurrentDateStr(String format){
|
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
try
|
{
|
return sdf.format(new Date());
|
} catch (Exception e)
|
{
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
/**
|
* 得到当前指定日期格式
|
* @param format
|
* @return Date
|
*/
|
public static Date getCurrentDate(String format){
|
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
|
String sDate = simpleDateFormat.format(new Date());
|
try
|
{
|
return simpleDateFormat.parse(sDate);
|
} catch (ParseException e)
|
{
|
e.printStackTrace();
|
}
|
return null;
|
|
}
|
|
/**
|
* 得到当前指定日期格式
|
* @param format
|
* @return Date
|
*/
|
public static Date stringToDate(String date,String format)
|
{
|
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
|
try
|
{
|
return simpleDateFormat.parse(date);
|
|
|
} catch (ParseException e)
|
{
|
e.printStackTrace();
|
}
|
return null;
|
|
}
|
|
/**
|
* localDateTime 转 自定义格式string
|
*
|
* @param localDateTime
|
* @param format 例:yyyy-MM-dd hh:mm:ss
|
* @return
|
*/
|
public static String localDateTimeToString(LocalDateTime localDateTime, String format) {
|
try {
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
|
return localDateTime.format(formatter);
|
|
} catch (DateTimeParseException e) {
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
/**
|
* string 转 LocalDateTime
|
*
|
* @param dateStr 例:"2017-08-11 01:00:00"
|
* @param format 例:"yyyy-MM-dd HH:mm:ss"
|
* @return
|
*/
|
public static LocalDateTime stringToLocalDateTime(String dateStr, String format) {
|
try {
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
|
return LocalDateTime.parse(dateStr, formatter);
|
} catch (DateTimeParseException e) {
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
/**
|
* localDate 转 自定义格式string
|
*
|
* @param localDate
|
* @param format 例:yyyy-MM-dd hh:mm:ss
|
* @return
|
*/
|
public static String localDateToString(LocalDate localDate, String format) {
|
try {
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
|
return localDate.format(formatter);
|
|
} catch (DateTimeParseException e) {
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
/**
|
* string 转 LocalDate
|
*
|
* @param dateStr 例:"2017-08-11 01:00:00"
|
* @param format 例:"yyyy-MM-dd HH:mm:ss"
|
* @return
|
*/
|
public static LocalDate stringToLocalDate(String dateStr, String format) {
|
try {
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
|
return LocalDate.parse(dateStr, formatter);
|
} catch (DateTimeParseException e) {
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
/**
|
* 根据时间获取当月有多少天数
|
*
|
* @param date
|
* @return
|
*/
|
public static int getActualMaximum(Date date) {
|
|
return dateToLocalDateTime(date).getMonth().length(dateToLocalDate(date).isLeapYear());
|
}
|
|
/**
|
* 根据日期获得星期
|
*
|
* @param date
|
* @return 1:星期一;2:星期二;3:星期三;4:星期四;5:星期五;6:星期六;7:星期日;
|
*/
|
public static int getWeekOfDate(Date date) {
|
return dateToLocalDateTime(date).getDayOfWeek().getValue();
|
}
|
|
|
/**
|
* 计算两个日期LocalDate相差的天数,不考虑日期前后,返回结果>=0
|
*
|
* @param before
|
* @param after
|
* @return
|
*/
|
public static int getAbsDateDiffDay(LocalDate before, LocalDate after) {
|
|
return Math.abs(Period.between(before, after).getDays());
|
}
|
|
/**
|
* 计算两个时间LocalDateTime相差的天数,不考虑日期前后,返回结果>=0
|
*
|
* @param before
|
* @param after
|
* @return
|
*/
|
public static int getAbsTimeDiffDay(LocalDateTime before, LocalDateTime after) {
|
|
return Math.abs(Period.between(before.toLocalDate(), after.toLocalDate()).getDays());
|
}
|
|
|
|
|
/**
|
* 根据传入日期返回星期几
|
*
|
* @param date 日期
|
* @return 1-7 1:星期天,2:星期一,3:星期二,4:星期三,5:星期四,6:星期五,7:星期六
|
*/
|
public static int getDayOfWeek(Date date) {
|
Calendar cal = new GregorianCalendar();
|
cal.setTime(date);
|
return cal.get(Calendar.DAY_OF_WEEK);
|
}
|
|
|
/**
|
* 获取指定日期的当月的月份数
|
*
|
* @param date
|
* @return
|
*/
|
public static int getLastMonth(Date date) {
|
return dateToLocalDateTime(date).getMonth().getValue();
|
|
}
|
|
|
/**
|
* 特定日期的当月第一天
|
*
|
* @param date 默认当前日期
|
* @return
|
*/
|
public static LocalDate newThisMonth(Date date) {
|
if(date ==null){
|
date =new Date();
|
}
|
LocalDate localDate = dateToLocalDate(date);
|
return LocalDate.of(localDate.getYear(), localDate.getMonth(), 1);
|
}
|
|
/**
|
* 特定日期的当月最后一天
|
*
|
* @param date
|
* @return
|
*/
|
public static LocalDate lastThisMonth(Date date) {
|
if(date ==null){
|
date =new Date();
|
}
|
int lastDay = getActualMaximum(date);
|
LocalDate localDate = dateToLocalDate(date);
|
return LocalDate.of(localDate.getYear(), localDate.getMonth(), lastDay);
|
}
|
|
|
/**
|
* 获得指定某一天 一周的第一天
|
*
|
* @param date 默认当前日期
|
* @return
|
*/
|
public static String newThisWeek(String date)
|
{
|
if (date ==null)
|
{
|
date = getCurrentDateStr(DATE_FMT_3);
|
}
|
LocalDate inputDate = LocalDate.parse(date);
|
TemporalAdjuster firstOfWeek = TemporalAdjusters.ofDateAdjuster(localDate -> localDate.minusDays(localDate.getDayOfWeek().getValue() - DayOfWeek.MONDAY.getValue()));
|
return inputDate.with(firstOfWeek).toString();
|
}
|
|
/**
|
* 获得指定某一天 一周的最后一天
|
*
|
* @param date 默认当前日期
|
* @return
|
*/
|
public static String lastThisWeek(String date)
|
{
|
if (StringUtils.isBlank(date))
|
{
|
date = getCurrentDateStr(DATE_FMT_3);
|
}
|
LocalDate inputDate = LocalDate.parse(date);
|
TemporalAdjuster lastOfWeek = TemporalAdjusters.ofDateAdjuster(localDate -> localDate.plusDays(DayOfWeek.SUNDAY.getValue() - localDate.getDayOfWeek().getValue()));
|
return inputDate.with(lastOfWeek).toString();
|
}
|
|
|
|
/**
|
* 获取当前时间
|
*
|
* @return LocalDateTime
|
*/
|
public static LocalDateTime getCurrentLocalDateTime() {
|
return LocalDateTime.now(Clock.system(ZoneId.of("Asia/Shanghai")));
|
|
}
|
|
|
/**
|
* 修改日期时间的时间部分
|
*
|
* @param date
|
* @param customTime 必须为"hh:mm:ss"这种格式
|
*/
|
public static LocalDateTime reserveDateCustomTime(Date date, String customTime) {
|
String dateStr = dateToLocalDate(date).toString() + " " + customTime;
|
return stringToLocalDateTime(dateStr, "yyyy-MM-dd HH:mm:ss");
|
}
|
|
/**
|
* 修改日期时间的时间部分
|
*
|
* @param date
|
* @param customTime 必须为"hh:mm:ss"这种格式
|
*/
|
public static LocalDateTime reserveDateCustomTime(Timestamp date, String customTime) {
|
String dateStr = timestampToLocalDate(date).toString() + " " + customTime;
|
return stringToLocalDateTime(dateStr, "yyyy-MM-dd HH:mm:ss");
|
}
|
|
/**
|
* 把日期后的时间归0 变成(yyyy-MM-dd 00:00:00:000)
|
*
|
* @param date
|
* @return LocalDateTime
|
*/
|
public static final LocalDateTime zerolizedTime(Date date) {
|
LocalDateTime localDateTime = dateToLocalDateTime(date);
|
return LocalDateTime.of(localDateTime.getYear(), localDateTime.getMonth(), localDateTime.getDayOfMonth(), 0, 0, 0, 0);
|
|
}
|
|
/**
|
* 把时间变成(yyyy-MM-dd 00:00:00:000)
|
*
|
* @param date
|
* @return LocalDateTime
|
*/
|
public static LocalDateTime zerolizedTime(Timestamp date) {
|
LocalDateTime localDateTime = timestampToLocalDateTime(date);
|
return LocalDateTime.of(localDateTime.getYear(), localDateTime.getMonth(), localDateTime.getDayOfMonth(), 0, 0, 0, 0);
|
}
|
|
/**
|
* 把日期的时间变成(yyyy-MM-dd 23:59:59:999)
|
*
|
* @param date
|
* @return LocalDateTime
|
*/
|
public static LocalDateTime getEndTime(Date date) {
|
LocalDateTime localDateTime = dateToLocalDateTime(date);
|
return LocalDateTime.of(localDateTime.getYear(), localDateTime.getMonth(), localDateTime.getDayOfMonth(), 23, 59, 59, 999 * 1000000);
|
}
|
|
/**
|
* 把时间变成(yyyy-MM-dd 23:59:59:999)
|
*
|
* @param date
|
* @return LocalDateTime
|
*/
|
public static LocalDateTime getEndTime(Timestamp date) {
|
LocalDateTime localDateTime = timestampToLocalDateTime(date);
|
return LocalDateTime.of(localDateTime.getYear(), localDateTime.getMonth(), localDateTime.getDayOfMonth(), 23, 59, 59, 999 * 1000000);
|
}
|
|
/**
|
* 计算特定时间到 当天 23.59.59.999 的秒数
|
*
|
* @return
|
*/
|
public static int calculateToEndTime(Date date) {
|
LocalDateTime localDateTime = dateToLocalDateTime(date);
|
LocalDateTime end = getEndTime(date);
|
return (int) (end.toEpochSecond(ZoneOffset.UTC) - localDateTime.toEpochSecond(ZoneOffset.UTC));
|
}
|
|
|
/**
|
* 增加或减少年/月/周/天/小时/分/秒数
|
*
|
* @param localDateTime 例:ChronoUnit.DAYS
|
* @param chronoUnit
|
* @param num
|
* @return LocalDateTime
|
*/
|
public static LocalDateTime addTime(LocalDateTime localDateTime, ChronoUnit chronoUnit, int num) {
|
return localDateTime.plus(num, chronoUnit);
|
}
|
|
/**
|
* 增加或减少年/月/周/天/小时/分/秒数
|
*
|
* @param chronoUnit 例:ChronoUnit.DAYS
|
* @param num
|
* @return LocalDateTime
|
*/
|
public static LocalDateTime addTime(Date date, ChronoUnit chronoUnit, int num) {
|
long nanoOfSecond = (date.getTime() % 1000) * 1000000;
|
LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(date.getTime() / 1000, (int) nanoOfSecond, ZoneOffset.of("+8"));
|
return localDateTime.plus(num, chronoUnit);
|
}
|
|
/**
|
* 增加或减少年/月/周/天/小时/分/秒数
|
*
|
* @param chronoUnit 例:ChronoUnit.DAYS
|
* @param num
|
* @return LocalDateTime
|
*/
|
public static LocalDateTime addTime(Timestamp date, ChronoUnit chronoUnit, int num) {
|
long nanoOfSecond = (date.getTime() % 1000) * 1000000;
|
LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(date.getTime() / 1000, (int) nanoOfSecond, ZoneOffset.of("+8"));
|
return localDateTime.plus(num, chronoUnit);
|
}
|
|
/**
|
* Date 转 LocalDateTime
|
*
|
* @param date
|
* @return LocalDateTime
|
*/
|
public static LocalDateTime dateToLocalDateTime(Date date) {
|
long nanoOfSecond = (date.getTime() % 1000) * 1000000;
|
LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(date.getTime() / 1000, (int) nanoOfSecond, ZoneOffset.of("+8"));
|
|
return localDateTime;
|
}
|
|
/**
|
* Timestamp 转 LocalDateTime
|
*
|
* @param date
|
* @return LocalDateTime
|
*/
|
public static LocalDateTime timestampToLocalDateTime(Timestamp date) {
|
LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(date.getTime() / 1000, date.getNanos(), ZoneOffset.of("+8"));
|
|
return localDateTime;
|
}
|
|
/**
|
* Date 转 LocalDateTime
|
*
|
* @param date
|
* @return LocalDate
|
*/
|
public static LocalDate dateToLocalDate(Date date) {
|
|
return dateToLocalDateTime(date).toLocalDate();
|
}
|
|
/**
|
* timestamp 转 LocalDateTime
|
*
|
* @param date
|
* @return LocalDate
|
*/
|
public static LocalDate timestampToLocalDate(Timestamp date) {
|
|
return timestampToLocalDateTime(date).toLocalDate();
|
}
|
|
/**
|
* 比较两个LocalDateTime是否同一天
|
*
|
* @param begin
|
* @param end
|
* @return
|
*/
|
public static boolean isTheSameDay(LocalDateTime begin, LocalDateTime end) {
|
return begin.toLocalDate().equals(end.toLocalDate());
|
}
|
|
|
/**
|
* 比较两个时间LocalDateTime大小
|
*
|
* @param time1
|
* @param time2
|
* @return 1:第一个比第二个大;0:第一个与第二个相同;-1:第一个比第二个小
|
*/
|
public static int compareTwoTime(LocalDateTime time1, LocalDateTime time2) {
|
|
if (time1.isAfter(time2)) {
|
return 1;
|
} else if (time1.isBefore(time2)) {
|
return -1;
|
} else {
|
return 0;
|
}
|
}
|
|
|
/**
|
* 比较time1,time2两个时间相差的秒数,如果time1<=time2,返回0
|
*
|
* @param time1
|
* @param time2
|
*/
|
public static long getTwoTimeDiffSecond(Timestamp time1, Timestamp time2) {
|
long diff = timestampToLocalDateTime(time1).toEpochSecond(ZoneOffset.UTC) - timestampToLocalDateTime(time2).toEpochSecond(ZoneOffset.UTC);
|
if (diff > 0) {
|
return diff;
|
} else {
|
return 0;
|
}
|
}
|
|
/**
|
* 比较time1,time2两个时间相差的分钟数,如果time1<=time2,返回0
|
*
|
* @param time1
|
* @param time2
|
*/
|
public static long getTwoTimeDiffMin(Timestamp time1, Timestamp time2) {
|
long diff = getTwoTimeDiffSecond(time1, time2) / 60;
|
if (diff > 0) {
|
return diff;
|
} else {
|
return 0;
|
}
|
}
|
|
/**
|
* 比较time1,time2两个时间相差的小时数,如果time1<=time2,返回0
|
*
|
* @param time1
|
* @param time2
|
*/
|
public static long getTwoTimeDiffHour(Timestamp time1, Timestamp time2) {
|
long diff = getTwoTimeDiffSecond(time1, time2) / 3600;
|
if (diff > 0) {
|
return diff;
|
} else {
|
return 0;
|
}
|
}
|
|
/**
|
* 判断当前时间是否在时间范围内
|
*
|
* @param startTime
|
* @param endTime
|
* @return
|
*/
|
public static boolean isTimeInRange(Date startTime, Date endTime) throws Exception {
|
LocalDateTime now = getCurrentLocalDateTime();
|
LocalDateTime start = dateToLocalDateTime(startTime);
|
LocalDateTime end = dateToLocalDateTime(endTime);
|
return (start.isBefore(now) && end.isAfter(now)) || start.isEqual(now) || end.isEqual(now);
|
}
|
|
public static boolean isValidDate(String str) {
|
boolean convertSuccess=true;
|
// 指定日期格式为四位年/两位月份/两位日期,注意yyyy/MM/dd区分大小写;
|
SimpleDateFormat format = new SimpleDateFormat(TIME_PATTERN);
|
try {
|
// 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01
|
format.setLenient(false);
|
format.parse(str);
|
} catch (ParseException e) {
|
e.printStackTrace();
|
convertSuccess=false;
|
}
|
return convertSuccess;
|
}
|
|
public static void main(String[] args) {
|
|
System.out.println(DateUtil.getCurrentDateStr());
|
System.out.println(DateUtil.newThisMonth(null) + "--------" +DateUtil.newThisWeek(null));
|
System.out.println(DateUtil.lastThisMonth(null) + "--------" +DateUtil.lastThisMonth(null));
|
|
|
}
|
|
|
}
|