import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
import java.util.Optional;
/**
* 日期转换相关功能的工具类
*
*/
@Slf4j
public class DateUtils {
/**
* 转换UTC时间字符串格式
*/
public static final String UTC_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
public static final DateTimeFormatter EXPIRATION_DATE_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZone(ZoneId.of("UTC"));
public static final DateTimeFormatter DATE_FORMATTER =
DateTimeFormatter.ofPattern("yyyyMMdd").withZone(ZoneId.of("UTC"));
public static final DateTimeFormatter TIME_FORMATTER =
DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'").withZone(ZoneId.of("UTC"));
public static final String DATE_YEAR_FORMATTER = "yyyy";
public static final String DATE_DAY_FORMAT = "yyyyMMdd";
public static final String DATE_HOUR_FORMAT = "yyyyMMddHH";
public static final String DATE_WEEK_FORMAT = "yyyyww";
public static final String DATE_MONTH_FORMAT = "yyyyMM";
/**
* 毫秒级格式
*/
public static final String SAMPLE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
/**
* 默认时间格式
*/
public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
/**
* 失效时间默认为2099-12-31 00:00:00.000
*/
public static final Long EXPIRED_TIMESTAMP = 4102329600000L;
/**
* 52 weeks a year
*/
private static final Integer FIFTY_TWO_WEEK = 52;
/**
* 53 weeks a year
*/
private static final Integer FIFTY_THREE_WEEK = 53;
/**
* 转换UTC时间字符串为Date类型
*
* @param dateStr UTC日期字符串
*
* @return Date类型日期
*/
public static Date convertUtcTime(String dateStr) {
if (StringUtils.isEmpty(dateStr)) {
return null;
}
DateFormat fmt = new SimpleDateFormat(UTC_DATE_FORMAT);
// 严格校验时间
fmt.setLenient(false);
Date date = null;
try {
date = fmt.parse(dateStr);
} catch (ParseException e) {
log.error("Failed to convert msg: {} string: {} to date with format {}.",
e.getMessage(), dateStr, UTC_DATE_FORMAT);
throw new ServiceException(400, PARAM_INVALID, "DateFormat is " + UTC_DATE_FORMAT);
}
return date;
}
/**
* 转换UTC时间字符串为Date类型
*
* @param date UTC日期
*
* @return 字符串类型日期
*/
public static String convertUtcString(Date date) {
if (date == null) {
return null;
}
DateFormat fmt = new SimpleDateFormat(UTC_DATE_FORMAT);
return fmt.format(date);
}
/**
* Format date stamp string.
*
* @param timeMilli the time milli
*
* @return the string
*/
public static String formatDateStamp(long timeMilli) {
return DATE_FORMATTER.format(Instant.ofEpochMilli(timeMilli));
}
/**
* Format timestamp string.
*
* @param timeMilli the time milli
*
* @return the string
*/
public static String formatTimestamp(long timeMilli) {
return TIME_FORMATTER.format(Instant.ofEpochMilli(timeMilli));
}
public static String formatDateStampWithZoneId(long timeMilli, String zoneId) {
LocalDateTime dateTime = Instant.ofEpochMilli(timeMilli).atZone(ZoneId.of(zoneId))
.toLocalDateTime();
DateTimeFormatter pattern = DateTimeFormatter.ofPattern(DATE_DAY_FORMAT);
return pattern.format(dateTime);
}
/**
* 获取失效时间
*
* @param date 当前日期
* @param seconds 秒
*
* @return Date
*/
public static Date getInvalidateDate(Date date, int seconds) {
Calendar instance = Calendar.getInstance();
instance.setTime(date);
instance.add(Calendar.SECOND, seconds);
return instance.getTime();
}
/**
* 描述
*
* @param sample 时间数值
*
* @return java.util.Date
*/
public static Date sampleToDate(Long sample) {
SimpleDateFormat sdf = new SimpleDateFormat(SAMPLE_FORMAT);
String dateStr = sdf.format(sample);
Date newDate = null;
try {
return sdf.parse(dateStr);
} catch (ParseException e) {
log.error("Convert date is exception : {}.", e.toString());
return newDate;
}
}
public static void main(String[] args) {
long st = 1646279306899L;
Date date = sampleToDate(st);
String s = convertUtcString(date);
System.out.println(s);
}
/**
* date 转 yyyyMMdd
*
* @param date 时间
* @param zoneId zoneId
*
* @return 整形时间
*/
public static int localDateToInteger(LocalDateTime date, String zoneId) {
DateTimeFormatter pattern = DateTimeFormatter.ofPattern(DATE_DAY_FORMAT)
.withZone(ZoneId.of(zoneId));
return NumberUtils.parseInt(pattern.format(date));
}
/**
* yyyyMMdd 转LocalDateTime
*
* @param date 日期
*
* @return {@link LocalDateTime}
*/
public static LocalDateTime integerToLocalDate(Integer date) {
if (date == null) {
return null;
}
try {
LocalDateTime time = LocalDateTime
.from(LocalDate.parse(date.toString(), DateTimeFormatter.ofPattern(DATE_DAY_FORMAT)
).atStartOfDay());
String format = DateTimeFormatter.ofPattern(DATE_DAY_FORMAT).format(time);
if (!date.toString().equals(format)) {
return null;
}
return time;
} catch (DateTimeParseException e) {
log.error("IntegerToLocalDate date is exception : {}.", e.toString());
return null;
}
}
/**
* yyyyMMdd 转LocalDateTime
*
* @param date 日期
* @param zoneId 时区
*
* @return {@link LocalDateTime}
*/
public static LocalDateTime integerToLocalDate(Integer date, String zoneId) {
if (date == null) {
return null;
}
try {
return LocalDateTime
.from(LocalDate.parse(date.toString(), DateTimeFormatter.ofPattern(DATE_DAY_FORMAT))
.atStartOfDay(ZoneId.of(zoneId)));
} catch (DateTimeParseException e) {
log.error("IntegerToLocalDate date is exception : {}.", e.toString());
return null;
}
}
/**
* 描述
*
* @param date 日期参数
*
* @return java.lang.String
*/
public static String dateToStr(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
return sdf.format(date);
}
/**
* 将日期时间归至零点
*
* @param date 日期参数
*
* @return java.util.Date
*/
public static Date dateToBeginOfDay(Date date) {
Objects.requireNonNull(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 endDate 日期参数
*
* @return java.util.Date
*/
public static Date convertToBiggestTime(Date endDate) {
Objects.requireNonNull(endDate);
Calendar calendar = Calendar.getInstance();
calendar.setTime(endDate);
calendar.set(Calendar.HOUR_OF_DAY,
calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
calendar.set(Calendar.MINUTE,
calendar.getActualMaximum(Calendar.MINUTE));
calendar.set(Calendar.SECOND,
calendar.getActualMaximum(Calendar.SECOND));
return calendar.getTime();
}
/**
* 将日期时间转化成一天中的最大值
*
* @param oldDate 日期参数
*
* @return java.util.Date
*/
public static Date clone(Date oldDate) {
return Optional.ofNullable(oldDate).map(date -> (Date) date.clone()).orElse(null);
}
/**
* check if is Current
*
* @param timeDim the param timeDim
* @param date the param date
*
* @return the Boolean
*/
public static Boolean isCurrent(String timeDim, Integer date) {
if (timeDim.equals("dayStat")) {
return isCurrentDay(date);
}
if (timeDim.equals("weekStat")) {
return isCurrentWeek(date);
}
if (timeDim.equals("monthStat")) {
return isCurrentMonth(date);
}
return false;
}
/**
* Format date stamp string.
*
* @param timeMilli the time milli
*
* @return the string
*/
public static String formatWeekStamp(long timeMilli) {
DateFormat fmt = new SimpleDateFormat(DATE_WEEK_FORMAT);
return fmt.format(new Date(timeMilli));
}
/**
* Format date stamp string.
*
* @param timeMilli the time milli
*
* @return the string
*/
public static String formatMonthStamp(long timeMilli) {
DateFormat fmt = new SimpleDateFormat(DATE_MONTH_FORMAT);
return fmt.format(new Date(timeMilli));
}
/**
* Format date stamp string.
*
* @param timeMilli the time milli
*
* @return the string
*/
public static String formatYearStamp(long timeMilli) {
DateFormat fmt = new SimpleDateFormat(DATE_YEAR_FORMATTER);
return fmt.format(new Date(timeMilli));
}
/**
* check if is CurrentDay
*
* @param date the param date
*
* @return the Boolean
*/
public static boolean isCurrentDay(Integer date) {
Date currentDate = new Date();
DateFormat fmt = new SimpleDateFormat(DATE_DAY_FORMAT);
return Objects.equals(String.valueOf(date), fmt.format(currentDate));
}
/**
* check if is CurrentWeek
*
* @param week the param week
*
* @return the Boolean
*/
public static boolean isCurrentWeek(Integer week) {
Date currentDate = new Date();
DateFormat fmt = new SimpleDateFormat(DATE_WEEK_FORMAT);
return Objects.equals(String.valueOf(week), fmt.format(currentDate));
}
/**
* check if is isCurrentMonth
*
* @param month the param month
*
* @return the Boolean
*/
public static boolean isCurrentMonth(Integer month) {
Date currentDate = new Date();
DateFormat fmt = new SimpleDateFormat(DATE_MONTH_FORMAT);
return Objects.equals(String.valueOf(month), fmt.format(currentDate));
}
/**
* get the first day of this current week
*
* @param week the param week
*
* @return the Integer
*/
public static Integer getFirstDayOfWeek(Integer week) {
Calendar cal = getWeekCalendar(week);
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
DateFormat fmt = new SimpleDateFormat(DATE_DAY_FORMAT);
return Integer.valueOf(fmt.format(cal.getTime()));
}
/**
* get the first day of next week
*
* @param week the param week
*
* @return the Integer
*/
public static Integer getLastDayOfWeek(Integer week) {
Calendar cal = getWeekCalendar(week);
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
cal.add(Calendar.DAY_OF_WEEK, 7);
DateFormat fmt = new SimpleDateFormat(DATE_DAY_FORMAT);
return Integer.valueOf(fmt.format(cal.getTime()));
}
/**
* get the current week Calender
*
* @param week the param week
*
* @return the Calendar
*/
private static Calendar getWeekCalendar(Integer week) {
int weekOfYear = week % 100; // 202150 % 100 = 50
int year = week / 100; // 202150 / 100 = 2021
Calendar cal = Calendar.getInstance();
cal.setFirstDayOfWeek(Calendar.MONDAY);
cal.set(Calendar.YEAR, year);
cal.set(Calendar.WEEK_OF_YEAR, weekOfYear);
return cal;
}
/**
* get the first day of this current month
*
* @param month the param month
*
* @return the Integer
*/
public static Integer getFirstDayOfMonth(Integer month) {
Calendar cal = getMonthCalendar(month);
cal.set(Calendar.DAY_OF_MONTH, 1);
DateFormat fmt = new SimpleDateFormat(DATE_DAY_FORMAT);
return Integer.valueOf(fmt.format(cal.getTime()));
}
/**
* get the first day of next week
*
* @param month the param month
*
* @return the Integer
*/
public static Integer getLastDayOfMonth(Integer month) {
Calendar cal = getMonthCalendar(month);
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.add(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
DateFormat fmt = new SimpleDateFormat(DATE_DAY_FORMAT);
return Integer.valueOf(fmt.format(cal.getTime()));
}
/**
* get the first month of current year
*
* @param year the param year
*
* @return the Integer
*/
public static Integer getFirstMonthOfYear(Integer year) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, 0);
DateFormat fmt = new SimpleDateFormat(DATE_MONTH_FORMAT);
return Integer.valueOf(fmt.format(cal.getTime()));
}
/**
* get the last month of current year
*
* @param year the param year
*
* @return the Integer
*/
public static Integer getLastMonthOfYear(Integer year) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, cal.getActualMaximum(Calendar.MONTH));
DateFormat fmt = new SimpleDateFormat(DATE_MONTH_FORMAT);
return Integer.valueOf(fmt.format(cal.getTime()));
}
/**
* get the current month Calender
*
* @param monthInput the param week
*
* @return the Calendar
*/
private static Calendar getMonthCalendar(Integer monthInput) {
int month = monthInput % 100; // 202109 % 100 = 9
int year = monthInput / 100; // 202109 / 100 = 2021
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month - 1);
return cal;
}
public static String format(Date time) {
return Optional.ofNullable(time)
.map(date -> {
DateFormat fmt = new SimpleDateFormat(UTC_DATE_FORMAT);
return fmt.format(time);
}).orElse(null);
}
/**
* 判断一年有多少周
*
* @param collecting 时间字符串
*
* @return {@link Boolean}
*/
public static Boolean getWeeksByYear(String collecting) {
int yearNum;
int weekNums;
try {
// 截取年
yearNum = Integer.parseInt(collecting.substring(0, collecting.length() - 2));
// 截取周数
weekNums = Integer.parseInt(collecting.substring(collecting.length() - 2));
} catch (NumberFormatException e) {
log.error("WeeksByYear date is exception : {}", e.getStackTrace());
return false;
}
LocalDateTime time = LocalDateTime.of(yearNum, 12, 31, 0, 0, 0);
DayOfWeek ofWeek = time.getDayOfWeek();
if (ofWeek.getValue() != DayOfWeek.SUNDAY.getValue()) {
if (weekNums < 1 || weekNums > FIFTY_TWO_WEEK) {
return false;
}
return true;
}
if (weekNums < 1 || weekNums > FIFTY_THREE_WEEK) {
return false;
}
return true;
}
}