org.sagacity.sqltoy.utils.DateUtil Maven / Gradle / Ivy
package org.sagacity.sqltoy.utils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @project sagacity-sqltoy
* @description 日期处理支持类,提供日常工作中的所有日期的操作处理
* @author zhongxuchen
* @version v1.0,Date:2008-12-14
* @modify data:2012-8-27 {对日期的格式化增加了locale功能}
* @modify data:2015-8-8 对parseString功能进行了优化,对英文和中文日期进行解析,同时优化了格式判断的逻辑
* @modify data:2019-10-11 支持LocalDate、LocalTime、LocalDateTime等新的日期类型
* @modify data:2023-12-05 强化英文日期的解析以及localTime、localDateTime格式化,提升格式化精度
*/
@SuppressWarnings({ "unused" })
public class DateUtil {
/**
* 定义日志
*/
private final static Logger logger = LoggerFactory.getLogger(DateUtil.class);
private static final String[] CHINA_DATE_KEYS = { "○", "О", "0", "Ο", "O", "零", "一", "二", "三", "四", "五", "六", "七",
"八", "九", "十", "年", "月", "日", "时", "分", "秒" };
private static final String[] CHINA_DATE_KEY_MAP = { "0", "0", "0", "0", "0", "0", "1", "2", "3", "4", "5", "6",
"7", "8", "9", "10", "-", "-", " ", ":", ":", " " };
/**
* 英文月份名称
*/
private static final String[] MONTH_ENGLISH_NAME = { "January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December" };
private static final String[] MONTH_ENGLISH_NAKE = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
"Oct", "Nov", "Dec" };
private final static Pattern MONTH_PATTERN = Pattern
.compile("(?i)(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\s");
/**
* 中文星期的名称
*/
private static final String[] WEEK_CHINA_NAME = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };
private static final String[] WEEK_ENGLISH_NAME = { "Monday", "Tuesday", "Wednesday", "Thurday", "Friday",
"Saturday", "Sunday" };
private static final String[] WEEK_ENGLISH_NAKE = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
private final static Pattern WEEK_PATTERN = Pattern.compile("(?i)(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\\s");
private final static Pattern DAY_PATTERN = Pattern.compile("(?i)\\s\\d{1,2}(st|th|rd)?\\s");
// 超过十的中文
private final static Pattern MORE_TEN_PATTERN = Pattern.compile("(一|二|三|四|五)?\\十(一|二|三|四|五|六|七|八|九)");
/**
* 英文日期的几种格式
*/
private static final Collection DEFAULT_DAY_PATTERNS = Arrays
.asList(new String[] { "MMM dd yyyy", "MMM dd z yyyy" });
private static final Collection DEFAULT_WEEK_DAY_PATTERNS = Arrays
.asList(new String[] { "EEE MMM dd yyyy", "EEE MMM dd z yyyy" });
private static final Collection DEFAULT_TIME_PATTERNS = Arrays.asList(new String[] {
"MMM dd HH:mm:ss z yyyy", "MMM dd HH:mm:ss yyyy", "MMM dd yyyy HH:mm:ss", "MMM dd yyyy HH:mm:ss z" });
private static final Collection DEFAULT_WEEK_TIME_PATTERNS = Arrays
.asList(new String[] { "EEE MMM dd HH:mm:ss z yyyy", "EEE MMM dd HH:mm:ss yyyy",
"EEE MMM dd yyyy HH:mm:ss z", "EEEE dd-MMM-yyyy HH:mm:ss", "EEEE dd-MMM-yyyy HH:mm:ss z",
"EEEE dd-MMM-yy HH:mm:ss z", "EEEE dd-MMM-yy HH:mm:ss" });
private final static Pattern DAYTH_PATTERN = Pattern.compile("(?i)\\s\\d{1,2}(st|th|nd|rd)\\s");
private final static Pattern TIME_PATTERN = Pattern.compile("\\d{1,2}\\:\\d{1,2}");
private final static Pattern TIME_DOT_PATTERN = Pattern.compile("\\d\\.\\d");
/**
* 定义日期的格式
*/
public final static class FORMAT {
public final static String YEAR_MONTH = "yyyy-MM";
/**
* 6位日期格式
*/
public final static String DATE_6CHAR = "yyMMdd";
/**
* 8位日期格式
*/
public final static String DATE_8CHAR = "yyyyMMdd";
/**
* 点号日期格式
*/
public final static String DATE_DOT = "yyyy.MM.dd";
/**
* 反斜杠日期格式
*/
public final static String DATE_SLASH = "yyyy/MM/dd";
/**
* 横杠日期格式
*/
public final static String DATE_HORIZONTAL = "yyyy-MM-dd";
/**
* 日期时间(日期点号分割)
*/
public final static String DATETIME_DOT = "yyyy.MM.dd HH:mm:ss";
/**
* 日期时间(日期反斜杠)
*/
public final static String DATETIME_SLASH = "yyyy/MM/dd HH:mm:ss";
/**
* 日期时间(日期横杠)
*/
public final static String DATETIME_HORIZONTAL = "yyyy-MM-dd HH:mm:ss";
}
private DateUtil() {
}
/**
* @todo 将日期字符串或时间转换成时间类型 日期字符串中的日期分隔符可是:"/",".","-", 返回时间具体到秒 只提供常用的日期格式处理
* @param data
* @param format
* @return
*/
public static Date parse(Object data, String format) {
return parse(data, format, null);
}
public static Date parse(Object data, String format, Locale locale) {
if (null == data) {
logger.error("The date string is null!");
return null;
}
if (data instanceof String) {
return parseString((String) data, format, locale);
}
if (format == null) {
return convertDateObject(data, null, locale);
}
// 非字符串
String result = formatDate(data, format, locale);
return parseString(result, format, locale);
}
public static Date parseString(String dateStr) {
return parseString(dateStr, null, null);
}
/**
* @todo 将日期字符串或时间转换成时间类型 日期字符串中的日期分隔符可是:"/",".","-", 返回时间具体到秒 只提供常用的日期格式处理
* @param dateVar
* @param dateFormat
* @param locale
* @return
*/
public static Date parseString(String dateVar, String dateFormat, Locale locale) {
if (dateVar == null) {
return null;
}
String dateStr = dateVar.trim();
if ("".equals(dateStr) || dateStr.toLowerCase().equals("null")) {
return null;
}
String realDF = null;
boolean isLocalDateTime = false;
boolean isLocalTime = false;
if (StringUtil.isNotBlank(dateFormat)) {
realDF = dateFormat;
} // 英文日期格式(2个以上字母)
else if (StringUtil.matches(dateStr, "[a-zA-Z]{2}")) {
return parseEnglishDate(dateStr, locale);
} else {
// 中文日期格式
if (StringUtil.matches(dateStr, "[年月日时分秒]")) {
dateStr = parseChinaDate(dateStr);
}
// 含中文,但非标准的时间性中文
else if (StringUtil.hasChinese(dateStr)) {
return null;
}
int size;
boolean hasBlank = (dateStr.indexOf(" ") != -1 || dateStr.toUpperCase().indexOf("T") >= 6);
int splitCount;
int startIndex;
// 日期和时间的组合
if (hasBlank) {
// 统一格式(去除掉日期中的符号变成全数字),update 2019-08-12 支持jdk8日期
dateStr = dateStr.replaceFirst("\\s+", " ").replaceFirst("(?i)T", " ").replace("-", "").replace(".", "")
.replace(":", "").replace("/", "");
int preSize = dateStr.indexOf(" ");
size = dateStr.length();
if (size > 21) {
dateStr = addZero(dateStr, size, 24);
realDF = "yyyyMMdd HHmmssSSSSSSSSS";
isLocalDateTime = true;
} else if (size > 18) {
dateStr = addZero(dateStr, size, 21);
realDF = "yyyyMMdd HHmmssSSSSSS";
isLocalDateTime = true;
} else if (size > 16) {
dateStr = addZero(dateStr, size, 18);
realDF = "yyyyMMdd HHmmssSSS";
isLocalDateTime = true;
} else if (size == 16) {
if (preSize == 8) {
realDF = "yyyyMMdd HHmmssS";
isLocalDateTime = true;
} else {
realDF = "yyMMdd HHmmssSSS";
isLocalDateTime = true;
}
} else if (size == 13) {
if (preSize == 8) {
realDF = "yyyyMMdd HHmm";
} else {
realDF = "yyMMdd HHmmss";
}
} else if (size == 11) {
if (preSize == 8) {
realDF = "yyyyMMdd HH";
} else {
realDF = "yyMMdd HHmm";
}
} else if (size == 9) {
realDF = "yyMMdd HH";
} else {
realDF = "yyyyMMdd HHmmss";
}
} else {
// 去除数字中带的,例如:201,512
dateStr = dateStr.replace(",", "");
size = dateStr.length();
if (dateStr.indexOf(":") != -1) {
if (dateStr.indexOf(".") != -1) {
if (size > 15) {
dateStr = addZero(dateStr, size, 18);
realDF = "HH:mm:ss.SSSSSSSSS";
isLocalTime = true;
} else if (size > 12) {
dateStr = addZero(dateStr, size, 15);
realDF = "HH:mm:ss.SSSSSS";
isLocalTime = true;
} else if (size > 10) {
dateStr = addZero(dateStr, size, 12);
realDF = "HH:mm:ss.SSS";
isLocalTime = true;
} else {
realDF = "HH:mm:ss.S";
isLocalTime = true;
}
} else {
if (size == 5) {
realDF = "HH:mm";
} else {
realDF = "HH:mm:ss";
}
}
} else {
dateStr = dateStr.replace("-", "/").replace(".", "/");
splitCount = StringUtil.matchCnt(dateStr, "\\/");
if (splitCount == 2) {
startIndex = dateStr.indexOf("/");
if (startIndex == 2) {
realDF = "yy/MM/dd";
} else {
realDF = "yyyy/MM/dd";
}
} else if (splitCount == 1) {
if (size > 5) {
realDF = "yyyy/MM";
} else {
realDF = "yy/MM";
}
} else {
if (size > 22) {
dateStr = dateStr.substring(0, 8).concat(" ").concat(dateStr.substring(8, 14)).concat(".")
.concat(addZero(dateStr.substring(14), 9));
realDF = "yyyyMMdd HHmmss.SSSSSSSSS";
isLocalDateTime = true;
} else if (size > 19) {
dateStr = dateStr.substring(0, 8).concat(" ").concat(dateStr.substring(8, 14)).concat(".")
.concat(addZero(dateStr.substring(14), 6));
realDF = "yyyyMMdd HHmmss.SSSSSS";
isLocalDateTime = true;
} else if (size > 17) {
dateStr = dateStr.substring(0, 8).concat(" ").concat(dateStr.substring(8, 14)).concat(".")
.concat(addZero(dateStr.substring(14), 3));
realDF = "yyyyMMdd HHmmss.SSS";
isLocalDateTime = true;
} else if (size == 17) {
dateStr = dateStr.substring(0, 8).concat(" ").concat(dateStr.substring(8, 14)).concat(".")
.concat(dateStr.substring(14));
realDF = "yyyyMMdd HHmmss.S";
isLocalDateTime = true;
} else if (size == 15) {
realDF = "yyyyMMdd HHmmss";
} else if (size == 14) {
realDF = "yyyyMMddHHmmss";
} // 无空白纯数字13位是System.currentTimeMillis()对应的值
else if (size == 13) {
return new java.util.Date(Long.valueOf(dateStr));
} else if (size == 12) {
realDF = "yyMMddHHmmss";
} else if (size == 10) {
realDF = "yyyyMMddHH";
} else if (size == 6) {
realDF = "yyyyMM";
} else if (size == 4) {
realDF = "yyyy";
} else {
realDF = "yyyyMMdd";
}
}
}
}
if (realDF == null) {
realDF = hasBlank ? "yyyy-MM-dd HH:mm:ss" : "yyyy-MM-dd";
}
}
// 针对高精度进行特殊处理
if (isLocalTime) {
LocalTime time = LocalTime.parse(dateStr, DateTimeFormatter.ofPattern(realDF));
return asDate(time);
} else if (isLocalDateTime) {
LocalDateTime localDateTime = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(realDF));
return asDate(localDateTime);
}
Date result = null;
// 通过异常模式进行一次容错处理
try {
DateFormat df = (locale == null) ? new SimpleDateFormat(realDF) : new SimpleDateFormat(realDF, locale);
result = df.parse(dateStr);
} catch (ParseException e) {
}
// 为null,通过字符自动解析进行一次补偿处理
if (result == null) {
result = parseString(dateVar, null, locale);
result = parseString(formatDate(result, realDF));
}
return result;
}
public static LocalDateTime parseLocalDateTime(String dateVar) {
return parseLocalDateTime(dateVar, null);
}
public static LocalDateTime parseLocalDateTime(String dateVar, String dateFormat) {
if (dateVar == null) {
return null;
}
String dateStr = dateVar.trim();
if ("".equals(dateStr) || dateStr.toLowerCase().equals("null")) {
return null;
}
String realDF = null;
boolean isTime = false;
boolean isDate = false;
if (StringUtil.isNotBlank(dateFormat)) {
realDF = dateFormat;
} // 英文日期格式(2个以上字母)
else if (StringUtil.matches(dateStr, "[a-zA-Z]{2}")) {
return asLocalDateTime(parseEnglishDate(dateStr, null));
} else {
// 中文日期格式
if (StringUtil.matches(dateStr, "[年月日时分秒]")) {
dateStr = parseChinaDate(dateStr);
} // 含中文,但非标准的时间性中文
else if (StringUtil.hasChinese(dateStr)) {
return null;
}
int size;
boolean hasBlank = (dateStr.indexOf(" ") != -1 || dateStr.toUpperCase().indexOf("T") >= 6);
int splitCount;
int startIndex;
// 日期和时间的组合
if (hasBlank) {
// 统一格式(去除掉日期中的符号变成全数字),update 2019-08-12 支持jdk8日期
dateStr = dateStr.replaceFirst("\\s+", " ").replaceFirst("(?i)T", " ").replace("-", "").replace(".", "")
.replace(":", "").replace("/", "");
int preSize = dateStr.indexOf(" ");
size = dateStr.length();
if (size > 21) {
dateStr = addZero(dateStr, size, 24);
realDF = "yyyyMMdd HHmmssSSSSSSSSS";
} else if (size > 18) {
dateStr = addZero(dateStr, size, 21);
realDF = "yyyyMMdd HHmmssSSSSSS";
} else if (size > 16) {
dateStr = addZero(dateStr, size, 18);
realDF = "yyyyMMdd HHmmssSSS";
} else if (size == 16) {
if (preSize == 8) {
realDF = "yyyyMMdd HHmmssS";
} else {
realDF = "yyMMdd HHmmssSSS";
}
} else if (size == 13) {
if (preSize == 8) {
realDF = "yyyyMMdd HHmm";
} else {
realDF = "yyMMdd HHmmss";
}
} else if (size == 11) {
if (preSize == 8) {
realDF = "yyyyMMdd HH";
} else {
realDF = "yyMMdd HHmm";
}
} else if (size == 9) {
realDF = "yyMMdd HH";
} else {
realDF = "yyyyMMdd HHmmss";
}
} else {
// 去除数字中带的,例如:201,512
dateStr = dateStr.replace(",", "");
size = dateStr.length();
if (dateStr.indexOf(":") != -1) {
if (dateStr.indexOf(".") != -1) {
if (size > 15) {
dateStr = addZero(dateStr, size, 18);
realDF = "HH:mm:ss.SSSSSSSSS";
} else if (size > 12) {
dateStr = addZero(dateStr, size, 15);
realDF = "HH:mm:ss.SSSSSS";
} else if (size > 10) {
dateStr = addZero(dateStr, size, 12);
realDF = "HH:mm:ss.SSS";
} else {
realDF = "HH:mm:ss.S";
}
} else {
if (size == 5) {
realDF = "HH:mm";
} else {
realDF = "HH:mm:ss";
}
}
isTime = true;
} else {
dateStr = dateStr.replace("-", "/").replace(".", "/");
splitCount = StringUtil.matchCnt(dateStr, "\\/");
if (splitCount == 2) {
startIndex = dateStr.indexOf("/");
if (startIndex == 2) {
realDF = "yy/MM/dd";
} else {
realDF = "yyyy/MM/dd";
}
isDate = true;
} else if (splitCount == 1) {
if (size > 5) {
realDF = "yyyy/MM";
} else {
realDF = "yy/MM";
}
isDate = true;
} else {
if (size > 22) {
realDF = "yyyyMMdd HHmmss.SSSSSSSSS";
dateStr = dateStr.substring(0, 8).concat(" ").concat(dateStr.substring(8, 14)).concat(".")
.concat(addZero(dateStr.substring(14), 9));
} else if (size > 19) {
dateStr = dateStr.substring(0, 8).concat(" ").concat(dateStr.substring(8, 14)).concat(".")
.concat(addZero(dateStr.substring(14), 6));
realDF = "yyyyMMdd HHmmss.SSSSSS";
} else if (size > 17) {
dateStr = dateStr.substring(0, 8).concat(" ").concat(dateStr.substring(8, 14)).concat(".")
.concat(addZero(dateStr.substring(14), 3));
realDF = "yyyyMMdd HHmmss.SSS";
} else if (size == 17) {
dateStr = dateStr.substring(0, 8).concat(" ").concat(dateStr.substring(8, 14)).concat(".")
.concat(dateStr.substring(14));
realDF = "yyyyMMdd HHmmss.S";
} else if (size == 15) {
realDF = "yyyyMMdd HHmmss";
} else if (size == 14) {
realDF = "yyyyMMddHHmmss";
} // 无空白纯数字13位是System.currentTimeMillis()对应的值
else if (size == 13) {
return asLocalDateTime(new java.util.Date(Long.valueOf(dateStr)));
} else if (size == 12) {
realDF = "yyMMddHHmmss";
} else if (size == 10) {
realDF = "yyyyMMddHH";
} else if (size == 6) {
realDF = "yyyyMM";
isDate = true;
} else if (size == 4) {
realDF = "yyyy";
isDate = true;
} else {
realDF = "yyyyMMdd";
isDate = true;
}
}
}
}
if (realDF == null) {
if (hasBlank) {
realDF = "yyyy-MM-dd HH:mm:ss";
} else {
realDF = "yyyy-MM-dd";
isDate = true;
}
}
}
LocalDateTime result = null;
try {
if (isTime) {
LocalTime timeResult = LocalTime.parse(dateStr, DateTimeFormatter.ofPattern(realDF));
return LocalDateTime.of(LocalDate.now(), timeResult);
} else if (isDate) {
Date dateResult = new SimpleDateFormat(realDF).parse(dateStr);
return asLocalDateTime(dateResult);
}
result = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(realDF));
} catch (Exception e) {
}
// 为null,通过字符自动解析进行一次补偿处理
if (result == null) {
result = parseLocalDateTime(dateStr, null);
result = parseLocalDateTime(formatDate(result, realDF));
}
return result;
}
public static Date convertDateObject(Object dt) {
return convertDateObject(dt, null, null);
}
public static LocalDateTime convertLocalDateTime(Object dt) {
if (dt == null) {
logger.warn("日期不能为空,请正确输入!");
return null;
}
LocalDateTime result = null;
if (dt instanceof String) {
return parseLocalDateTime(dt.toString().trim());
} // 为什么要new 一个,目的是避免前面日期对象变化导致后续转化后的也变化,所以这里是新建
else if (dt instanceof java.util.Date) {
return asLocalDateTime((Date) dt);
} else if (dt instanceof java.time.LocalDate) {
LocalDate localDate = (LocalDate) dt;
result = LocalDateTime.of(localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth(), 0, 0,
0);
return result;
} else if (dt instanceof java.time.LocalDateTime) {
return (LocalDateTime) dt;
} else if (dt instanceof java.lang.Number) {
return parseLocalDateTime(dt.toString().trim());
} else if (dt instanceof java.time.LocalTime) {
result = LocalDateTime.of(LocalDate.now(), (LocalTime) dt);
}
return result;
}
/**
* @todo 日期对象类型转换
* @param dt
* @param format
* @param locale
* @return
*/
public static Date convertDateObject(Object dt, String format, Locale locale) {
if (dt == null) {
logger.warn("日期不能为空,请正确输入!");
return null;
}
Date result = null;
if (dt instanceof String) {
String dtStr = dt.toString().trim();
if (dtStr.length() == 13 && NumberUtil.isInteger(dtStr)) {
result = new java.util.Date(Long.valueOf(dtStr));
} else {
result = parseString(dtStr, format, locale);
}
} // 为什么要new 一个,目的是避免前面日期对象变化导致后续转化后的也变化,所以这里是新建
else if (dt instanceof java.util.Date) {
result = new java.util.Date(((java.util.Date) dt).getTime());
} else if (dt instanceof java.time.LocalDate) {
result = asDate((LocalDate) dt);
} else if (dt instanceof java.time.LocalDateTime) {
result = asDate((LocalDateTime) dt);
} else if (dt instanceof java.lang.Number) {
String dtStr = dt.toString().trim();
// 13位表示毫秒数
if (dtStr.length() != 13) {
result = parseString(dtStr, format, locale);
} else {
result = new java.util.Date(((Number) dt).longValue());
}
} else if (dt instanceof java.time.LocalTime) {
result = asDate((LocalTime) dt);
} else {
result = parseString(dt.toString().trim(), format, locale);
}
return result;
}
/**
* @todo 格式化日期
* @param dt
* @param format
* @return
*/
public static String formatDate(Object dt, String format) {
return formatDate(dt, format, null);
}
public static String formatDate(Object dt, String format, Locale locale) {
if (dt == null) {
return null;
}
if (format == null) {
throw new IllegalArgumentException("格式化日期指定的format 为null,请正确输入参数!");
}
String fmtUpper = format.toUpperCase();
if ("YY".equals(fmtUpper)) {
String year = Integer.toString(getYear(dt));
return year.substring(year.length() - 2);
}
if ("YYYY".equals(fmtUpper)) {
return Integer.toString(getYear(dt));
}
if ("MM".equals(fmtUpper)) {
int month = getMonth(dt);
return (month < 10 ? "0" : "").concat(Integer.toString(month));
}
if ("DD".equals(fmtUpper)) {
int day = getDay(dt);
return (day < 10 ? "0" : "").concat(Integer.toString(day));
}
if (dt instanceof LocalDateTime) {
return DateTimeFormatter.ofPattern(format).format((LocalDateTime) dt);
} else if (dt instanceof LocalTime) {
return DateTimeFormatter.ofPattern(format).format((LocalTime) dt);
} else if (dt instanceof LocalDate) {
return DateTimeFormatter.ofPattern(format).format((LocalDate) dt);
}
// 高精度时间用localDateTime、localTime
if (locale == null && (fmtUpper.endsWith("SSS") || fmtUpper.endsWith(".S"))) {
LocalDateTime result = convertLocalDateTime(dt);
if (result == null) {
return null;
}
// yyyy-MM-dd HH:mm:ss.SSS
if (fmtUpper.startsWith("YY")) {
return DateTimeFormatter.ofPattern(format).format(result);
} else if (fmtUpper.startsWith("HH")) {
return DateTimeFormatter.ofPattern(format).format(result.toLocalTime());
}
}
// 低精度用SimpleDateFormat,兼容性强
DateFormat df = (locale == null) ? new SimpleDateFormat(format) : new SimpleDateFormat(format, locale);
Date tmp = convertDateObject(dt, null, locale);
return (null == tmp) ? null : df.format(tmp);
}
/**
* @TODO 通过一个格式解析,再转化为另外一个格式
* @param dt
* @param format
* @param targetFormat
* @param locale
* @return
*/
@Deprecated
public static String formatDate(Object dt, String format, String targetFormat, Locale locale) {
Date result = parse(dt, format, locale);
return formatDate(result, targetFormat);
}
/**
* @todo 获取当前以sql.date的日期
* @param date
* @return
*/
public static java.sql.Date getSqlDate(Object date) {
return new java.sql.Date(convertDateObject(date == null ? new Date() : date).getTime());
}
public static java.sql.Timestamp getTimestamp(Object date) {
return new Timestamp(date == null ? System.currentTimeMillis() : convertDateObject(date).getTime());
}
/**
* @todo 获取当前操作系统的时间
* @return 当前操作系统的时间
*/
public static Date getNowTime() {
return Calendar.getInstance().getTime();
}
public static LocalDate getDate() {
return LocalDate.now();
}
public static LocalDate getDate(Object date) {
if (date == null) {
return null;
}
if (date instanceof LocalDate) {
return (LocalDate) date;
} else if (date instanceof LocalDateTime) {
return ((LocalDateTime) date).toLocalDate();
}
return asLocalDate(convertDateObject(date));
}
public static LocalDateTime getDateTime() {
return LocalDateTime.now();
}
public static LocalDateTime getDateTime(Object date) {
if (date == null) {
return null;
}
if (date instanceof LocalDateTime) {
return (LocalDateTime) date;
}
return asLocalDateTime(convertDateObject(date));
}
public static LocalTime getTime() {
return LocalTime.now();
}
// Add millisecond
public static Date addMilliSecond(Object dt, long millisecond) {
Date result = convertDateObject(dt);
if (millisecond != 0) {
result.setTime(result.getTime() + millisecond);
}
return result;
}
public static Date addSecond(Object dt, double second) {
Double millisecond = Double.valueOf(1000.0 * second);
return addMilliSecond(dt, millisecond.longValue());
}
public static Date addDay(Object dt, long day) {
return addMilliSecond(dt, 1000L * 60L * 60L * 24L * day);
}
public static Date addDay(Object dt, double day) {
Double millisecond = Double.valueOf(1000.0 * 60.0 * 60.0 * 24.0 * day);
return addMilliSecond(dt, millisecond.longValue());
}
// add month
public static Date addMonth(Object dt, int month) {
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(convertDateObject(dt));
gc.add(Calendar.MONTH, month);
return gc.getTime();
}
public static Date addYear(Object dt, int year) {
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(convertDateObject(dt));
gc.add(Calendar.YEAR, year);
return gc.getTime();
}
public static int getYear(Object dateValue) {
if (dateValue == null) {
return LocalDate.now().getYear();
}
return convertLocalDateTime(dateValue).getYear();
}
public static int getMonth(Object dateValue) {
if (dateValue == null) {
return LocalDate.now().getMonthValue();
}
return convertLocalDateTime(dateValue).getMonthValue();
}
/**
* @see getDayOfMonth(Object dateValue)
* @param dateValue
* @return
*/
@Deprecated
public static int getDay(Object dateValue) {
return getDayOfMonth(dateValue);
}
/**
* @TODO 获取当月中的第几天(1~31)
* @param dateValue
* @return
*/
public static int getDayOfMonth(Object dateValue) {
if (dateValue == null) {
return LocalDate.now().getDayOfMonth();
}
return convertLocalDateTime(dateValue).getDayOfMonth();
}
/**
* @todo 获取指定日期是星期几(from 1 (Monday) to 7 (Sunday))
* @param dateValue
* @return
*/
public static int getDayOfWeek(Object dateValue) {
if (dateValue == null) {
return LocalDate.now().getDayOfWeek().getValue();
}
return convertLocalDateTime(dateValue).getDayOfWeek().getValue();
}
/**
* @todo 获取两时间间隔的月数
* @param floorDate
* @param goalDate
* @return
*/
public static int getIntervalMonths(Object floorDate, Object goalDate) {
LocalDateTime date1 = convertLocalDateTime(goalDate);
LocalDateTime date2 = convertLocalDateTime(floorDate);
return date1.getYear() * 12 + date1.getMonthValue() - date2.getYear() * 12 - date2.getMonthValue();
}
/**
* @todo 获取两时间间隔的整数年数
* @param floorDate
* @param goalDate
* @return
*/
public static int getIntervalYears(Object floorDate, Object goalDate) {
return convertLocalDateTime(goalDate).getYear() - convertLocalDateTime(floorDate).getYear();
}
/**
* @todo 获取两个时间间隔的天数
* @param floorDate
* @param goalDate
* @return
*/
public static int getIntervalDays(Object floorDate, Object goalDate) {
BigDecimal result = new BigDecimal(
Double.valueOf(getIntervalMillSeconds(formatDate(floorDate, FORMAT.DATE_HORIZONTAL),
formatDate(goalDate, FORMAT.DATE_HORIZONTAL))) / (3600 * 1000 * 24));
return result.setScale(1, RoundingMode.HALF_UP).intValue();
}
/**
* @todo 获取两个时间间隔的小时
* @param floorDate
* @param goalDate
* @return
*/
public static double getIntervalHours(Object floorDate, Object goalDate) {
BigDecimal result = new BigDecimal(Double.valueOf(getIntervalMillSeconds(floorDate, goalDate)) / (3600 * 1000));
return result.setScale(1, RoundingMode.HALF_UP).doubleValue();
}
/**
* @todo 获取两时间的间隔分钟
* @param floorDate
* @param goalDate
* @return
*/
public static double getIntervalMinutes(Object floorDate, Object goalDate) {
BigDecimal result = new BigDecimal(Double.valueOf(getIntervalMillSeconds(floorDate, goalDate)) / (60 * 1000));
return result.setScale(1, RoundingMode.HALF_UP).doubleValue();
}
/**
* @todo 获取两时间间隔的秒数
* @param floorDate
* @param goalDate
* @return
*/
public static double getIntervalSeconds(Object floorDate, Object goalDate) {
return Double.valueOf(getIntervalMillSeconds(floorDate, goalDate)) / (1000);
}
/**
* @todo 获取两时间间隔的毫秒数
* @param floorDate
* @param goalDate
* @return
*/
public static long getIntervalMillSeconds(Object floorDate, Object goalDate) {
return convertDateObject(goalDate).getTime() - convertDateObject(floorDate).getTime();
}
/**
* @todo 将日期转化为中文格式
* @param dateValue
* @return
*/
public static String format2China(Object dateValue) {
Date date = convertDateObject(dateValue);
if (null == date) {
return null;
}
GregorianCalendar pointDate = new GregorianCalendar();
pointDate.setTime(date);
String tmpDate;
StringBuilder result = new StringBuilder();
if (dateValue instanceof String) {
tmpDate = (String) dateValue;
if (tmpDate.length() >= 4) {
result.append(pointDate.get(Calendar.YEAR) + "年");
}
if (tmpDate.length() >= 6) {
result.append((pointDate.get(Calendar.MONTH) + 1) + "月");
}
if (tmpDate.length() >= 8) {
result.append(pointDate.get(Calendar.DAY_OF_MONTH) + "日");
}
if (tmpDate.length() > 10) {
result.append(pointDate.get(Calendar.HOUR_OF_DAY) + "时");
result.append(pointDate.get(Calendar.MINUTE) + "分");
result.append(pointDate.get(Calendar.SECOND) + "秒");
}
} else {
result.append(pointDate.get(Calendar.YEAR) + "年");
result.append((pointDate.get(Calendar.MONTH) + 1) + "月");
result.append(pointDate.get(Calendar.DAY_OF_MONTH) + "日");
result.append(pointDate.get(Calendar.HOUR_OF_DAY) + "时");
result.append(pointDate.get(Calendar.MINUTE) + "分");
result.append(pointDate.get(Calendar.SECOND) + "秒");
}
return result.toString();
}
/**
* @todo 转换中文日期为指定格式的英文日期形式
* @param chinaDate
* @param format
* @return
*/
public static String parseChinaDate(String chinaDate, String format) {
if (StringUtil.isBlank(chinaDate)) {
return null;
}
// 去除中文日期文字之间的空格
String tmp = chinaDate.replaceAll("\\s+", "");
// 处理十几的值
Matcher matcher = MORE_TEN_PATTERN.matcher(tmp);
LinkedHashMap map = new LinkedHashMap();
String groupStr;
while (matcher.find()) {
groupStr = matcher.group();
// 三位如:二十五
if (groupStr.length() == 3) {
map.put(groupStr, groupStr.replace("十", ""));
} else if (groupStr.length() == 2) {
map.put(groupStr, groupStr.replace("十", "1"));
}
}
for (Map.Entry entry : map.entrySet()) {
tmp = tmp.replaceAll(entry.getKey(), entry.getValue());
}
for (int i = 0; i < CHINA_DATE_KEYS.length; i++) {
tmp = tmp.replaceAll(CHINA_DATE_KEYS[i], CHINA_DATE_KEY_MAP[i]);
}
tmp = tmp.replace("整", "").trim();
if (tmp.endsWith("-") || tmp.endsWith(":")) {
tmp = tmp.substring(0, tmp.length() - 1);
}
if (StringUtil.isBlank(format)) {
return tmp.toString();
}
return formatDate(tmp, format);
}
/**
* @todo 转换中文日期为英文格式
* @param chinaDate
* @return
*/
public static String parseChinaDate(String chinaDate) {
return parseChinaDate(chinaDate, null);
}
/**
* @todo 获取月份的第一天
* @param objectDate
* @return
*/
public static Date firstDayOfMonth(Object objectDate) {
Date date = convertDateObject(objectDate);
if (null == date) {
return null;
}
String tmp = formatDate(date, FORMAT.DATE_HORIZONTAL);
return parse(tmp, FORMAT.YEAR_MONTH);
}
/**
* @todo 获取月份的最后一天
* @param objectDate
* @return
*/
public static Date lastDayOfMonth(Object objectDate) {
Date date = convertDateObject(objectDate);
if (null == date) {
return null;
}
String tmp = formatDate(date, FORMAT.DATE_HORIZONTAL);
Date result = parse(tmp, FORMAT.YEAR_MONTH);
result = addMonth(result, 1);
result = addDay(result, -1);
return result;
}
public static Date asDate(LocalDate localDate) {
if (localDate == null) {
return null;
}
return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
}
public static Date asSqlDate(LocalDate localDate) {
if (localDate == null) {
return null;
}
return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
}
public static Date asDate(LocalTime localTime) {
if (localTime == null) {
return null;
}
LocalDateTime localDateTime = LocalDateTime.of(LocalDate.now(), localTime);
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
public static Time asTime(LocalTime localTime) {
if (localTime == null) {
return null;
}
return java.sql.Time.valueOf(localTime);
}
public static Date asDate(LocalDateTime localDateTime) {
if (localDateTime == null) {
return null;
}
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
public static LocalDate asLocalDate(Date date) {
if (date == null) {
return null;
}
return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
}
public static LocalTime asLocalTime(Date date) {
if (date == null) {
return null;
}
return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalTime();
}
public static LocalDateTime asLocalDateTime(Date date) {
if (date == null) {
return null;
}
return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
}
/**
* @TODO 处理英文日期字符串,转化为日期类型
* @param dateStr
* @param locale
* @return
*/
private static Date parseEnglishDate(String dateStr, Locale locale) {
// 统一格式,替换逗号和点号为空白
dateStr = dateStr.replace(",", " ");
dateStr = dateStr.replace(". ", " ");
// 替换时间格式中可能存在的点号
Matcher dotMatcher = TIME_DOT_PATTERN.matcher(dateStr);
List indexList = new ArrayList<>();
while (dotMatcher.find()) {
indexList.add(dotMatcher.start() + 1);
}
if (!indexList.isEmpty()) {
StringBuilder stringBuilder = new StringBuilder(dateStr);
for (int index : indexList) {
stringBuilder.deleteCharAt(index);
stringBuilder.insert(index, ":");
}
dateStr = stringBuilder.toString();
}
for (int i = 0; i < 12; i++) {
dateStr = dateStr.replaceFirst("(?i)" + MONTH_ENGLISH_NAME[i], MONTH_ENGLISH_NAKE[i]);
}
// 统一九月的英文
dateStr = dateStr.replaceFirst("(?i)Sept\\s", "Sep ");
// 统一星期2、星期4的英文
dateStr = dateStr.replaceFirst("(?i)Thur\\s", "Thu ").replaceFirst("(?i)Tues\\s", "Tue ");
for (int i = 0; i < 7; i++) {
dateStr = dateStr.replaceFirst("(?i)" + WEEK_ENGLISH_NAME[i], WEEK_ENGLISH_NAKE[i]);
}
// 首位补空格,便于匹配
dateStr = " ".concat(dateStr);
Matcher daythMatcher = DAYTH_PATTERN.matcher(dateStr);
while (daythMatcher.find()) {
String groupString = daythMatcher.group();
groupString = groupString.substring(0, groupString.length() - 3);
dateStr = dateStr.substring(0, daythMatcher.start()).concat(groupString)
.concat(dateStr.substring(daythMatcher.end() - 1));
break;
}
// 规整将月在前
int monthIndex = StringUtil.matchIndex(dateStr, MONTH_PATTERN);
int dayIndex = StringUtil.matchIndex(dateStr, DAY_PATTERN);
if (monthIndex != 1 && dayIndex != -1 && dayIndex < monthIndex) {
Matcher dayMatcher = DAY_PATTERN.matcher(dateStr);
String dayStr = "";
while (dayMatcher.find()) {
dateStr = dateStr.substring(0, dayMatcher.start()).concat(dateStr.substring(dayMatcher.end() - 1));
dayStr = dayMatcher.group().trim();
break;
}
Matcher mothMatcher = MONTH_PATTERN.matcher(dateStr);
while (mothMatcher.find()) {
dateStr = dateStr.substring(0, mothMatcher.end()).concat(dayStr)
.concat(dateStr.substring(mothMatcher.end() - 1));
break;
}
}
// 是否存在week
boolean hasWeek = StringUtil.matches(dateStr, WEEK_PATTERN);
dateStr = dateStr.trim();
SimpleDateFormat dateParser = null;
Iterator formatIter;
if (StringUtil.matches(dateStr, TIME_PATTERN)) {
if (hasWeek) {
formatIter = DEFAULT_WEEK_TIME_PATTERNS.iterator();
} else {
formatIter = DEFAULT_TIME_PATTERNS.iterator();
}
} else {
if (hasWeek) {
formatIter = DEFAULT_WEEK_DAY_PATTERNS.iterator();
} else {
formatIter = DEFAULT_DAY_PATTERNS.iterator();
}
}
Date result = null;
String format;
while (formatIter.hasNext()) {
format = (String) formatIter.next();
if (dateParser == null) {
dateParser = new SimpleDateFormat(format, (locale == null) ? Locale.ENGLISH : locale);
} else {
dateParser.applyPattern(format);
}
try {
result = dateParser.parse(dateStr);
if (result != null) {
break;
}
} catch (ParseException pe) {
}
}
return result;
}
/**
* @TODO 判断是否有纳秒,并处理优化实际精度
* @param nanoTime
* @return
*/
public static String processNano(int nanoTime) {
// 纳秒为零,则到秒级
if (nanoTime == 0) {
return "";
}
String nanoStr = StringUtil.addLeftZero2Len("" + nanoTime, 9);
// 后6位全为零,则为毫秒
if (nanoStr.endsWith("000000")) {
nanoStr = nanoStr.substring(0, 3);
} // 后3位全为零,则为微秒
else if (nanoStr.endsWith("000")) {
nanoStr = nanoStr.substring(0, 6);
}
return "." + nanoStr;
}
private static String addZero(String timeStr, int toLength) {
return addZero(timeStr, timeStr.length(), toLength);
}
/**
* 快速补充零
*
* @param timeStr
* @param size
* @param toLength
* @return
*/
private static String addZero(String timeStr, int size, int toLength) {
int addSize = toLength - size;
if (addSize == 1) {
return timeStr.concat("0");
} else if (addSize == 2) {
return timeStr.concat("00");
} else if (addSize == 3) {
return timeStr.concat("000");
}
return timeStr;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy