From 6904379440e2c1c3b8c4c868e9706bd563e7df7f Mon Sep 17 00:00:00 2001
From: zhaowenyu <35589726@qq.com>
Date: Sat, 15 Nov 2025 15:34:23 +0800
Subject: [PATCH] 2025-11-15 zwy 对时间戳的工具类

---
 ard-sample/src/main/java/com/ard/sample/utils/TimestampUtils.java |  257 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 257 insertions(+), 0 deletions(-)

diff --git a/ard-sample/src/main/java/com/ard/sample/utils/TimestampUtils.java b/ard-sample/src/main/java/com/ard/sample/utils/TimestampUtils.java
new file mode 100644
index 0000000..e748a19
--- /dev/null
+++ b/ard-sample/src/main/java/com/ard/sample/utils/TimestampUtils.java
@@ -0,0 +1,257 @@
+package com.ard.sample.utils;
+
+import org.springframework.stereotype.Component;
+
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * 时间戳工具类(支持毫秒级/秒级时间戳,基于Java 8+时间API)
+ * 功能:加/减时间、转换为LocalDateTime、格式化字符串等
+ */
+@Component
+public class TimestampUtils {
+
+    // 默认时区:北京时间(Asia/Shanghai)
+    private static final ZoneId DEFAULT_ZONE = ZoneId.of("Asia/Shanghai");
+
+    // 默认日期时间格式:yyyy-MM-dd HH:mm:ss
+    private static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+    // 时间单位常量(毫秒)
+    private static final long ONE_SECOND = 1000L;         // 1秒 = 1000毫秒
+    private static final long ONE_MINUTE = 60 * ONE_SECOND; // 1分钟 = 60秒
+    private static final long ONE_HOUR = 60 * ONE_MINUTE;   // 1小时 = 60分钟
+    private static final long ONE_DAY = 24 * ONE_HOUR;      // 1天 = 24小时
+
+
+    // -------------------------- 毫秒级时间戳操作 --------------------------
+
+    /**
+     * 毫秒级时间戳 + N天
+     * @param millisTimestamp 原毫秒级时间戳(13位)
+     * @param days 天数(正数加,负数减)
+     * @return 计算后的毫秒级时间戳
+     */
+    public long plusDaysByMillis(long millisTimestamp, int days) {
+        return Instant.ofEpochMilli(millisTimestamp)
+                .plusMillis(days * ONE_DAY)
+                .toEpochMilli();
+    }
+
+    /**
+     * 毫秒级时间戳 + N小时
+     * @param millisTimestamp 原毫秒级时间戳(13位)
+     * @param hours 小时数(正数加,负数减)
+     * @return 计算后的毫秒级时间戳
+     */
+    public long plusHoursByMillis(long millisTimestamp, int hours) {
+        return Instant.ofEpochMilli(millisTimestamp)
+                .plusMillis(hours * ONE_HOUR)
+                .toEpochMilli();
+    }
+
+    /**
+     * 毫秒级时间戳 + N分钟
+     * @param millisTimestamp 原毫秒级时间戳(13位)
+     * @param minutes 分钟数(正数加,负数减)
+     * @return 计算后的毫秒级时间戳
+     */
+    public long plusMinutesByMillis(long millisTimestamp, int minutes) {
+        return Instant.ofEpochMilli(millisTimestamp)
+                .plusMillis(minutes * ONE_MINUTE)
+                .toEpochMilli();
+    }
+
+    /**
+     * 毫秒级时间戳 + N秒
+     * @param millisTimestamp 原毫秒级时间戳(13位)
+     * @param seconds 秒数(正数加,负数减)
+     * @return 计算后的毫秒级时间戳
+     */
+    public long plusSecondsByMillis(long millisTimestamp, int seconds) {
+        return Instant.ofEpochMilli(millisTimestamp)
+                .plusMillis(seconds * ONE_SECOND)
+                .toEpochMilli();
+    }
+
+
+    // -------------------------- 秒级时间戳操作 --------------------------
+
+    /**
+     * 秒级时间戳 + N天(自动转换为毫秒级计算,结果转回秒级)
+     * @param secondTimestamp 原秒级时间戳(10位)
+     * @param days 天数(正数加,负数减)
+     * @return 计算后的秒级时间戳
+     */
+    public long plusDaysBySecond(long secondTimestamp, int days) {
+        long millis = secondTimestamp * ONE_SECOND;
+        long newMillis = plusDaysByMillis(millis, days);
+        return newMillis / ONE_SECOND;
+    }
+
+    /**
+     * 秒级时间戳 + N小时
+     * @param secondTimestamp 原秒级时间戳(10位)
+     * @param hours 小时数(正数加,负数减)
+     * @return 计算后的秒级时间戳
+     */
+    public long plusHoursBySecond(long secondTimestamp, int hours) {
+        long millis = secondTimestamp * ONE_SECOND;
+        long newMillis = plusHoursByMillis(millis, hours);
+        return newMillis / ONE_SECOND;
+    }
+
+    /**
+     * 秒级时间戳 + N分钟
+     * @param secondTimestamp 原秒级时间戳(10位)
+     * @param minutes 分钟数(正数加,负数减)
+     * @return 计算后的秒级时间戳
+     */
+    public long plusMinutesBySecond(long secondTimestamp, int minutes) {
+        long millis = secondTimestamp * ONE_SECOND;
+        long newMillis = plusMinutesByMillis(millis, minutes);
+        return newMillis / ONE_SECOND;
+    }
+
+    /**
+     * 秒级时间戳 + N秒
+     * @param secondTimestamp 原秒级时间戳(10位)
+     * @param seconds 秒数(正数加,负数减)
+     * @return 计算后的秒级时间戳
+     */
+    public long plusSecondsBySecond(long secondTimestamp, int seconds) {
+        return secondTimestamp + seconds; // 秒级直接加减,无需转毫秒
+    }
+
+
+    // -------------------------- 时间戳转换为LocalDateTime --------------------------
+
+    /**
+     * 毫秒级时间戳转换为LocalDateTime(默认时区:北京时间)
+     * @param millisTimestamp 毫秒级时间戳(13位)
+     * @return LocalDateTime对象
+     */
+    public LocalDateTime toLocalDateTimeByMillis(long millisTimestamp) {
+        return LocalDateTime.ofInstant(
+                Instant.ofEpochMilli(millisTimestamp),
+                DEFAULT_ZONE
+        );
+    }
+
+    /**
+     * 秒级时间戳转换为LocalDateTime(默认时区:北京时间)
+     * @param secondTimestamp 秒级时间戳(10位)
+     * @return LocalDateTime对象
+     */
+    public LocalDateTime toLocalDateTimeBySecond(long secondTimestamp) {
+        return LocalDateTime.ofInstant(
+                Instant.ofEpochSecond(secondTimestamp), // 直接用ofEpochSecond处理秒级
+                DEFAULT_ZONE
+        );
+    }
+
+
+    // -------------------------- 时间戳格式化为字符串 --------------------------
+
+    /**
+     * 毫秒级时间戳格式化为字符串(默认格式:yyyy-MM-dd HH:mm:ss)
+     * @param millisTimestamp 毫秒级时间戳(13位)
+     * @return 格式化后的字符串
+     */
+    public String formatByMillis(long millisTimestamp) {
+        return formatByMillis(millisTimestamp, DEFAULT_FORMATTER);
+    }
+
+    /**
+     * 毫秒级时间戳格式化为自定义格式字符串
+     * @param millisTimestamp 毫秒级时间戳(13位)
+     * @param formatter 自定义格式器(如:DateTimeFormatter.ofPattern("yyyy/MM/dd"))
+     * @return 格式化后的字符串
+     */
+    public String formatByMillis(long millisTimestamp, DateTimeFormatter formatter) {
+        LocalDateTime dateTime = toLocalDateTimeByMillis(millisTimestamp);
+        return dateTime.format(formatter);
+    }
+
+    /**
+     * 秒级时间戳格式化为字符串(默认格式:yyyy-MM-dd HH:mm:ss)
+     * @param secondTimestamp 秒级时间戳(10位)
+     * @return 格式化后的字符串
+     */
+    public String formatBySecond(long secondTimestamp) {
+        return formatBySecond(secondTimestamp, DEFAULT_FORMATTER);
+    }
+
+    /**
+     * 秒级时间戳格式化为自定义格式字符串
+     * @param secondTimestamp 秒级时间戳(10位)
+     * @param formatter 自定义格式器
+     * @return 格式化后的字符串
+     */
+    public String formatBySecond(long secondTimestamp, DateTimeFormatter formatter) {
+        LocalDateTime dateTime = toLocalDateTimeBySecond(secondTimestamp);
+        return dateTime.format(formatter);
+    }
+
+    /**
+     * 取原时间戳的时间部分,与当前日期组合成新时间戳
+     * @param originalTimestamp 原时间戳(毫秒,如System.currentTimeMillis()返回值)
+     * @return 组合后的新时间戳(毫秒)
+     */
+    public Long combine( Long originalTimestamp) {
+        // 1. 校验原时间戳合法性
+        if (originalTimestamp == null || originalTimestamp < 0) {
+            throw new IllegalArgumentException("原时间戳无效");
+        }
+
+        // 2. 解析原时间戳,提取时间部分(时、分、秒、毫秒)
+        // 原时间戳转换为ZonedDateTime(带时区的日期时间)
+        ZonedDateTime originalZoned = Instant.ofEpochMilli(originalTimestamp)
+                .atZone(DEFAULT_ZONE);
+        // 提取时间部分:时、分、秒、纳秒(纳秒需转换为毫秒级精度)
+        int hour = originalZoned.getHour();
+        int minute = originalZoned.getMinute();
+        int second = originalZoned.getSecond();
+        int nanoOfSecond = originalZoned.getNano(); // 纳秒(1毫秒=1,000,000纳秒)
+        int milliOfSecond = nanoOfSecond / 1_000_000; // 取毫秒部分(0-999)
+
+
+        // 3. 获取当前日期(年月日)
+        LocalDate currentDate = LocalDate.now(DEFAULT_ZONE);
+
+
+        // 4. 组合新的日期时间:当前年月日 + 原时间的时分秒毫秒
+        LocalTime combinedTime = LocalTime.of(hour, minute, second, nanoOfSecond);
+        LocalDateTime combinedDateTime = LocalDateTime.of(currentDate, combinedTime);
+
+
+        // 5. 转换为新时间戳(毫秒)
+        return combinedDateTime.atZone(DEFAULT_ZONE)
+                .toInstant()
+                .toEpochMilli();
+    }
+
+    /**
+     * 获取指定时间戳当天0点0分0秒的时间戳(带时区处理)
+     * @param timestamp 指定时间戳(毫秒,如System.currentTimeMillis()返回值)
+     * @return 当天0点的时间戳(毫秒)
+     */
+    public Long getDayStartTimestamp(Long timestamp) {
+        // 校验参数合法性
+        if (timestamp == null || timestamp < 0) {
+            throw new IllegalArgumentException("时间戳无效(不能为null或负数)");
+        }
+        // 1. 将时间戳转换为带时区的日期时间
+        ZonedDateTime zonedDateTime = Instant.ofEpochMilli(timestamp)
+                .atZone(DEFAULT_ZONE);
+
+        // 2. 获取当天的起始时刻(00:00:00.000)
+        // atStartOfDay(zoneId) 会自动处理时区特殊情况(如夏令时切换)
+        ZonedDateTime dayStart = zonedDateTime.toLocalDate()
+                .atStartOfDay(DEFAULT_ZONE);
+
+        // 3. 转换为毫秒级时间戳
+        return dayStart.toInstant().toEpochMilli();
+    }
+}

--
Gitblit v1.9.3