Files
timi-utils/src/main/java/com/imyeyu/utils/Time.java
T
Timi 3fb1363d8e
CI/CD / build-deploy (pull_request) Successful in 11s
v0.0.13
2026-08-11 23:55:18 +08:00

370 lines
8.9 KiB
Java

package com.imyeyu.utils;
import com.imyeyu.java.TimiJava;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 时间转换相关
*
* @author 夜雨
* @version 2021-06-10 20:07
*/
public class Time {
// ---------- 格式化 ----------
/** 格式化 yy */
public static final SimpleDateFormat year = new SimpleDateFormat("yy");
/** 格式化 yyyy */
public static final SimpleDateFormat yearFull = new SimpleDateFormat("yyyy");
/** 格式化 M */
public static final SimpleDateFormat month = new SimpleDateFormat("M");
/** 格式化 MM */
public static final SimpleDateFormat monthFull = new SimpleDateFormat("MM");
/** 格式化 d */
public static final SimpleDateFormat day = new SimpleDateFormat("d");
/** 格式化 dd */
public static final SimpleDateFormat dayFull = new SimpleDateFormat("dd");
/** 格式化 HH */
public static final SimpleDateFormat hour = new SimpleDateFormat("HH");
/** 格式化 mm */
public static final SimpleDateFormat minute = new SimpleDateFormat("mm");
/** 格式化 ss */
public static final SimpleDateFormat second = new SimpleDateFormat("ss");
/** 格式化 hh:mm */
public static final SimpleDateFormat hhmm = new SimpleDateFormat("HH:mm");
/** 格式化 mm:ss */
public static final SimpleDateFormat mmss = new SimpleDateFormat("mm:ss");
/** 格式化 yyyyMMdd */
public static final SimpleDateFormat ymd = new SimpleDateFormat("yyyyMMdd");
/** 格式化 HH:mm:ss.SSS */
public static final SimpleDateFormat log = new SimpleDateFormat("[HH:mm:ss.SSS]");
/** 格式化 HH:mm:ss.SSS */
public static final SimpleDateFormat longLog = new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss.SSS]");
/** 格式化 yyyy-MM-dd */
public static final SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd");
/** 格式化 HH:mm:ss */
public static final SimpleDateFormat time = new SimpleDateFormat("HH:mm:ss");
/** 格式化 yyyy-MM-dd HH:mm:ss */
public static final SimpleDateFormat dateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/** 格式化 yyyy-MM-dd'T'HH:mm:ss */
public static final SimpleDateFormat dateTimeT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
/** 格式化 yyyy-MM-dd HH:mm:ss */
public static final SimpleDateFormat serialize = new SimpleDateFormat("yyyyMMddHHmmss");
// ---------- 长整型时间戳 ----------
/** 1 秒时间戳 */
public static final long S = 1000;
/** 1 分钟时间戳 */
public static final long M = S * 60;
/** 1 小时时间戳 */
public static final long H = M * 60;
/** 1 天时间戳 */
public static final long D = H * 24;
// ---------- 整型时间戳 ----------
/** 1 秒时间戳(整型) */
public static final int SI = 1000;
/** 1 分钟时间戳(整型) */
public static final int MI = SI * 60;
/** 1 小时时间戳(整型) */
public static final int HI = MI * 60;
/** 1 天时间戳(整型) */
public static final int DI = HI * 24;
/**
* 获取此刻毫秒
*
* @return 毫秒
*/
public static long now() {
return System.currentTimeMillis();
}
/**
* 获取当前时间 yyyy-MM-dd HH:mm:ss
*
* @return 当前时间
*/
public static String nowString() {
return toDateTime(new Date());
}
/**
* 获取昨天零时时间戳
*
* @return 昨天零时时间戳
*/
public static long yesterday() {
return yesterday(now());
}
public static long yesterday(long time) {
return today(time) - D;
}
/**
* 获取今天零时时间戳
*
* @return 今天零时时间戳
*/
public static long today() {
return today(now());
}
public static long today(long time) {
return Instant.ofEpochMilli(time).atZone(ZoneId.systemDefault()).toLocalDate().atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
/**
* 获取明天零时时间戳
*
* @return 明天零时时间戳
*/
public static long tomorrow() {
return tomorrow(now());
}
public static long tomorrow(long time) {
return today(time) + D;
}
/**
* 转义为日期 yyyy-MM-dd
*
* @param unixTime 时间戳
* @return 日期字符串
*/
public static String toDate(long unixTime) {
return date.format(unixTime);
}
/**
* 转义为时间 HH:mm:ss
*
* @param unixTime 时间戳
* @return 时间字符串
*/
public static String toTime(long unixTime) {
return time.format(unixTime);
}
/**
* 转义为日期时间 yyyy-MM-dd HH:mm:ss
*
* @param unixTime 时间戳
* @return 日期时间字符串
*/
public static String toDateTime(long unixTime) {
return dateTime.format(unixTime);
}
/**
* 转义为日期时间 yyyy-MM-dd HH:mm:ss
*
* @param date 时间对象
* @return 日期时间字符串
*/
public static String toDateTime(Date date) {
return dateTime.format(date);
}
/**
* 本地时间对象转时间戳(本地时区)
*
* @param date 本地日期对象
* @return 时间戳
*/
public static Long fromLocalDate(LocalDate date) {
if (date == null) {
return null;
}
return date.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
/**
* 本地时间对象转时间戳(本地时区)
*
* @param dateTime 本地日期对象
* @return 时间戳
*/
public static Long fromLocalDateTime(LocalDateTime dateTime) {
if (dateTime == null) {
return null;
}
return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
/**
* 时间戳转本地日期(本地时区)
*
* @param unixTime 时间戳
* @return 本地日期对象
*/
public static LocalDateTime toLocalDateTime(Long unixTime) {
if (unixTime == null) {
return null;
}
return Instant.ofEpochMilli(unixTime).atZone(ZoneId.systemDefault()).toLocalDateTime();
}
/**
* 将时间字符串解析为毫秒值
*
* <p>支持的格式示例:
* <pre>
* 10 = 10
* 10ms = 10
* 10s = 10,000
* 10m = 600,000
* 10h = 36,000,000
* 10d = 10D = 10 d = 864,000,000
* 10.5d = 907,200,000
* </pre>
*
* @param timeStr 时间字符串
* @return 毫秒
* @throws IllegalArgumentException 输入格式无效
*/
public static long parseToMS(String timeStr) {
if (TimiJava.isEmpty(timeStr)) {
throw new IllegalArgumentException("not found timeStr");
}
String normalized = timeStr.replaceAll("\\s+", "").toLowerCase();
Pattern pattern = Pattern.compile("^(\\d+(?:\\.\\d+)?)(ms|[dhms])?$");
Matcher matcher = pattern.matcher(normalized);
if (!matcher.matches()) {
throw new IllegalArgumentException("invalid format: " + timeStr);
}
double value = Double.parseDouble(matcher.group(1));
String unit = matcher.group(2);
if (TimiJava.isEmpty(unit) || unit.equals("ms")) {
return Math.round(value);
}
double multiplier = switch (unit) {
case "s" -> Time.S;
case "m" -> Time.M;
case "h" -> Time.H;
case "d" -> Time.D;
default -> throw new IllegalArgumentException("invalid format unit: " + unit);
};
return Math.round(value * multiplier);
}
/**
* 媒体时间操作
*
* @author 夜雨
* @version 2023-01-24 01:10
*/
public static class Media {
private static final Pattern PATTERN = Pattern.compile("(\\d*):?([0-5]\\d):([0-5]\\d)\\.?(\\d{1,3})?");
/**
* 解析字符串为毫秒,匹配 999:59:59.999 格式,兼容 999:59:59
*
* @param time 时间字符串
* @return 毫秒
*/
public static long fromString(String time) {
if (TimiJava.isEmpty(time)) {
return 0;
}
Matcher matcher = PATTERN.matcher(time);
if (matcher.find()) {
long h = 0;
if (TimiJava.isNotEmpty(matcher.group(1))) {
h = Long.parseLong(matcher.group(1));
}
long m = Long.parseLong(matcher.group(2));
long s = Long.parseLong(matcher.group(3));
long ms = 0;
if (TimiJava.isNotEmpty(matcher.group(4))) {
String gms = matcher.group(4);
ms = Long.parseLong(gms);
if (gms.length() == 2) {
ms *= 10;
}
}
return h * Time.H + m * Time.M + s * Time.S + ms;
}
return 0;
}
/**
* 秒转媒体时间,00:00:00
*
* @param second 秒
* @return 时间字符串
*/
public static String toString(double second) {
return toString((int) second);
}
/**
* 秒转媒体时间,00:00:00
*
* @param second 秒
* @return 时间字符串
*/
public static String toString(int second) {
int h = second / 60 / 60;
if (0 < h) {
return String.format("%d:%02d:%02d", h, second / 60 - h * 60, second % 60);
} else {
return String.format("%02d:%02d", second / 60, second % 60);
}
}
/**
* 毫秒转媒体时间,音视频播放时间,00:00:00.000
*
* @param millis 毫秒
* @return 时间字符串
*/
public static String toString(long millis) {
long s = millis / 1000;
long h = s / 60 / 60;
return String.format("%d:%02d:%02d.%03d", h, s / 60 - h * 60, s % 60, millis % 1000);
}
}
}