package com.shkpr.service.alambizplugin.commtools; import org.springframework.util.StringUtils; import java.text.SimpleDateFormat; import java.time.*; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.time.format.ResolverStyle; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; public class TimeTool { public static final long MS_HTTP_REQ_TIMEOUT = 120*1000; //两分钟的毫秒数 public static final long MS_ONE_HALF_MIN = 90*1000; //一分半钟的毫秒数 public static final long MS_ONE_MIN = 60*1000; //一分钟的毫秒数 public static final long MIN_ONE_DAY = 24*60; //一天中的分 public static final long SEC_ONE_DAY = 24*60*60; //一天中的秒 public static final long MS_ONE_DAY = 24*60*60*1000; //一天中的毫秒 public static final long MS_ONE_YEAR = 365*MS_ONE_DAY;//一年中的毫秒 public static final long MS_ONE_HOUR = 60*60*1000; //一小时的毫秒 public static final String YEAR_FORMAT = "yyyy"; public static final String YEAR_MONTH_FORMAT_EX = "yyyyMM"; public static final String YEAR_MONTH_FORMAT = "yyyy-MM"; public static final String YEAR_MONTH_FORMAT_SLASH = "yyyy/MM"; public static final String YEAR_MONTH_DAY_FORMAT = "yyyy-MM-dd"; public static final String TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss"; public static final String TIMESTAMP_FORMAT_EX = "yyyy-MM-dd HH:mm:ss.SSS"; public static final String TIMESTAMP_FORMAT_EX2 = "yyyyMMddHHmmss"; public static final long UTC_MS_START_ONLINE = 1538323200000L;//2018-10-01 00:00:00 public static volatile long UTC_MS_TODAY_BEGIN = 0L; public static volatile long UTC_MS_TODAY_END = 0L; public static volatile long UTC_MS_THIS_MONTH_BEGIN = 0L; public static volatile long UTC_MS_THIS_MONTH_END = 0L; private static final DateTimeFormatter TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT); private static final DateTimeFormatter TIMESTAMP_EX_FORMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT_EX); private static final DateTimeFormatter TIMESTAMP_EX2_FORMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT_EX2); private static final DateTimeFormatter YEAR_MONTH_FORMATTER = DateTimeFormatter.ofPattern(YEAR_MONTH_FORMAT); private static final DateTimeFormatter YEAR_MONTH_DAY_FORMATTER = DateTimeFormatter.ofPattern(YEAR_MONTH_DAY_FORMAT); public static void refreshUTCTimeRes(){ UTC_MS_TODAY_BEGIN = getTodayBeginUTC(); UTC_MS_TODAY_END = getTodayEndUTC(); UTC_MS_THIS_MONTH_BEGIN = getMonthBeginUTC(System.currentTimeMillis()); UTC_MS_THIS_MONTH_END = getMonthEndUTC(System.currentTimeMillis()); } private static LocalDateTime strTime2LocalDateTime(String time, String format) { switch (format){ case YEAR_MONTH_FORMAT: return LocalDateTime.parse(time, YEAR_MONTH_FORMATTER); case YEAR_MONTH_DAY_FORMAT: return LocalDateTime.parse(time, YEAR_MONTH_DAY_FORMATTER); case TIMESTAMP_FORMAT: return LocalDateTime.parse(time, TIMESTAMP_FORMATTER); case TIMESTAMP_FORMAT_EX: return LocalDateTime.parse(time, TIMESTAMP_EX_FORMATTER); case TIMESTAMP_FORMAT_EX2: return LocalDateTime.parse(time, TIMESTAMP_EX2_FORMATTER); default: return LocalDateTime.parse(time, DateTimeFormatter.ofPattern(format)); } } private static String localDateTime2StrTime(LocalDateTime localDateTime, String format) { switch (format){ case YEAR_MONTH_FORMAT: return localDateTime.format(YEAR_MONTH_FORMATTER); case YEAR_MONTH_DAY_FORMAT: return localDateTime.format(YEAR_MONTH_DAY_FORMATTER); case TIMESTAMP_FORMAT: return localDateTime.format(TIMESTAMP_FORMATTER); case TIMESTAMP_FORMAT_EX: return localDateTime.format(TIMESTAMP_EX_FORMATTER); case TIMESTAMP_FORMAT_EX2: return localDateTime.format(TIMESTAMP_EX2_FORMATTER); default: return localDateTime.format(DateTimeFormatter.ofPattern(format)); } } private static LocalDateTime utcMsTime2LocalDateTime(long lUTC) { if (!isMsUTC(lUTC)){ lUTC = lUTC*1000; } Instant instant = Instant.ofEpochMilli(lUTC); ZoneId zone = ZoneId.systemDefault(); return LocalDateTime.ofInstant(instant, zone); } private static long localDateTime2UtcMsTime(LocalDateTime localDateTime) { ZoneId zone = ZoneId.systemDefault(); Instant instant = localDateTime.atZone(zone).toInstant(); return instant.toEpochMilli(); } private static long strTime2UtcMsTime(String dateStr, String format){ return localDateTime2UtcMsTime(strTime2LocalDateTime(dateStr, format)); } private static String utcMsTime2StrTime(long lUTC, String format){ return localDateTime2StrTime(utcMsTime2LocalDateTime(lUTC), format); } public static long convertDateStr2UTC(String dateStr){ try { dateStr = dateStr.trim(); int len = dateStr.length(); if (len >= 23) return strTime2UtcMsTime(dateStr, TIMESTAMP_FORMAT_EX); else if (len >= 19) return strTime2UtcMsTime(dateStr, TIMESTAMP_FORMAT); else if (len >= 14) return strTime2UtcMsTime(dateStr, TIMESTAMP_FORMAT_EX2); else if (len >= 10)//即dataStr为yyyy-MM-dd return strTime2UtcMsTime(String.format("%s 00:00:00", dateStr), TIMESTAMP_FORMAT); else if (len >= 7)//即dataStr为yyyy-MM return strTime2UtcMsTime(String.format("%s-01 00:00:00", dateStr), TIMESTAMP_FORMAT); else if (len >= 6)//即dataStr为yyyyMM return strTime2UtcMsTime(String.format("%s01000000", dateStr), TIMESTAMP_FORMAT_EX2); else if (len >= 4)//即dataStr为yyyy return strTime2UtcMsTime(String.format("%s-01-01 00:00:00", dateStr), TIMESTAMP_FORMAT); }catch (Exception e){} return 0L; } /** * 指定UTC是否为精确到毫秒的UTC时间 * @param lUTC * @return */ public static boolean isMsUTC(long lUTC){ return lUTC > 10000000000L; } public static long getCurSecUTC(){ return (System.currentTimeMillis()/1000)*1000; } public static long getCurMsUTC(){ return System.currentTimeMillis(); } /** * * @param lUTC UTC时间格式(单位:毫秒) * @param strDateFormat 日期格式模板:如:yyyy-MM-dd HH:mm:ss * @return */ public static String convertUTC2DateStr(long lUTC, String strDateFormat){ try { return utcMsTime2StrTime(lUTC<=0?System.currentTimeMillis():lUTC , StringUtils.isEmpty(strDateFormat)?TIMESTAMP_FORMAT:strDateFormat); }catch (Exception e){} return ""; } /** * 从当前时间算起,还有多少毫秒今天将结束 * @return 所剩的毫秒数 */ public static long hasMsWhenTodayEnd(){ long lR = UTC_MS_TODAY_END+1-System.currentTimeMillis(); if (lR <= 0) lR = 1; return lR; } /** * 获取过期时间 * @param nSeconds 从当前时间算起,nSeconds秒后过期 * @return UTC时间格式(单位:毫秒) */ public static long createExpiredTime(long nSeconds){ nSeconds = nSeconds<0?0:nSeconds; long nowMillis = System.currentTimeMillis(); return nowMillis+(nSeconds*1000); } /** * 获取当天的开始时间 * @return UTC时间格式(单位:毫秒) * 返回时间格式为:00:00:00.000所对应的时间戳 */ public static long getTodayBeginUTC(){ return LocalDateTime.of(LocalDate.now(), LocalTime.MIN) .atZone(ZoneId.systemDefault()) .toInstant() .toEpochMilli(); /*Calendar todayStart = Calendar.getInstance(); todayStart.set(Calendar.HOUR_OF_DAY, 0); todayStart.set(Calendar.MINUTE, 0); todayStart.set(Calendar.SECOND, 0); todayStart.set(Calendar.MILLISECOND, 0); return todayStart.getTime().getTime();*/ } /** * 获取当天距离最近的整点时刻 * @return UTC时间格式(单位:毫秒) * @return */ public static long getTodayLastHourUTC(){ return LocalDateTime.now().withMinute(0).withSecond(0).withNano(0) .atZone(ZoneId.systemDefault()) .toInstant() .toEpochMilli(); } /** * 获取指定时间当日的起始时刻(即00:00:00.000) * @param tmMS * @return */ public static long getBeginUTCOfTime(long tmMS){ if (!isMsUTC(tmMS)){ tmMS = tmMS*1000; } LocalDateTime startOfDay = LocalDateTime.ofInstant(Instant.ofEpochMilli(tmMS), ZoneId.systemDefault()).with(LocalTime.MIN); return startOfDay.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); } /** * 获取指定时间当日的结束时刻(即23:59:59.999) * @param tmMS * @return */ public static long getEndUTCOfTime(long tmMS){ if (!isMsUTC(tmMS)){ tmMS = tmMS*1000; } LocalDateTime startOfDay = LocalDateTime.ofInstant(Instant.ofEpochMilli(tmMS), ZoneId.systemDefault()).with(LocalTime.MAX); return startOfDay.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); } /** * 获取当天的结束时间 * @return UTC时间格式(单位:毫秒) * 返回时间格式为:23:59:59.999所对应的时间戳 */ public static long getTodayEndUTC(){ return LocalDateTime.of(LocalDate.now(), LocalTime.MAX) .atZone(ZoneId.systemDefault()) .toInstant() .toEpochMilli(); /*Calendar todayStart = Calendar.getInstance(); todayStart.set(Calendar.HOUR_OF_DAY, 23); todayStart.set(Calendar.MINUTE, 59); todayStart.set(Calendar.SECOND, 59); todayStart.set(Calendar.MILLISECOND, 999); return todayStart.getTime().getTime();*/ } /** * 获取当前时间所在月份的开始时间戳 * @param curTime * @return UTC时间格式(单位:毫秒) * 返回时间格式为:xxxx-xx-01 00:00:00.000所对应的时间戳 */ public static long getMonthBeginUTC(long curTime){ Calendar c = Calendar.getInstance(); if (!isMsUTC(curTime)) curTime = curTime*1000; try { c.setTime(new Date(curTime)); c.set(Calendar.DAY_OF_MONTH, 1); c.set(Calendar.HOUR_OF_DAY, 0); c.set(Calendar.MINUTE, 0); c.set(Calendar.SECOND,0); c.set(Calendar.MILLISECOND, 0); return c.getTimeInMillis(); }catch (Exception e){} return 0L; } /** * 获取当前时间所在月份的结束时间戳 * @param curTime * @return UTC时间格式(单位:毫秒) * 返回时间格式为:xxxx-xx-31 23:59:59.999所对应的时间戳 */ public static long getMonthEndUTC(long curTime){ Calendar c = Calendar.getInstance(); if (!isMsUTC(curTime)) curTime = curTime*1000; try { c.setTime(new Date(curTime)); c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH)); c.set(Calendar.HOUR_OF_DAY, 23); c.set(Calendar.MINUTE, 59); c.set(Calendar.SECOND,59); c.set(Calendar.MILLISECOND, 999); return c.getTimeInMillis(); }catch (Exception e){} return 0L; } /** * 获取指定时间段内的所有月份列表 * @param startTime 起始时间,UTC时间格式,秒或毫秒 * @param endTime 结束时间,UTC时间格式,秒或毫秒 * @return 月份字符串列表 * ["2018-01", "2018-02"] */ public static List getMonthListBetween(long startTime, long endTime){ ArrayList arrMonth = new ArrayList<>(); if (!isMsUTC(startTime)) startTime = startTime*1000; if (!isMsUTC(endTime)) endTime = endTime*1000; try{ String strStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(new Date(startTime)); String strEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(new Date(endTime)); Date dtStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).parse(strStart); Date dtEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).parse(strEnd); Calendar dPos = Calendar.getInstance(); dPos.setTime(dtStart); //设置日期起始时间 while (dPos.getTime().before(dtEnd)) { arrMonth.add((new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(dPos.getTime())); dPos.add(Calendar.MONTH, 1);//进行当前日期月份加1 } arrMonth.add(strEnd); }catch (Exception e){e.printStackTrace();} return arrMonth; } /** * 获取指定时间段内的所有月份列表 * @param startTime 起始时间,UTC时间格式,秒或毫秒 * @param endTime 结束时间,UTC时间格式,秒或毫秒 * @return 月份字符串列表 * ["201801", "201802"] */ public static List getMonthListBetweenEx(long startTime, long endTime){ ArrayList arrMonth = new ArrayList<>(); if (!isMsUTC(startTime)) startTime = startTime*1000; if (!isMsUTC(endTime)) endTime = endTime*1000; try{ String strStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).format(new Date(startTime)); String strEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).format(new Date(endTime)); Date dtStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).parse(strStart); Date dtEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).parse(strEnd); Calendar dPos = Calendar.getInstance(); dPos.setTime(dtStart); //设置日期起始时间 while (dPos.getTime().before(dtEnd)) { arrMonth.add((new SimpleDateFormat(YEAR_MONTH_FORMAT_EX)).format(dPos.getTime())); dPos.add(Calendar.MONTH, 1);//进行当前日期月份加1 } arrMonth.add(strEnd); }catch (Exception e){e.printStackTrace();} return arrMonth; } /** * 获取指定时间段内的所有月份列表UTC * @param startTime 起始时间,UTC时间格式,秒或毫秒 * @param endTime 结束时间,UTC时间格式,秒或毫秒 * @return 月份UTC时间戳列表(精确到毫秒) * [2018-01-01 00:00:00.000对应的UTC, 2018-02-01 00:00:00.000对应的UTC] */ public static List getMonthUTCListBetween(long startTime, long endTime){ ArrayList arrMonth = new ArrayList<>(); if (!isMsUTC(startTime)) startTime = startTime*1000; if (!isMsUTC(endTime)) endTime = endTime*1000; try{ String strStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(new Date(startTime)); String strEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).format(new Date(endTime)); Date dtStart = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).parse(strStart); Date dtEnd = (new SimpleDateFormat(YEAR_MONTH_FORMAT)).parse(strEnd); Calendar dPos = Calendar.getInstance(); dPos.setTime(dtStart); //设置日期起始时间 while (dPos.getTime().before(dtEnd)) { arrMonth.add(dPos.getTimeInMillis()); dPos.add(Calendar.MONTH, 1);//进行当前日期月份加1 } arrMonth.add(dtEnd.getTime()); }catch (Exception e){e.printStackTrace();} return arrMonth; } /** * 获取指定时间段内的所有月份列表 * @param startTime 起始月份,如:2018-01-01 00:00:00 * @param endTime 结束月份,如:2018-02-01 00:00:00 * @return 月份字符串列表 * ["2018-01", "2018-02"] */ public static List getMonthListBetween(String startTime, String endTime){ try { //Date d1 = new SimpleDateFormat(YEAR_MONTH_FORMAT).parse(startTime); //Date d2 = new SimpleDateFormat(YEAR_MONTH_FORMAT).parse(endTime); return getMonthListBetween(convertDateStr2UTC(startTime), convertDateStr2UTC(endTime)); }catch (Exception e){ e.printStackTrace(); } return null; } /** * 获取指定时间段内的所有月份列表 * @param startTime 起始月份,如:2018-01-01 00:00:00 * @param endTime 结束月份,如:2018-02-01 00:00:00 * @return 月份字符串列表 * ["201801", "201802"] */ public static List getMonthListBetweenEx(String startTime, String endTime){ try { //Date d1 = new SimpleDateFormat(YEAR_MONTH_FORMAT_EX).parse(startTime); //Date d2 = new SimpleDateFormat(YEAR_MONTH_FORMAT_EX).parse(endTime); return getMonthListBetweenEx(convertDateStr2UTC(startTime), convertDateStr2UTC(endTime)); }catch (Exception e){ e.printStackTrace(); } return null; } /** * 获取指定时间段内的所有月份列表UTC * @param startTime 起始月份,如:2018-01-01 00:00:00 * @param endTime 结束月份,如:2018-02-01 00:00:00 * @return 月份UTC时间戳列表(精确到秒) * [2018-01-01 00:00:00.000对应的UTC, 2018-02-01 00:00:00.000对应的UTC] */ public static List getMonthUTCListBetween(String startTime, String endTime){ try { Date d1 = new SimpleDateFormat(YEAR_MONTH_FORMAT).parse(startTime); Date d2 = new SimpleDateFormat(YEAR_MONTH_FORMAT).parse(endTime); return getMonthUTCListBetween(d1.getTime(), d2.getTime()); }catch (Exception e){ e.printStackTrace(); } return null; } /** * yyyyMMddhhmmss时间字符串转yyyy-MM-dd HH:mm:ss时间字符串 * @param strDateStr * @return */ public static String addSplitForDateStr(String strDateStr){ if (!StringUtils.isEmpty(strDateStr)){ try { return localDateTime2StrTime(strTime2LocalDateTime(strDateStr, TIMESTAMP_FORMAT_EX2), TIMESTAMP_FORMAT); }catch (Exception e){} } return ""; } /** * 修改指定时间的月份 * @param curTime * @param month > 0 在指定时间上加数个月;< 0 在指定时间上减数个月; * @return */ public static long getTimeChgMonth(long curTime, int month){ if (month == 0) return curTime; Calendar c = Calendar.getInstance(); if (!isMsUTC(curTime)) curTime = curTime*1000; try { c.setTime(new Date(curTime)); c.add(Calendar.MONTH, month); return c.getTimeInMillis(); }catch (Exception e){} return 0L; } public static String convertDateObj2DateStr(Date dateObj, String strDateFormat){ try { int len = strDateFormat.length(); if (len >= 21) return new SimpleDateFormat(TIMESTAMP_FORMAT_EX).format(dateObj); else if (len >= 17) return new SimpleDateFormat(TIMESTAMP_FORMAT).format(dateObj); else if (len >= 12) return new SimpleDateFormat(TIMESTAMP_FORMAT_EX2).format(dateObj); else { int splitCounts = CommTool.totalCharCountsInStr(strDateFormat, '-'); if (splitCounts <= 0) splitCounts = CommTool.totalCharCountsInStr(strDateFormat, '/'); if (splitCounts >= 2) return new SimpleDateFormat(YEAR_MONTH_DAY_FORMAT).format(dateObj); else if (splitCounts >= 1) return new SimpleDateFormat(YEAR_MONTH_FORMAT).format(dateObj); else return new SimpleDateFormat(YEAR_MONTH_FORMAT_EX).format(dateObj); } }catch (Exception e){} return new SimpleDateFormat(YEAR_MONTH_DAY_FORMAT).format(dateObj); } public static boolean checkValidDate(String dateStr) { try { DateTimeFormatter formatter = DateTimeFormatter .ofPattern("uuuu-MM-dd")//使用 "uuuu" 避免年份解析歧义 .withResolverStyle(ResolverStyle.STRICT); LocalDate.parse(dateStr, formatter); return true; } catch (DateTimeParseException e) { return false; } } }