java项目中经常会使用到对日期进行格式校验、格式化日期、LocalDate与Date互转等等,以下整理一份经常会使用到的日期操作相关的方法。
一般项目中需要对入参进行校验,比如必须是一个合法的日期且格式为yyyy-MM-dd,则可使用以下方法对日期进行校验
public static void main(String[] args) {
String date = "2018-02- 9";
// 调用isLegalDate方法的时候,length参数一定要是要校验日期的length
System.out.println(isLegalDate(date,date.length(),"yyyy-MM-dd")); //false
//如下面的示例,若length传入的是date的长度,则以下这种日期格式也能用isLegalDate方法进行校验
date = "2018年02月09日";
System.out.println(isLegalDate(date,date.length(),"yyyy'年'MM'月'dd'日'"));//true
}
/**
* 校验日期是否是符合指定格式的合法日期
* <p>
* 此方法是为了解决接口入参的日期格式校验,我们需要接口入参是日期是一个合法的而且是指定格式的日期
* </p>
*
* @param date 日期
* @param length 日期的长度,必须是date参数的长度,这样可以兼容多种格式的校验
* @param format 日期的格式,需要与日期格式保持一致
* @return
*/
public static boolean isLegalDate(String date,int length,String format){
if(date == null || date.length() != length){
return false;
}
try{
DateFormat formatter = new SimpleDateFormat(format);
// 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期,比如2018-02-29会被接受,并转换成2018-03-01
//"2019022 "|"201902 2" 这两种也能被Date转化,所以最后需要用date.equals(formatter.format(date1));
formatter.setLenient(false);
Date date1 = formatter.parse(date);
log.info("入参:"+date+";转换后日期:"+formatter.format(date1));
return date.equals(formatter.format(date1));
}catch (Exception e){
log.info(e.getMessage(),e);
return false;
}
}
将String类型的日期转化为Date类型
public static void main(String[] args) {
String date = "2018-02-09";
System.out.println(parse(date,"yyyy-MM-dd")); //Fri Feb 09 00:00:00 CST 2018
}
/**
* 使用用户格式格式化日期
*
* @param date 日期
* @param pattern 日期格式,格式需要与入参格式保持一致
* @return
*/
public static Date parse(String date, String pattern) {
Date returnValue = null;
if (date != null) {
SimpleDateFormat df = new SimpleDateFormat(pattern);
try {
returnValue = df.parse(date);
} catch (ParseException e) {
// throw new BusinessException(ResponseEnum.DATE_PARSE_FAILURE);
}
}
return returnValue;
}
将Date类型的日期格式化为String类型,如将Date输出为yyyyMMdd、yyyy-MM-dd、yyyy-MM格式等等
public static void main(String[] args) {
Date date = parse("2022-02-05", "yyyy-MM-dd");
System.out.println(format(date, "yyyy-MM-dd")); //2022-02-05
System.out.println(format(date, "yyyyMMdd")); //20220205
System.out.println(format(date, "yyyy-MM")); //2022-02
}
/**
* 使用用户格式格式化日期
*
* @param date 日期
* @param pattern 日期格式
* @return
*/
public static String format(Date date, String pattern) {
String returnValue = "";
if (date != null) {
SimpleDateFormat df = new SimpleDateFormat(pattern);
returnValue = df.format(date);
}
return (returnValue);
}
如获取2022-02-02所在季度的第一天
/**
* 获取入参所在季度的第一天
* @param date
* @return
*/
public static Date getQuarterStart(Date date){
Calendar startCalendar = Calendar.getInstance();
startCalendar.setTime(date);
//get方法:获取给定日历属性的值,如 endCalendar.get(Calendar.MONTH) 获取日历的月份
//计算季度数:由于月份从0开始,即1月份的Calendar.MONTH值为0,所以计算季度的第一个月份只需 月份 / 3 * 3
startCalendar.set(Calendar.MONTH, ((startCalendar.get(Calendar.MONTH)) / 3) * 3);
startCalendar.set(Calendar.DAY_OF_MONTH, 1);
return startCalendar.getTime();
}
如获取2022-02-02所在季度的最后一天
/**
* 获取入参所在季度的最后一天
* @param date
* @return
*/
public static Date getQuarterEnd(Date date) { // 季度结束
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(date);
//计算季度数:由于月份从0开始,即1月份的Calendar.MONTH值为0,所以计算季度的第三个月份只需 月份 / 3 * 3 + 2
endCalendar.set(Calendar.MONTH, ((endCalendar.get(Calendar.MONTH)) / 3) * 3 + 2);
endCalendar.set(Calendar.DAY_OF_MONTH, endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
return endCalendar.getTime();
}
/**
* LocalDate转为Date 格式
* @param localDate
* @return
*/
public static Date localDateToDate(LocalDate localDate){
ZoneId zone = ZoneId.systemDefault();
Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
return Date.from(instant);
}
import lombok.extern.slf4j.Slf4j;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
@Slf4j
public class DateUtil {
public static void main(String[] args) {
String date = "2018-02- 9";
System.out.println(isLegalDate(date,date.length(),"yyyy-MM-dd"));
}
/**
* 校验日期是否是符合指定格式的合法日期
* <p>
* 此方法是为了解决接口入参的日期格式校验,我们需要接口入参是日期是一个合法的而且是指定格式的日期
* </p>
*
* @param date 日期
* @param length 日期的长度
* @param format 日期的格式,需要与日期格式保持一致
* @return
*/
public static boolean isLegalDate(String date,int length,String format){
if(date == null || date.length() != length){
return false;
}
try{
DateFormat formatter = new SimpleDateFormat(format);
// 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期,比如2018-02-29会被接受,并转换成2018-03-01
//"2019022 "|"201902 2" 这两种也能被Date转化,所以最后需要用date.equals(formatter.format(date1));
formatter.setLenient(false);
Date date1 = formatter.parse(date);
log.info("入参:"+date+";转换后日期:"+formatter.format(date1));
return date.equals(formatter.format(date1));
}catch (Exception e){
log.info(e.getMessage(),e);
return false;
}
}
/**
* 将LocalDateTime转换成Date
*
* @param localDateTime
* @return
*/
public static Date localDateTimeToDate (LocalDateTime localDateTime) {
if (null == localDateTime) {
return null;
}
try {
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
} catch (Exception e) {
log.warn("将LocalDateTime转换成Date发生异常 : " + e.getMessage(), e);
return null;
}
}
/**
* 将Date转换成LocalDateTime
*
* @param date
* @return
*/
public static LocalDateTime dateToLocalDateTime (Date date) {
if (null == date) {
return null;
}
try {
Instant instant = date.toInstant();
ZoneId zoneId = ZoneId.systemDefault();
return instant.atZone(zoneId).toLocalDateTime();
} catch (Exception e) {
log.warn("将Date转换成LocalDateTime发生异常 : " + e.getMessage(), e);
return null;
}
}
/**
* 获取当日最小时间(0时0分0秒)
* @return
*/
public static LocalDateTime getCurrentDayStart () {
return LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
}
/**
* 获取当日最大时间(23时59分59秒)
* @return
*/
public static LocalDateTime getCurrentDayEnd () {
return LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
}
/**
* 获取昨天的年月日 yyyy-MM-dd
* @return
*/
public static String getStringYesterday(){
LocalDate date = LocalDate.now().plusDays(-1);
return date.toString();
}
/**
* 获取入参日期的前一天 yyyyMMdd
* @param date 日期 yyyy-MM-dd/yyyyMMdd
* @param pattern 必须与data参数格式保持一致,若入参data是八位,则pattern为yyyyMMdd
* @return yyyyMMdd
*/
public static Integer getBeforeOfDate(String date,String pattern){
LocalDate localDate = LocalDate.parse(date,DateTimeFormatter.ofPattern(pattern)).plusDays(-1); //直接调用parse的话,入参必须是10位的日期即yyyy-MM-dd,若位数缺少,会抛异常
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
return Integer.parseInt(localDate.format(dtf));
}
/**
* 获取当前自然日期的年月日 yyyyMMdd
* @return
*/
public static Integer getTodayLocalDate(){
LocalDate localDate = LocalDate.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
return Integer.parseInt(localDate.format(dtf));
}
/**
* 获取参数日期的当月一号0点
* @param date
* @return
*/
public static Date getMonthStart(Date date){
LocalDateTime localDateTime = dateToLocalDateTime(date);
localDateTime = localDateTime.with(TemporalAdjusters.firstDayOfMonth());
localDateTime = LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MIN);
return localDateTimeToDate(localDateTime);
}
/**
* 获取参数日期的当月最后一天23点
* @param date
* @return
*/
public static Date getMonthLast(Date date){
LocalDateTime localDateTime = dateToLocalDateTime(date);
localDateTime = localDateTime.with(TemporalAdjusters.lastDayOfMonth());
localDateTime = LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MAX);
return localDateTimeToDate(localDateTime);
}
/**
* 获取参数日期的上月一号0点
* @param date
* @return
*/
public static Date getLastMonthStart(Date date){
LocalDateTime localDateTime = dateToLocalDateTime(date);
localDateTime = localDateTime.plusMonths(-1);
localDateTime = localDateTime.with(TemporalAdjusters.firstDayOfMonth());
localDateTime = LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MIN);
return localDateTimeToDate(localDateTime);
}
/**
* 获取参数日期的上月末尾时间
* @param date
* @return
*/
public static Date getLastMonthEnd(Date date){
LocalDateTime localDateTime = dateToLocalDateTime(date);
localDateTime = localDateTime.plusMonths(-1);
localDateTime = localDateTime.with(TemporalAdjusters.lastDayOfMonth());
localDateTime = LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MAX);
return localDateTimeToDate(localDateTime);
}
/**
* 获取参数日期的上周一0点
* @param date
* @return
*/
public static Date getLastWeekStart(Date date){
LocalDateTime localDateTime = dateToLocalDateTime(date);
localDateTime = localDateTime.plusWeeks(-1);
localDateTime = localDateTime.with(DayOfWeek.MONDAY);
localDateTime = LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MIN);
return localDateTimeToDate(localDateTime);
}
/**
* 获取参数日期的上周日23:59:59点
* @param date
* @return
*/
public static Date getLastWeekEnd(Date date){
LocalDateTime localDateTime = dateToLocalDateTime(date);
localDateTime = localDateTime.plusWeeks(-1);
localDateTime = localDateTime.with(DayOfWeek.SUNDAY);
localDateTime = LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MAX);
return localDateTimeToDate(localDateTime);
}
/**
* 获取当前日期的前一天
* @param date
*
*/
public static Date getYesterday(Date date){
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DATE,-1);
return calendar.getTime();
}
/**
* 获取一天的开始时间
* @param date
* @return
*/
public static Date getStart(Date date){
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY,0);
calendar.set(Calendar.MINUTE,0);
calendar.set(Calendar.SECOND,0);
calendar.set(Calendar.MILLISECOND,0);
return calendar.getTime();
}
/**
* 获取一天的开始时间
* @param date
* @return
*/
public static Date getEnd(Date date){
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY,23);
calendar.set(Calendar.MINUTE,59);
calendar.set(Calendar.SECOND,59);
calendar.set(Calendar.MILLISECOND,999);
return calendar.getTime();
}
/**
* 使用用户格式格式化日期
*
* @param date 日期
* @param pattern 日期格式
* @return
*/
public static String format(Date date, String pattern) {
String returnValue = "";
if (date != null) {
SimpleDateFormat df = new SimpleDateFormat(pattern);
returnValue = df.format(date);
}
return (returnValue);
}
/**
* 使用用户格式格式化日期
*
* @param date 日期
* @param pattern 日期格式
* @return
*/
public static String formatCn(Date date, String pattern) {
String returnValue = "";
if (date != null) {
SimpleDateFormat df = new SimpleDateFormat(pattern, Locale.CHINA);
returnValue = df.format(date);
}
return (returnValue);
}
/**
* 使用用户格式格式化日期
*
* @param date 日期
* @param pattern 日期格式,格式需要与入参格式保持一致
* @return
*/
public static Date parse(String date, String pattern) {
Date returnValue = null;
if (date != null) {
SimpleDateFormat df = new SimpleDateFormat(pattern);
try {
returnValue = df.parse(date);
} catch (ParseException e) {
throw new BusinessException(ResponseEnum.DATE_PARSE_FAILURE);
}
}
return returnValue;
}
/**
* @Method getDateTimeOfTimestamp
* @Description 根据时间戳获取时间
*/
public static LocalDateTime getDateTimeOfTimestamp (long timestamp) {
Instant instant = Instant.ofEpochMilli(timestamp);
ZoneId zone = ZoneId.systemDefault();
return LocalDateTime.ofInstant(instant, zone);
}
/**
* 使用用户格式格式化LocalDateTime
*
* @param date 日期
* @param pattern 日期格式
* @return
*/
public static LocalDateTime formatLocalDT(String date, String pattern) {
DateTimeFormatter timeDtf = DateTimeFormatter.ofPattern(pattern);
return LocalDateTime.parse(date, timeDtf);
}
}