package com.ff.base.utils; import org.apache.commons.lang3.time.DateFormatUtils; import java.lang.management.ManagementFactory; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.*; import java.time.format.DateTimeFormatter; import java.time.temporal.TemporalAdjusters; import java.util.*; /** * 时间工具类 * * @author ff */ public class DateUtils extends org.apache.commons.lang3.time.DateUtils { public static String YYYY = "yyyy"; public static String YYYY_MM = "yyyy-MM"; public static String YYYY_MM_DD = "yyyy-MM-dd"; public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; public static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; public static String HHMMSS = "HH:mm:ss"; public static String DAY_START_TIME = "00:00:00"; public static String DAY_END_TIME = "23:59:59"; public static final String ISO_8601_FORMAT= "yyyy-MM-dd'T'HH:mm:ss"; /** * 获取当前Date型日期 * * @return Date() 当前日期 */ public static Long getNowDate() { return Instant.now().toEpochMilli(); } /** * 获取当前日期 * * @return {@link Long } */ public static Date getCurrentDate() { return new Date(); } /** * 获取当前日期, 默认格式为yyyy-MM-dd * * @return String */ public static String getDate() { return dateTimeNow(YYYY_MM_DD); } public static final String getTime() { return dateTimeNow(YYYY_MM_DD_HH_MM_SS); } public static final String dateTimeNow() { return dateTimeNow(YYYYMMDDHHMMSS); } public static final String dateTimeNow(final String format) { return parseDateToStr(format, new Date()); } public static final String dateTime(final Date date) { return parseDateToStr(YYYY_MM_DD, date); } public static final String parseDateToStr(final String format, final Date date) { return new SimpleDateFormat(format).format(date); } public static final Date dateTime(final String format, final String ts) { try { return new SimpleDateFormat(format).parse(ts); } catch (ParseException e) { throw new RuntimeException(e); } } /** * 日期路径 即年/月/日 如2018/08/08 */ public static final String datePath() { Date now = new Date(); return DateFormatUtils.format(now, "yyyy/MM/dd"); } /** * 日期路径 即年/月/日 如20180808 */ public static final String dateTime() { Date now = new Date(); return DateFormatUtils.format(now, "yyyyMMdd"); } /** * 日期型字符串转化为日期 格式 */ public static Date parseDate(Object str) { if (str == null) { return null; } try { return parseDate(str.toString(), parsePatterns); } catch (ParseException e) { return null; } } /** * 获取服务器启动时间 */ public static Date getServerStartDate() { long time = ManagementFactory.getRuntimeMXBean().getStartTime(); return new Date(time); } /** * 计算相差天数 */ public static int differentDaysByMillisecond(Date date1, Date date2) { return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24))); } /** * 计算时间差 * * @param endDate 最后时间 * @param startTime 开始时间 * @return 时间差(天/小时/分钟) */ public static String timeDistance(Date endDate, Date startTime) { long nd = 1000 * 24 * 60 * 60; long nh = 1000 * 60 * 60; long nm = 1000 * 60; // long ns = 1000; // 获得两个时间的毫秒时间差异 long diff = endDate.getTime() - startTime.getTime(); // 计算差多少天 long day = diff / nd; // 计算差多少小时 long hour = diff % nd / nh; // 计算差多少分钟 long min = diff % nd % nh / nm; // 计算差多少秒//输出结果 // long sec = diff % nd % nh % nm / ns; return day + "天" + hour + "小时" + min + "分钟"; } /** * 增加 LocalDateTime ==> Date */ public static Date toDate(LocalDateTime temporalAccessor) { ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault()); return Date.from(zdt.toInstant()); } /** * 获取格式化日期yymmd * * @return {@link String } */ public static String getFormattedDate() { ZonedDateTime nowUtcMinus4 = ZonedDateTime.now(ZoneId.of("UTC-4")); String year = String.format("%02d", nowUtcMinus4.getYear() % 100); String month = String.format("%02d", nowUtcMinus4.getMonthValue()); String day = String.valueOf(nowUtcMinus4.getDayOfMonth()); return year + month + day; } /** * 将日期格式化为gmt4 * * @param date 日期 * @return {@link String } */ public static String formatDateToGMT4(Date date) { // 将 Date 转换为 ZonedDateTime ZonedDateTime zdt = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of("GMT-4")); // 定义日期时间格式 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); // 格式化并返回字符串 return zdt.format(formatter); } /** * 将时间戳转换为指定格式的时间字符串 * * @param timestamp 时间戳(毫秒) * @param format 目标时间格式,例如:yyyy-MM-dd'T'HH:mm:ssXXX * @param timeZone 时区,例如:GMT+8,UTC等 * @return 格式化后的时间字符串 */ public static String convertTimestampToFormattedDate(long timestamp, String format, String timeZone) { // 创建日期格式化对象 SimpleDateFormat sdf = new SimpleDateFormat(format); // 设置时区为GMT+8 sdf.setTimeZone(TimeZone.getTimeZone(timeZone)); // 转换为 Date 对象 Date date = new Date(timestamp); // 返回格式化后的时间字符串 return sdf.format(date); } /** * 将毫秒时间戳转换为指定时区的时间,并按指定格式输出 * * @param timestampInMillis 毫秒级时间戳 * @param timeZone 时区(例如:America/New_York) * @param format 时间格式(例如:yyyy-MM-dd HH:mm:ss) * @return 格式化后的时间字符串 */ public static String convertTimeZone(long timestampInMillis, String timeZone, String format) { // 将毫秒时间戳转换为 Instant Instant instant = Instant.ofEpochMilli(timestampInMillis); // 将 UTC 时间转换为指定时区的时间 ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of(timeZone)); // 格式化输出为指定格式的时间字符串 return zonedDateTime.format(DateTimeFormatter.ofPattern(format)); } /** * 增加 LocalDate ==> Date */ public static Date toDate(LocalDate temporalAccessor) { LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0)); ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); return Date.from(zdt.toInstant()); } /** * 给定毫秒级时间戳,增加或扣除指定分钟 * * @param timestampMillis 初始时间戳(毫秒级) * @param minutes 要增加或扣除的分钟数(正值为增加,负值为扣除) * @return long 结果时间戳(毫秒级) */ public static long addOrSubtractMinutes(long timestampMillis, int minutes) { // 将分钟转换为毫秒,并加到时间戳上 return timestampMillis + minutes * 60 * 1000L; } /** * 加或减一天 * * @param timestampDay 时间戳日期 * @param day 白天 * @return long */ public static long addOrSubtractDay(long timestampDay, int day) { // 将分钟转换为毫秒,并加到时间戳上 return timestampDay + day * 60 * 1000L * 60 * 24; } /** * 获取给定日期 * * @return 不带时区的给定日期的起始时间戳(毫秒) */ public static Long getDayStart(Calendar calendar) { // 设置时间为当天的 00:00:00 calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTimeInMillis(); } /** * 获取指定时间戳指定时区的一天的开始时间 * * @param timestamp 时间戳 * @param timeZoneId 时区 * @return 时间戳 */ public static Long getDayStart(long timestamp, String timeZoneId) { ZoneId zoneId = ZoneId.of(timeZoneId); ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(java.time.Instant.ofEpochMilli(timestamp), zoneId); LocalDate localDate = zonedDateTime.toLocalDate(); LocalDateTime startOfDay = localDate.atStartOfDay(); ZonedDateTime startOfDayZoned = startOfDay.atZone(zoneId); return startOfDayZoned.toInstant().toEpochMilli(); } /** * 获取给定日期 * * @return 不带时区的给定日期的结束时间戳(毫秒) */ public static Long getDayEnd(Calendar calendar) { // 设置时间为当天的 23:59:59 calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 59); calendar.set(Calendar.MILLISECOND, 999); return calendar.getTimeInMillis(); } /** * 获取指定时间戳指定时区的一天的结束时间 * * @param timestamp 时间戳 * @param timeZoneId 时区 * @return 时间戳 */ public static Long getDayEnd(long timestamp, String timeZoneId) { ZoneId zoneId = ZoneId.of(timeZoneId); ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(java.time.Instant.ofEpochMilli(timestamp), zoneId); LocalDate localDate = zonedDateTime.toLocalDate(); LocalDateTime endOfDay = localDate.atTime(23, 59, 59, 999999999); ZonedDateTime endOfDayZoned = endOfDay.atZone(zoneId); return endOfDayZoned.toInstant().toEpochMilli(); } /** * 获取昨天的开始时间(不带时区) * * @return 时间戳 */ public static Long getYesterdayStart() { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); // 回溯一天 calendar.add(Calendar.DAY_OF_MONTH, -1); // 设置时间为当天的 00:00:00 calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTimeInMillis(); } /** * 获取昨天的结束时间(不带时区) * * @return 时间戳 */ public static Long getYesterdayEnd() { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); // 回溯一天 calendar.add(Calendar.DAY_OF_MONTH, -1); // 设置时间为当天的 23:59:59 calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 59); calendar.set(Calendar.MILLISECOND, 999); return calendar.getTimeInMillis(); } /** * 获取上周的开始时间(不带时区) * * @return 时间戳 */ public static Long getLastWeekBegin() { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); // 计算上周的起始日期(周一) calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); calendar.add(Calendar.WEEK_OF_YEAR, -1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTimeInMillis(); } /** * 获取上周的结束时间(不带时区) * * @return 时间戳 */ public static Long getLastWeekEnd() { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); // 计算上周的结束日期(周日) calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 59); calendar.set(Calendar.MILLISECOND, 999); return calendar.getTimeInMillis(); } /** * 获取一周的开始时间 * * @return 时间戳 */ public static Long getWeekBegin(Calendar calendar) { // 设置一周的第一天为星期一 calendar.setFirstDayOfWeek(Calendar.MONDAY); // 获取当前日期在本周的位置 int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); // 计算需要回溯的天数 int daysToSubtract = (dayOfWeek == Calendar.SUNDAY ? 6 : dayOfWeek - 2); calendar.add(Calendar.DAY_OF_MONTH, -daysToSubtract); // 设置时间为当天的 00:00:00 calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTimeInMillis(); } /** * 获取一周的结束时间 * * @return 时间戳 */ public static Long getWeekEnd(Calendar calendar) { // 设置一周的第一天为星期一 calendar.setFirstDayOfWeek(Calendar.MONDAY); // 获取当前日期在本周的位置 int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); // 计算需要前进的天数 int daysToAdd = (dayOfWeek == Calendar.SUNDAY ? 0 : 7 - (dayOfWeek - 1)); calendar.add(Calendar.DAY_OF_MONTH, daysToAdd); // 设置时间为当天的 23:59:59 calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 59); calendar.set(Calendar.MILLISECOND, 999); return calendar.getTimeInMillis(); } /** * 获取当前月份的开始时间 * * @return 时间戳 */ public static Long getMonthStart(Calendar calendar) { // 设置时间为当月的第一天 calendar.set(Calendar.DAY_OF_MONTH, 1); // 设置时间为当天的 00:00:00 calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTimeInMillis(); } /** * 获取当前月份的结束时间(不带时区) * * @return 时间戳 */ public static Long getMonthEnd(Calendar calendar) { // 设置时间为当月的最后一天 calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); // 设置时间为当天的 23:59:59 calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 59); calendar.set(Calendar.MILLISECOND, 999); return calendar.getTimeInMillis(); } /** * 获取上个月的开始时间(不带时区) * * @return 时间戳 */ public static Long getLastMonthStart() { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); // 计算上个月的起始日期(1号) calendar.add(Calendar.MONTH, -1); calendar.set(Calendar.DAY_OF_MONTH, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTimeInMillis(); } /** * 获取上个月的结束时间(不带时区) * * @return 时间戳 */ public static Long getLastMonthEnd() { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); calendar.add(Calendar.MONTH, -1); // 回退一个月 // 计算上个月的结束日期(最后一天) calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); // 设置日期为当月最后一天 calendar.set(Calendar.HOUR_OF_DAY, 23); // 设置小时为23 calendar.set(Calendar.MINUTE, 59); // 设置分钟为59 calendar.set(Calendar.SECOND, 59); // 设置秒为59 calendar.set(Calendar.MILLISECOND, 999); // 设置毫秒为999 return calendar.getTimeInMillis(); } /** * 判断时间戳 A 距离时间戳 B 近还是距离时间戳 C 近 * * @param timestampA 时间戳 A * @param timestampB 时间戳 B * @param timestampC 时间戳 C * @return 返回 true 表示时间戳 A 更接近时间戳 B,返回 false 表示时间戳 A 更接近时间戳 C */ public static boolean isCloserToB(long timestampA, long timestampB, long timestampC) { long diffAB = Math.abs(timestampA - timestampB); long diffAC = Math.abs(timestampA - timestampC); return diffAB < diffAC; } /** * 获取指定时间戳次日指定时区指定时间的时间戳 * * @param utcTimestamp utc时间戳 * @param date 具体时间 * @param timeZonId 指定时区 * @return 只改变时区 不改变具体日期的时间戳 */ public static long getTomorrowTimeByZonId(long utcTimestamp, Date date, String timeZonId) { SimpleDateFormat sdf = new SimpleDateFormat(HHMMSS); String format = sdf.format(date); DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(HHMMSS); LocalTime localTime = LocalTime.parse(format, timeFormatter); // 将时间戳转换为 Instant Instant instant = Instant.ofEpochMilli(addOrSubtractDay(utcTimestamp, 1)); ZoneId zoneId = ZoneId.of(timeZonId); LocalDate localDate = instant.atZone(zoneId).toLocalDate(); LocalDateTime tomorrowDrawStartTime = localDate.atTime(localTime); return tomorrowDrawStartTime.atZone(zoneId).toInstant().toEpochMilli(); } /** * 指定时区并具体时间的的实时时间戳 * * @param date 具体时间 * @param timeZonId 时区 * @return 只改变时区 不改变具体日期的时间戳 */ public static long getTodayTimeByZonId(Date date, String timeZonId) { // 获取今日指定时间后的时间戳 SimpleDateFormat sdf = new SimpleDateFormat(HHMMSS); String format = sdf.format(date); DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(HHMMSS); LocalTime localTime = LocalTime.parse(format, timeFormatter); LocalDate currentDate = LocalDate.now(); LocalDateTime todayDrawStartTime = currentDate.atTime(localTime); ZoneId zoneId = ZoneId.of(timeZonId); return todayDrawStartTime.atZone(zoneId).toInstant().toEpochMilli(); } /** * 获取下周指定周几的几点的指定时区时间戳 * * @param dayOfWeek 周几,1-7表示周一到周日 * @param date 具体时间,Date对象 * @return UTC时间戳(毫秒) */ public static long getNextWeekTimestamp(int dayOfWeek, Date date, ZoneId zoneId) { // 将Date对象转换为LocalDateTime对象 SimpleDateFormat sdf = new SimpleDateFormat(HHMMSS); String format = sdf.format(date); DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(HHMMSS); LocalTime localTime = LocalTime.parse(format, timeFormatter); // 获取当前日期时间 ZonedDateTime now = ZonedDateTime.now(zoneId); // 找到本周的周几 ZonedDateTime startOfWeek = now.with(dayOfWeek < now.getDayOfWeek().getValue() ? TemporalAdjusters.previousOrSame(DayOfWeek.of(dayOfWeek)) : TemporalAdjusters.nextOrSame(DayOfWeek.of(dayOfWeek))); // 加上一个完整的星期,得到下周的周几 ZonedDateTime nextWeekStart = startOfWeek.plusWeeks(1); // 设置指定的时间 ZonedDateTime targetDateTime = nextWeekStart.withHour(localTime.getHour()).withMinute(localTime.getMinute()).withSecond(localTime.getSecond()).withNano(0); // 转换为时间戳(毫秒) return targetDateTime.toInstant().toEpochMilli(); } /** * 获取指定时区当前周指定周几的几点的时间戳 * * @param dayOfWeek 周几,1-7表示周一到周日 * @param date 具体时间,Date对象 * @return 时间戳(毫秒) */ public static long getCurrentWeekTimestamp(int dayOfWeek, Date date, ZoneId zoneId) { // 将Date对象转换为LocalDateTime对象 SimpleDateFormat sdf = new SimpleDateFormat(HHMMSS); String format = sdf.format(date); DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(HHMMSS); LocalTime localTime = LocalTime.parse(format, timeFormatter); // 获取当前日期时间 LocalDateTime now = LocalDateTime.now(); // 获取当前周的指定周几的日期时间 LocalDateTime currentWeekDateTime = now.with(dayOfWeek < now.getDayOfWeek().getValue() ? TemporalAdjusters.previousOrSame(DayOfWeek.of(dayOfWeek)) : TemporalAdjusters.nextOrSame(DayOfWeek.of(dayOfWeek))) .withHour(localTime.getHour()) .withMinute(localTime.getMinute()) .withSecond(localTime.getSecond()) .withNano(0); // 将LocalDateTime转换为ZonedDateTime,使用UTC时区 ZonedDateTime zonedDateTime = currentWeekDateTime.atZone(zoneId); // 将ZonedDateTime转换为时间戳(毫秒) return zonedDateTime.toInstant().toEpochMilli(); } /** * 获取下月指定日的几点的时间戳 * * @param dayOfMonth 指定日,1-31表示 * @param date 具体时间,Date对象 * @param month 下几月 * @return 时间戳(毫秒) */ public static long getNextMonthTimestamp(int dayOfMonth, Date date, ZoneId zoneId, int month) { // 将Date对象转换为LocalDateTime对象 SimpleDateFormat sdf = new SimpleDateFormat(HHMMSS); String format = sdf.format(date); DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(HHMMSS); LocalTime localTime = LocalTime.parse(format, timeFormatter); // 获取当前日期时间 LocalDateTime now = LocalDateTime.now(); // 获取下个月的年份和月份 YearMonth nextMonth = YearMonth.from(now).plusMonths(month); int maxDayNum = nextMonth.lengthOfMonth(); if (dayOfMonth > maxDayNum) { dayOfMonth = maxDayNum; } // 创建下个月指定日的LocalDateTime对象 LocalDateTime nextMonthDateTime = LocalDateTime.of(nextMonth.getYear(), nextMonth.getMonth(), dayOfMonth, localTime.getHour(), localTime.getMinute(), localTime.getSecond(), 0); // 将LocalDateTime转换为ZonedDateTime,使用UTC时区 ZonedDateTime zonedDateTime = nextMonthDateTime.atZone(zoneId); // 将ZonedDateTime转换为时间戳(毫秒) return zonedDateTime.toInstant().toEpochMilli(); } /** * 获取本月指定日的几点的时间戳 * * @param dayOfMonth 指定日,1-31表示 * @param date 具体时间,Date对象 * @return 时间戳(毫秒) */ public static long getCurrentMonthTimestamp(int dayOfMonth, Date date, ZoneId zoneId) { // 将Date对象转换为LocalDateTime对象 SimpleDateFormat sdf = new SimpleDateFormat(HHMMSS); String format = sdf.format(date); DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(HHMMSS); LocalTime localTime = LocalTime.parse(format, timeFormatter); // 获取当前日期时间 LocalDateTime now = LocalDateTime.now(); // 获取本月的年份和月份 YearMonth currentMonth = YearMonth.from(now); int maxDayNum = currentMonth.lengthOfMonth(); if (dayOfMonth > maxDayNum) { dayOfMonth = maxDayNum; } // 创建本月指定日的LocalDateTime对象 LocalDateTime currentMonthDateTime = LocalDateTime.of(currentMonth.getYear(), currentMonth.getMonth(), dayOfMonth, localTime.getHour(), localTime.getMinute(), localTime.getSecond(), 0); // 将LocalDateTime转换为ZonedDateTime,使用UTC时区 ZonedDateTime zonedDateTime = currentMonthDateTime.atZone(zoneId); // 将ZonedDateTime转换为时间戳(毫秒) return zonedDateTime.toInstant().toEpochMilli(); } /** * 将时间戳转换为UTC0时区的时间戳 * * @param timeZoneId 时区id * @param timestamp 时间戳 * @return UTC0时区的时间戳 */ public static long covertToUTCtimestamp(String timeZoneId, long timestamp) { // 将时间戳转换为 Instant 对象 Instant instant = Instant.ofEpochMilli(timestamp); // 使用指定的时区将 Instant 对象转换为 ZonedDateTime 对象 ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of(timeZoneId)); ZonedDateTime zonedDateTime1 = zonedDateTime.withZoneSameLocal(ZoneOffset.UTC); // 将 ZonedDateTime 对象转换为 UTC0 时区的 Instant 对象 // 获取 UTC0 时区的时间戳(以毫秒为单位) return zonedDateTime1.toInstant().toEpochMilli(); } /** * 将UTC时间戳转换为指定时区的时间戳 * * @param timeZoneId 时区id * @param timestamp 时间戳 * @return 指定时区的时间戳 */ public static long covertUTCTotimeZonetimestamp(String timeZoneId, long timestamp) { // 将时间戳转换为 Instant 对象 Instant instant = Instant.ofEpochMilli(timestamp); // 使用指定的时区将 Instant 对象转换为 ZonedDateTime 对象 ZonedDateTime zonedDateTime = instant.atZone(ZoneOffset.UTC); ZonedDateTime zonedDateTime1 = zonedDateTime.withZoneSameLocal(ZoneId.of(timeZoneId)); // 获取 指定 时区的时间戳(以毫秒为单位) return zonedDateTime1.toInstant().toEpochMilli(); } /** * 判断是否是指定时区的当天的0点 * * @param timestamp * @param timeZone * @return */ public static boolean isMidnight(long timestamp, TimeZone timeZone) { Calendar calendar = Calendar.getInstance(timeZone); calendar.setTimeInMillis(timestamp); return calendar.get(Calendar.HOUR_OF_DAY) == 0 && calendar.get(Calendar.MINUTE) == 0 && calendar.get(Calendar.SECOND) == 0 && calendar.get(Calendar.MILLISECOND) == 0; } /** * 判断是否是指定时区的周一的0点 * * @param timestamp 时间戳 * @param timeZone 指定时区 * @return 是否是周一的0点 */ public static boolean isMondayMidnight(long timestamp, TimeZone timeZone) { Calendar calendar = Calendar.getInstance(timeZone); calendar.setTimeInMillis(timestamp); return isMidnight(timestamp, timeZone) && calendar.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY; } /** * 将 ISO 8601 格式的时间字符串转换为毫秒时间戳 * * @param isoDate ISO 8601 格式的时间字符串,例如 "2025-05-10T08:23:34Z" * @return 从 Unix epoch 开始的毫秒时间戳 */ public static long convertToMilliseconds(String isoDate) { Instant instant = Instant.parse(isoDate); return instant.toEpochMilli(); } /** * 将 ZoneId 转换为 TimeZone * * @param zoneId 要转换的 ZoneId * @return 对应的 TimeZone */ public static TimeZone zoneIdToTimeZone(ZoneId zoneId) { return TimeZone.getTimeZone(zoneId.getId()); } /** * 获取指定星期几的开始和结束UTC时间戳 * * @param dayOfWeek 星期几,1-7,1表示星期一,7表示星期日 * @return 包含开始和结束UTC时间戳的数组,第一个元素是开始时间戳,第二个元素是结束时间戳 */ public static Map getStartAndEndUTCTimestampOfDayOfWeek(int dayOfWeek) { if (dayOfWeek < 1 || dayOfWeek > 7) { throw new IllegalArgumentException("dayOfWeek must be between 1 and 7"); } // 获取当前日期 LocalDate today = LocalDate.now(ZoneOffset.UTC); // 计算本周的开始日期(星期一) LocalDate monday = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); // 计算指定星期几的日期 LocalDate targetDay = monday.plusDays(dayOfWeek - 1); // 计算指定星期几的开始时间(00:00:00 UTC) ZonedDateTime startOfDay = targetDay.atStartOfDay(ZoneOffset.UTC); // 计算指定星期几的结束时间(23:59:59 UTC) ZonedDateTime endOfDay = targetDay.atTime(LocalTime.MAX).atZone(ZoneOffset.UTC); // 获取开始和结束时间戳 long startTimestamp = startOfDay.toInstant().toEpochMilli(); long endTimestamp = endOfDay.toInstant().toEpochMilli(); Map map = new HashMap<>(); map.put("beginTime", startTimestamp); map.put("endTime", endTimestamp); return map; } /** * 获取本月指定月几号的开始和结束UTC时间戳 * * @param dayOfMonth 本月几号,1-31 * @return 包含开始和结束UTC时间戳的Map,键分别为"beginTime"和"endTime" */ public static Map getStartAndEndUTCTimestampOfDayOfMonth(int dayOfMonth) { // 获取当前日期 LocalDate today = LocalDate.now(ZoneOffset.UTC); // 获取本月的年份和月份 YearMonth currentMonth = YearMonth.from(today); int maxDayNum = currentMonth.lengthOfMonth(); if (dayOfMonth > maxDayNum) { dayOfMonth = maxDayNum; } // 获取当前年份和月份 int year = today.getYear(); int month = today.getMonthValue(); // 构建指定月几号的日期 LocalDate targetDay; try { targetDay = LocalDate.of(year, month, dayOfMonth); } catch (DateTimeException e) { throw new IllegalArgumentException("Invalid dayOfMonth for the current month", e); } // 计算指定月几号的开始时间(00:00:00 UTC) ZonedDateTime startOfDay = targetDay.atStartOfDay(ZoneOffset.UTC); // 计算指定月几号的结束时间(23:59:59 UTC) ZonedDateTime endOfDay = targetDay.atTime(LocalTime.MAX).atZone(ZoneOffset.UTC); // 获取开始和结束时间戳 long startTimestamp = startOfDay.toInstant().toEpochMilli(); long endTimestamp = endOfDay.toInstant().toEpochMilli(); Map map = new HashMap<>(); map.put("beginTime", startTimestamp); map.put("endTime", endTimestamp); return map; } /** * 判断两个毫秒级时间戳是否为同一天 * * @param timestamp1 第一个时间戳 * @param timestamp2 第二个时间戳 * @return 如果两个时间戳属于同一天,返回true;否则返回false */ public static boolean isSameDay(long timestamp1, long timestamp2) { // 将时间戳转换为 LocalDate LocalDate date1 = Instant.ofEpochMilli(timestamp1) .atZone(ZoneId.systemDefault()) // 使用系统默认时区 .toLocalDate(); LocalDate date2 = Instant.ofEpochMilli(timestamp2) .atZone(ZoneId.systemDefault()) // 使用系统默认时区 .toLocalDate(); // 比较日期部分是否相同 return date1.isEqual(date2); } /** * 获取 UTC 时区的当前日期,并返回 java.util.Date 类型 * * @return java.util.Date 对象,表示 UTC 时区的当前日期 */ public static Date getUTCDate() { // 获取 UTC 时区的当前时间 ZonedDateTime utcTime = ZonedDateTime.now(ZoneId.of("UTC")); // 提取 UTC 时区的日期部分 ZonedDateTime utcDateTime = utcTime.toLocalDate().atStartOfDay(ZoneId.of("UTC")); // 将 ZonedDateTime 转换为 java.util.Date return Date.from(utcDateTime.toInstant()); } /** * 将 LocalTime 转换为 Date * * @param localTime LocalTime对象 * @return Date对象 */ public static Date convertToDate(LocalTime localTime) { // 使用当前日期作为参考日期 LocalDate today = LocalDate.now(); // 将 LocalTime 和 LocalDate 结合成 LocalDateTime LocalDateTime localDateTime = LocalDateTime.of(today, localTime); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String format = localDateTime.format(formatter); // 将 LocalDateTime 转换为 Date return DateUtils.parseDate(format); } /** * 判断是否在指定时间段内 * * @param value 要判断的时间戳 * @param minValue 开始时间戳 * @param maxValue 结束时间戳 * @return 是否在指定时间段内 */ public static boolean isBetween(Long value, Long minValue, Long maxValue) { return value >= minValue && value <= maxValue; } }