本文是JAVA的DateUtil时间工具类,包含常用的时间类的操作,如常用的时间转换和取值、校验时间格式、转换时间格式、计算两个时间的差值、获取给定的两个日期之间的月份等操作。代码为作者自用的或网上搜索的时间操作整合而来,如与其他作者雷同还请见谅。其它编程语言如C#也可用AI自行转为对应的工具类使用
1.需要引入依赖
commons依赖主要用于参数的判空,如不需要判空或项目有可用的判空方法也可以不引用此依赖并将当前工具类代码中的判空删除或替换为自己的判空方法
Maven
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
Gradle
implementation 'org.apache.commons:commons-lang3:3.9'
Gradle高版本
implementation ("org.apache.commons:commons-lang3:3.9")
2.完整代码如下
package com.example.utils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;
public class DateUtils {
/** 仅显示年月日,例如 2015-08-11. */
public static final String DATE_FORMAT = "yyyy-MM-dd";
/** 显示年月日时分秒,例如 2015-08-11 09:51:53. */
public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
/** 仅显示时分秒,例如 09:51:53. */
public static final String TIME_FORMAT = "HH:mm:ss";
/** 每天的毫秒数 8640000. */
public static final long MILLISECONDS_PER_DAY = 86400000L;
/** 每周的天数. */
public static final long DAYS_PER_WEEK = 7L;
/** 每小时毫秒数. */
public static final long MILLISECONDS_PER_HOUR = 3600000L;
/** 每分钟秒数. */
public static final long SECONDS_PER_MINUTE = 60L;
/** 每小时秒数. */
public static final long SECONDS_PER_HOUR = 3600L;
/** 每天秒数. */
public static final long SECONDS_PER_DAY = 86400L;
/** 每个月秒数,默认每月30天. */
public static final long SECONDS_PER_MONTH = 2592000L;
/** 每年秒数,默认每年365天. */
public static final long SECONDS_PER_YEAR = 31536000L;
/** 日期格式,年份和月份,例如:200707,2008-08 */
public static final String DATE_FORMAT_YYYY_MM = "yyyy-MM";
/** 日期格式,年月日,用横杠分开,例如:2006-12-25,2008-08-08 */
public static final String DATE_FORMAT_YYYY_MM_DD = "yyyy-MM-dd";
/** 常用的时间格式. */
private static String[] parsePatterns = {
"yyyy-MM-dd",
"yyyy-MM-dd HH:mm:ss",
"yyyy-MM-dd HH:mm",
"yyyy/MM/dd",
"yyyy/MM/dd HH:mm:ss",
"yyyy/MM/dd HH:mm"
};
private static String DATE_REGEX =
"^([1-9]\\d{3}-)(([0]{0,1}[1-9]-)|([1][0-2]-))(([0-3]{0,1}[0-9]))$";
/**
* 得到当前日期字符串.
*
* @return String 日期字符串,例如2015-08-11
* @since 1.0
*/
public static String getDate() {
return getDate(DateUtils.DATE_FORMAT);
}
/**
* 得到当前时间字符串.
*
* @return String 时间字符串,例如 09:51:53
* @since 1.0
*/
public static String getTime() {
return formatDate(new Date(), DateUtils.TIME_FORMAT);
}
/**
* 得到当前日期和时间字符串.
*
* @return String 日期和时间字符串,例如 2015-08-11 09:51:53
* @since 1.0
*/
public static String getDateTime() {
return formatDate(new Date(), DateUtils.DATETIME_FORMAT);
}
/**
* 获取当前时间指定格式下的字符串.
*
* @param pattern 转化后时间展示的格式,例如"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss"等
* @return String 格式转换之后的时间字符串.
* @since 1.0
*/
public static String getDate(String pattern) {
return DateFormatUtils.format(new Date(), pattern);
}
/**
* 获取指定日期的字符串格式.
*
* @param date 需要格式化的时间,不能为空
* @param pattern 时间格式,例如"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss"等
* @return String 格式转换之后的时间字符串.
* @since 1.0
*/
public static String getDate(Date date, String pattern) {
return DateFormatUtils.format(date, pattern);
}
/**
* 获取日期时间字符串,默认格式为(yyyy-MM-dd).
*
* @param date 需要转化的日期时间
* @param pattern 时间格式,例如"yyyy-MM-dd" "HH:mm:ss" "E"等
* @return String 格式转换后的时间字符串
* @since 1.0
*/
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, DateUtils.DATE_FORMAT);
}
return formatDate;
}
/**
* 获取当前年份字符串.
*
* @return String 当前年份字符串,例如 2015
* @since 1.0
*/
public static String getYear() {
return formatDate(new Date(), "yyyy");
}
/**
* 获取当前月份字符串.
*
* @return String 当前月份字符串,例如 08
* @since 1.0
*/
public static String getMonth() {
return formatDate(new Date(), "MM");
}
/**
* 获取当前天数字符串.
*
* @return String 当前天数字符串,例如 11
* @since 1.0
*/
public static String getDay() {
return formatDate(new Date(), "dd");
}
/**
* 获取当前星期字符串.
*
* @return String 当前星期字符串,例如星期二
* @since 1.0
*/
public static String getWeek() {
return formatDate(new Date(), "E");
}
/**
* 将日期型字符串转换为日期格式. 支持的日期字符串格式包括"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
* "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm"
*
* @param str
* @return Date
* @since 1.0
*/
public static Date parseDate(Object str) {
if (str == null) {
return null;
}
try {
return org.apache.commons.lang3.time.DateUtils.parseDate(str.toString(), parsePatterns);
} catch (ParseException e) {
return null;
}
}
/**
* 获取当前日期与指定日期相隔的天数.
*
* @param date 给定的日期
* @return long 日期间隔天数,正数表示给定日期在当前日期之前,负数表示在当前日期之后
* @since 1.0
*/
public static long pastDays(Date date) {
// 将指定日期转换为yyyy-MM-dd格式
date = DateUtils.parseDate(DateUtils.formatDate(date, DateUtils.DATE_FORMAT));
// 当前日期转换为yyyy-MM-dd格式
Date currentDate = DateUtils.parseDate(DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT));
long t = 0;
if (date != null && currentDate != null) {
t = (currentDate.getTime() - date.getTime()) / DateUtils.MILLISECONDS_PER_DAY;
}
return t;
}
/**
* 获取当前日期指定天数之后的日期.
*
* @param num 相隔天数
* @return Date 日期
* @since 1.0
*/
public static Date nextDay(int num) {
Calendar curr = Calendar.getInstance();
curr.set(Calendar.DAY_OF_MONTH, curr.get(Calendar.DAY_OF_MONTH) + num);
return curr.getTime();
}
/**
* 获取当前日期指定月数之后的日期.
*
* @param num 间隔月数
* @return Date 日期
* @since 1.0
*/
public static Date nextMonth(int num) {
Calendar curr = Calendar.getInstance();
curr.set(Calendar.MONTH, curr.get(Calendar.MONTH) + num);
return curr.getTime();
}
/**
* 获取当前日期指定年数之后的日期.
*
* @param num 间隔年数
* @return Date 日期
* @since 1.0
*/
public static Date nextYear(int num) {
Calendar curr = Calendar.getInstance();
curr.set(Calendar.YEAR, curr.get(Calendar.YEAR) + num);
return curr.getTime();
}
/**
* 将 Date 日期转化为 Calendar 类型日期.
*
* @param date 给定的时间,若为null,则默认为当前时间
* @return Calendar Calendar对象
* @since 1.0
*/
public static Calendar getCalendar(Date date) {
Calendar calendar = Calendar.getInstance();
// calendar.setFirstDayOfWeek(Calendar.SUNDAY);//每周从周日开始
// calendar.setMinimalDaysInFirstWeek(1); // 设置每周最少为1天
if (date != null) {
calendar.setTime(date);
}
return calendar;
}
/**
* 计算两个日期之间相差天数.
*
* @param start 计算开始日期
* @param end 计算结束日期
* @return long 相隔天数
* @since 1.0
*/
public static long getDaysBetween(Date start, Date end) {
// 将指定日期转换为yyyy-MM-dd格式
start = DateUtils.parseDate(DateUtils.formatDate(start, DateUtils.DATE_FORMAT));
// 当前日期转换为yyyy-MM-dd格式
end = DateUtils.parseDate(DateUtils.formatDate(end, DateUtils.DATE_FORMAT));
long diff = 0;
if (start != null && end != null) {
diff = (end.getTime() - start.getTime()) / DateUtils.MILLISECONDS_PER_DAY;
}
return diff;
}
/**
* 计算两个日期之前相隔多少周.
*
* @param start 计算开始时间
* @param end 计算结束时间
* @return long 相隔周数,向下取整
* @since 1.0
*/
public static long getWeeksBetween(Date start, Date end) {
return getDaysBetween(start, end) / DateUtils.DAYS_PER_WEEK;
}
/**
* 获取与指定日期间隔给定天数的日期.
*
* @param specifiedDay 给定的字符串格式日期,支持的日期字符串格式包括"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd
* HH:mm", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm"
* @param num 间隔天数
* @return String 间隔指定天数之后的日期
* @since 1.0
*/
public static String getSpecifiedDayAfter(String specifiedDay, int num) {
Date specifiedDate = parseDate(specifiedDay);
Calendar c = Calendar.getInstance();
c.setTime(specifiedDate);
int day = c.get(Calendar.DATE);
c.set(Calendar.DATE, day + num);
String dayAfter = formatDate(c.getTime(), DateUtils.DATE_FORMAT);
return dayAfter;
}
/**
* 获取当前时间前后hour小时的时间,负数是前正数是后
* @param date
* @param hour
* @return java.util.Date
*/
public static Date beforeOneHourToNowDate(Date date,int hour) {
Calendar calendar = Calendar.getInstance();
/* HOUR_OF_DAY 指示一天中的小时 */
calendar.setTime(date);
calendar.add(Calendar.HOUR_OF_DAY, hour);
return calendar.getTime();
}
/**
* 获取当前时间前后minute分钟的时间,负数是前正数是后
* @param date
* @param minute
* @return java.util.Date
*/
public static Date getFiveMinAfter(Date date, Integer minute) throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Calendar now = Calendar.getInstance();
now.setTime(date);
now.add(Calendar.MINUTE,minute);
return now.getTime();
}
/**
* 获取指定时间与当前时间的间隔毫秒数
* @param date
* @return java.util.Date
*/
public static Integer diff(Date date) throws ParseException {
long currentTime =System.currentTimeMillis();
long createTime = date.getTime();
long diff=(currentTime-createTime)/1000/60;
return Integer.parseInt(String.valueOf(diff));
}
/**
* 计算两个日期之前间隔的小时数.
*
* @param date1 结束时间
* @param date2 开始时间
* @return String 相差的小时数,保留一位小数
* @since 1.0
*/
public static String dateMinus(Date date1, Date date2) {
if (date1 == null || date2 == null) {
return "0";
}
Long r = date1.getTime() - date2.getTime();
DecimalFormat df = new DecimalFormat("#.0");
double result = r * 1.0 / DateUtils.MILLISECONDS_PER_HOUR;
return df.format(result);
}
/**
* 获取当前季度 .
*
* @return Integer 当前季度数
* @since 1.0
*/
public static Integer getCurrentSeason() {
Calendar calendar = Calendar.getInstance();
Integer month = calendar.get(Calendar.MONTH) + 1;
int season = 0;
if (month >= 1 && month <= 3) {
season = 1;
} else if (month >= 4 && month <= 6) {
season = 2;
} else if (month >= 7 && month <= 9) {
season = 3;
} else if (month >= 10 && month <= 12) {
season = 4;
}
return season;
}
/**
* 将以秒为单位的时间转换为其他单位.
*
* @param seconds 秒数
* @return String 例如 16分钟前、2小时前、3天前、4月前、5年前等
* @since 1.0
*/
public static String getIntervalBySeconds(long seconds) {
StringBuffer buffer = new StringBuffer();
if (seconds < SECONDS_PER_MINUTE) {
buffer.append(seconds).append("秒前");
} else if (seconds < SECONDS_PER_HOUR) {
buffer.append(seconds / SECONDS_PER_MINUTE).append("分钟前");
} else if (seconds < SECONDS_PER_DAY) {
buffer.append(seconds / SECONDS_PER_HOUR).append("小时前");
} else if (seconds < SECONDS_PER_MONTH) {
buffer.append(seconds / SECONDS_PER_DAY).append("天前");
} else if (seconds < SECONDS_PER_YEAR) {
buffer.append(seconds / SECONDS_PER_MONTH).append("月前");
} else {
buffer.append(seconds / DateUtils.SECONDS_PER_YEAR).append("年前");
}
return buffer.toString();
}
/**
* getNowTimeBefore(记录时间相当于目前多久之前)
*
* @param seconds 秒
* @return
* @exception @since 1.0
* @author rlliu
*/
public static String getNowTimeBefore(long seconds) {
StringBuffer buffer = new StringBuffer();
buffer.append("上传于");
if (seconds < 3600) {
buffer.append((long) Math.floor(seconds / 60.0)).append("分钟前");
} else if (seconds < 86400) {
buffer.append((long) Math.floor(seconds / 3600.0)).append("小时前");
} else if (seconds < 604800) {
buffer.append((long) Math.floor(seconds / 86400.0)).append("天前");
} else if (seconds < 2592000) {
buffer.append((long) Math.floor(seconds / 604800.0)).append("周前");
} else if (seconds < 31104000) {
buffer.append((long) Math.floor(seconds / 2592000.0)).append("月前");
} else {
buffer.append((long) Math.floor(seconds / 31104000.0)).append("年前");
}
return buffer.toString();
}
/**
* getMonthsBetween(查询两个日期相隔的月份)
*
* @param startDate 开始日期1 (格式yyyy-MM-dd)
* @param endDate 截止日期2 (格式yyyy-MM-dd)
* @return
*/
public static int getMonthsBetween(String startDate, String endDate) {
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(DateUtils.parseDate(startDate));
c2.setTime(DateUtils.parseDate(endDate));
int year = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
int month = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);
return Math.abs(year * 12 + month);
}
/**
* getDayOfWeek(获取当前日期是星期几)
*
* @param dateStr 日期
* @return 星期几
*/
public static String getDayOfWeek(String dateStr) {
String[] weekOfDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
Date date = parseDate(dateStr);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int num = calendar.get(Calendar.DAY_OF_WEEK) - 1;
return weekOfDays[num];
}
/**
* sns 格式 如几秒前,几分钟前,几小时前,几天前,几个月前,几年后, ... 精细,类如某个明星几秒钟之前发表了一篇微博
*
* @param createTime
* @return
*/
public static String snsFormat(long createTime) {
long now = System.currentTimeMillis() / 1000;
long differ = now - createTime / 1000;
String dateStr = "";
if (differ <= 60) {
dateStr = "刚刚";
} else if (differ <= 3600) {
dateStr = (differ / 60) + "分钟前";
} else if (differ <= 3600 * 24) {
dateStr = (differ / 3600) + "小时前";
} else if (differ <= 3600 * 24 * 30) {
dateStr = (differ / (3600 * 24)) + "天前";
} else {
Date date = new Date(createTime);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
dateStr = sdf.format(date);
}
return dateStr;
}
/**
* 得到UTC时间,类型为字符串,格式为"yyyy-MM-dd HH:mm" 如果获取失败,返回null
*
* @return
*/
public static String getUTCTimeStr() {
StringBuffer UTCTimeBuffer = new StringBuffer();
// 1、取得本地时间:
Calendar cal = Calendar.getInstance();
// 2、取得时间偏移量:
int zoneOffset = cal.get(Calendar.ZONE_OFFSET);
// 3、取得夏令时差:
int dstOffset = cal.get(Calendar.DST_OFFSET);
// 4、从本地时间里扣除这些差量,即可以取得UTC时间:
cal.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
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);
UTCTimeBuffer.append(year).append("-").append(month).append("-").append(day);
UTCTimeBuffer.append(" ").append(hour).append(":").append(minute);
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
sdf.parse(UTCTimeBuffer.toString());
return UTCTimeBuffer.toString();
} catch (ParseException e) {
}
return null;
}
/**
* 格式化String时间 年份和月份和天
*
* @param time String类型时间
* @return 格式化后的Date日期
*/
public static String dayAndYearParse(String time) {
if (StringUtils.isBlank(time)) {
return null;
}
String date = null;
try {
DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_YYYY_MM_DD);
date = dateFormat.format(dateFormat.parse(time));
} catch (Exception e) {
String fullStackTrace = ExceptionUtils.getStackTrace(e);
}
return date;
}
/**
* 时间增加一月
*
* @param time
* @return
*/
public static String dateAddMonth(String time) {
if (StringUtils.isBlank(time)) {
return null;
}
String date = null;
try {
DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_YYYY_MM);
Calendar calendar = Calendar.getInstance();
calendar.setTime(dateFormat.parse(time));
calendar.add(Calendar.MONTH, 1);
date = dateFormat.format(calendar.getTime());
} catch (Exception e) {
String fullStackTrace = ExceptionUtils.getStackTrace(e);
}
return date;
}
/**
* 格式化String时间 年份和月份
*
* @param time String类型时间
* @return 格式化后的Date日期
*/
public static String monthAndYearParse(String time) {
if (StringUtils.isBlank(time)) {
return null;
}
String date = null;
try {
DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_YYYY_MM);
date = dateFormat.format(dateFormat.parse(time));
} catch (Exception e) {
String fullStackTrace = ExceptionUtils.getStackTrace(e);
}
return date;
}
/**
* 计算时间差
* @param minDate 最小时间
* @param maxDate 最大时间
* @return 日期集合 格式为 年-月
* @throws Exception
*/
public static List<String> getMonthBetween(String minDate, String maxDate) {
ArrayList<String> result = null;
try {
result = new ArrayList<>();
// 格式化为年月
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
Calendar min = Calendar.getInstance();
Calendar max = Calendar.getInstance();
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);
Calendar curr = min;
while (curr.before(max)) {
result.add(sdf.format(curr.getTime()));
curr.add(Calendar.MONTH, 1);
}
} catch (Exception e) {
String fullStackTrace = ExceptionUtils.getStackTrace(e);
System.out.println(fullStackTrace);
}
return result;
}
/***
* @desc 校验日期的格式,yyyy-MM-dd,无法校验dd的完整性,
* 就是可能出现 2020-2-32,2020-1-33这样的天数,可以通过设置日期的严禁性来转成日期,若报错则日期不正确
* @author chenyu
* @date 2020-09-28 18:50
* @param
* @param date:日期,格式:yyyy-MM-dd
* @return boolean
*/
public static boolean validDate(String date) {
boolean matches = Pattern.matches(DATE_REGEX, date);
if (!matches) {
return false;
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 设置日期格式转的严谨性
sdf.setLenient(false);
try {
sdf.parse(date);
} catch (Exception e) {
String fullStackTrace = ExceptionUtils.getStackTrace(e);
return false;
}
return true;
}
/***
* 比较两个日期相差时间大小 时分秒
* @param date1 需要比较的时间
* @param date2 当前时期 或需要比较的日期
* @return
* @throws ParseException
*/
public static Long[] checkDate(Date date1, Date date2) throws ParseException {
Long[] difference = new Long[4];
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = df.parse(df.format(date1));
Date date = df.parse(DateUtils.getDate(new Date(), DateUtils.DATETIME_FORMAT));
System.out.println(DateUtils.getDate(new Date(), DateUtils.DATETIME_FORMAT));
System.out.println(df.format(date1));
long l = now.getTime() - date.getTime();
long day = l / (24 * 60 * 60 * 1000);
long hour = (l / (60 * 60 * 1000) - day * 24);
long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
difference[0] = day;
difference[1] = hour;
difference[2] = min;
difference[3] = s;
return difference;
}
}