赞
踩
如下未特别说明, 均指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)); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。