概述
如下未特别说明, 均指jdk1.8实现版本.
功能列表:
- 解决多线程下使用SimpleDateFormat(非线程安全类), 导致的如下问题:
java.lang.NumberFormatException: multiple points
- 多线程环境下,将 dateStr 转化为 Date 形式.
- 多线程环境下,将 dateTimeStr 转化为 Date 形式.
- 对象转为JSON字符串, 序列化格式由自己自定义指定(如: 空list,空string,null数字,null布尔值,nullMap).
- 根据步长(step)来向前或向后获取某一天的日期字符串(date形式).
- 根据步长(step)来向前或向后获取某一天的日期字符串(datetime形式).
- 根据给定参照日期(baseDate), 和步长(step)来向前或向后获取某一天的日期字符串(datetime形式).
- 字符串转Long类型.
- 根据指定的如下格式的字符串, 格式化为Date类型.
private static final String DATE_FORMAT = “yyyy-MM-dd
”;
private static final String DATETIME_FORMAT = “yyyy-MM-dd HH:mm:ss
”;- 判断某一年份是否闰年.
- 根据步长返回N年前或N年后的年份数字.
- 根据步长返回N年前或N年后的年份数字.
- JDK8之前版本: 获取当前时间的整点时刻.
- JDK8中 : 获取当前时间的整点时刻.
- 通过如下枚举类型
* ①: LOCAL_DATE获取当日日期
: 格式为 “yyyy-MM-dd”
* ②: LOCAL_DATETIME获取当日整点时间:
格式为 “yyyy-MM-dd HH:00:00”.- 获取两个日期间隔的所有日期.
MyDateUtils.java代码清单:
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Stream;
/**
* User: DavidTest
* Date:
* Time:
* Desc: Java日期处理工具类
*/
@Slf4j
public class MyDateUtils {
private static DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private static DateTimeFormatter DTF_OF_TIME = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final String DATE_FORMAT = "yyyy-MM-dd";
private static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
//对于每一个( Date | Datetime ) 类型的线程
private static final ThreadLocal<SimpleDateFormat> THREAD_LOCAL_SDF = new ThreadLocal<>();
//日期类型枚举:①:LOCAL_DATE,格式 "yyyy-MM-dd" ;②:LOCAL_DATETIME,格式: "yyyy-MM-dd HH:mm:ss".
public enum MY_DATE_TYPE {
LOCAL_DATE, LOCAL_DATETIME
}
/**
* 多线程环境下,将 dateStr 转化为 Date 形式.
* 避免多线程下使用不安全的 SimpleDateFormat,
* 抛出: java.lang.NumberFormatException: multiple points 异常.
*
* @param dateStr
* @return
*/
public static Date parseBySDF(String dateStr) throws ParseException {
SimpleDateFormat sdf = THREAD_LOCAL_SDF.get();
if (sdf == null) {
sdf = new SimpleDateFormat(DATE_FORMAT);
}
log.info(">>>> 当前线程为: " + Thread.currentThread().getName());
Date date = sdf.parse(dateStr);
return date;
}
/**
* 多线程环境下,将 dateTimeStr 转化为 Date 形式.
* 避免多线程下使用不安全的 SimpleDateFormat,
* 抛出: java.lang.NumberFormatException: multiple points 异常.
*
* @param dateTimeStr
* @return
*/
public static Date parseBySDFLong(String dateTimeStr) throws ParseException {
SimpleDateFormat sdfLong = THREAD_LOCAL_SDF.get();
if (sdfLong == null) {
sdfLong = new SimpleDateFormat(DATETIME_FORMAT);
}
log.info(">>>> 当前线程为: " + Thread.currentThread().getName());
Date date = sdfLong.parse(dateTimeStr);
return date;
}
public static String toJSONStr(Object obj) {
String msg = JSON.toJSONString(obj,
SerializerFeature.WriteNullListAsEmpty,
SerializerFeature.WriteNullStringAsEmpty,
SerializerFeature.WriteNullNumberAsZero,
SerializerFeature.WriteNullBooleanAsFalse,
SerializerFeature.WriteMapNullValue);
return msg;
}
public static String getDate(Long daysToAdd) {
LocalDate daysBefore = LocalDate.now().plusDays(daysToAdd);
return daysBefore.format(DTF);
}
public static String getDateTime(Long daysToAdd) {
LocalDateTime daysBefore = LocalDateTime.now().plusDays(daysToAdd);
return daysBefore.format(DTF_OF_TIME);
}
public static String getDate(String baseDate, Long daysToAdd) {
LocalDate daysBefore = LocalDate.parse(baseDate).plusDays(daysToAdd);
return daysBefore.format(DTF);
}
public static Long getLong(String x) {
Long r = null;
try {
r = new Long(x.trim());
} catch (NumberFormatException e) {
log.error("", e);
}
return r;
}
public static Date getDate(String dateStr) {
try {
return new SimpleDateFormat(DATE_FORMAT).parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
public static String getDateStr(Date date) {
return new SimpleDateFormat(DATETIME_FORMAT).format(date);
}
/**
* 判断某一年份是否闰年
*
* @param year
* @return
*/
public static Boolean isLeapYear(Integer year) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
return true;
} else {
return false;
}
}
/**
* 根据步长返回N年前或N年后的年份数字
*
* @param step
* @return
*/
public static Integer getSpecificYearByStep(Integer step) {
LocalDate localDate = LocalDate.now();
return localDate.plusYears(step).getYear();
}
/**
* 根据步长返回N年前或N年后的年份数字
*
* @param baseDateTime 日期时间格式, 如"2020-04-20 00:00:00"
* @param step 向前后向后的时间间隔,由正负值确定是向前或向后变更小时数(如 step=1, 表示"2020-04-20 01:00:00
* @return
*/
public static String getSpecificDateHourByStep(String baseDateTime, Integer step) {
if (baseDateTime != null && 19 == baseDateTime.length()) {
LocalDateTime localDate = LocalDateTime.parse(baseDateTime, DTF_OF_TIME);
return localDate.plusHours(step).format(DTF_OF_TIME);
} else {
throw new RuntimeException("Parameter baseDateTime's formatter invalid, please check!");
}
}
/**
* 获取2个日期之间相差的天数.
* 如果:
* 1: localDate1 > localDate2, 值为正.
* 2: localDate1 < localDate2, 值为负.
*
* @param localDate1 起始日
* @param localDate2 终止日
* @return
*/
public static Integer getPeriodDays(LocalDate localDate1, LocalDate localDate2) {
return (int) (localDate1.toEpochDay() - localDate2.toEpochDay());
}
/**
* JDK8之前: 获取当前时间的整点时刻
*
* @return
*/
public static Date getCurrentHourTimeBeforeJDK8() {
Calendar ca = Calendar.getInstance();
ca.set(Calendar.MINUTE, 0);
ca.set(Calendar.SECOND, 0);
ca.set(Calendar.MILLISECOND, 0);
return ca.getTime();
}
/**
* JDK8中 : 获取当前时间的整点时刻
*
* 如下两种实现方式都可以.
* @return
*/
public static Date getCurrentHourTimeOfJDK8() {
LocalDateTime time = LocalDateTime.now();
return Date.from(time.minusMinutes(time.getMinute()).minusSeconds(time.getSecond()).atZone(ZoneId.systemDefault()).toInstant());
//return Date.from(time.withMinute(0).withSecond(0).atZone(ZoneId.systemDefault()).toInstant());
}
/**
* 通过如下枚举类型
* ①: LOCAL_DATE 获取当日日期 : 格式为 "yyyy-MM-dd"
* ②: LOCAL_DATETIME 获取当日整点时间: 格式为 "yyyy-MM-dd HH:00:00"
*
* @return
*/
public static String getCurrentDateOrTimeByType(MY_DATE_TYPE date_type) {
LocalDateTime time = LocalDateTime.now();
switch (date_type) {
case LOCAL_DATE:
return (time.withMinute(0).withSecond(0).withNano(0)).format(DTF);
case LOCAL_DATETIME:
return (time.withMinute(0).withSecond(0).withNano(0)).format(DTF_OF_TIME);
default:
return null;
}
}
/**
* 获取两个日期间隔的所有日期
*
* @param start 格式必须为'2019-01-01'
* @param end 格式必须为'2019-02-01'
* @return
*/
public static List<String> getBetweenDate(String start, String end) {
List<String> list = new ArrayList<>();
LocalDate startDate = LocalDate.parse(start);
LocalDate endDate = LocalDate.parse(end);
long distance = ChronoUnit.DAYS.between(startDate, endDate);
System.out.println("distance = " + distance);
Stream.iterate(startDate, localDate -> localDate.plusDays(1))
.limit(distance + 1)
.forEach(f -> {
list.add(f.toString());
});
return list;
}
public static void main(String[] args) {
// System.out.println(getSpecificYearByStep(-1));
// System.out.println(MyDateUtils.getSpecificYearByStep(0));
// System.out.println(MyDateUtils.getDate("2020-02-29", -366L));
// System.out.println(MyDateUtils.getDate("2019-01-01", 0L));
// System.out.println(MyDateUtils.getDate("2020-02-28", -365L));
// System.out.println(MyDateUtils.getDateTime(0L));
// System.out.println(getCurrentDateOrTimeByType(MY_DATE_TYPE.LOCAL_DATE));
// System.out.println(getCurrentDateOrTimeByType(MY_DATE_TYPE.LOCAL_DATETIME));
// System.out.println((int)((double)297/54*2));
System.out.println(getBetweenDate("2019-05-01", "2020-05-20").size());
System.out.println(getSpecificDateHourByStep("2020-05-21 00:00:00", -1));
}
}
最后
以上就是甜美冰淇淋为你收集整理的JAVA日期处理工具类-DateUtil的全部内容,希望文章能够帮你解决JAVA日期处理工具类-DateUtil所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复