149 lines
4.8 KiB
JavaScript
149 lines
4.8 KiB
JavaScript
import dayjs from 'dayjs';
|
||
|
||
/**
|
||
* 将时间字符串格式化为时间对象
|
||
* @param {string} timeStr - 时间字符串,格式:2025/09/03 04:05:40
|
||
* @returns {Date} 时间对象
|
||
*/
|
||
function parseTimeString(timeStr) {
|
||
// 支持多种分隔符
|
||
const normalizedStr = timeStr.replace(/[\/\-]/g, '/');
|
||
return new Date(normalizedStr);
|
||
}
|
||
|
||
/**
|
||
* 将时间对象格式化为指定格式的字符串
|
||
* @param {Date} date - 时间对象
|
||
* @param {string} format - 格式字符串,如:yyyy-MM-dd HH:MM:ss
|
||
* 注意:MM 在日期部分(yyyy-MM-dd)表示月份,在时间部分(HH:MM)表示分钟
|
||
* @returns {string} 格式化后的时间字符串
|
||
*/
|
||
function formatTime(date, format) {
|
||
const year = date.getFullYear();
|
||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||
const day = String(date.getDate()).padStart(2, '0');
|
||
const hours = String(date.getHours()).padStart(2, '0');
|
||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||
|
||
// 使用临时占位符避免 MM 冲突
|
||
// 先处理日期部分的 MM(在 yyyy 和 dd 之间的 MM 表示月份)
|
||
let result = format.replace(/(yyyy-)(MM)(-dd)/g, '$1__MONTH__$3');
|
||
|
||
// 再处理时间部分的 MM(在 HH 之后的 MM 表示分钟)
|
||
result = result.replace(/(HH:)(MM)/g, '$1__MINUTE__');
|
||
|
||
// 替换所有其他标记
|
||
result = result.replace(/yyyy/g, year);
|
||
result = result.replace(/dd/g, day);
|
||
result = result.replace(/HH/g, hours);
|
||
result = result.replace(/mm/g, month); // 小写 mm 始终表示月份
|
||
result = result.replace(/ss/g, seconds);
|
||
|
||
// 最后替换临时占位符
|
||
result = result.replace(/__MONTH__/g, month);
|
||
result = result.replace(/__MINUTE__/g, minutes);
|
||
|
||
// 处理剩余的 MM(如果还有,默认表示月份)
|
||
result = result.replace(/MM/g, month);
|
||
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* 计算两个时间对象的时间差(不返回秒)
|
||
* @param {Date} time1 - 开始时间
|
||
* @param {Date} time2 - 结束时间
|
||
* @returns {string} 时间差描述,如:4小时 或 4小时10分钟
|
||
*/
|
||
function calculateTimeRange(time1, time2) {
|
||
// 确保time2晚于time1,否则交换
|
||
let startTime = time1;
|
||
let endTime = time2;
|
||
|
||
if (time1 > time2) {
|
||
startTime = time2;
|
||
endTime = time1;
|
||
}
|
||
|
||
const diffMs = endTime - startTime;
|
||
const diffMinutes = Math.floor(diffMs / (1000 * 60));
|
||
const diffHours = Math.floor(diffMinutes / 60);
|
||
const remainingMinutes = diffMinutes % 60;
|
||
|
||
let result = '';
|
||
|
||
if (diffHours > 0) {
|
||
result += `${diffHours}小时`;
|
||
}
|
||
|
||
if (remainingMinutes > 0) {
|
||
if (result) result += ' ';
|
||
result += `${remainingMinutes}分钟`;
|
||
}
|
||
|
||
// 如果时间差为0,返回0分钟
|
||
if (!result) {
|
||
return '0分钟';
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* 判断给定日期是今天、明天还是后天
|
||
* @param {string|number|Date|dayjs} input - 目标日期,可以是时间戳、日期字符串、Date 对象等
|
||
* @returns {string} - 返回 '今天' | '明天' | '后天' | '其他'
|
||
*/
|
||
function getDayDescription(input) {
|
||
|
||
|
||
if (input == null || input == "" || input == 0) {
|
||
return "请选择时间";
|
||
}
|
||
const target = dayjs(input); // 解析输入日期
|
||
const today = dayjs().startOf('day'); // 今天的 00:00:00
|
||
const tomorrow = today.add(1, 'day'); // 明天的 00:00:00
|
||
const dayAfterTomorrow = today.add(2, 'day'); // 后天的 00:00:00
|
||
|
||
let tips = "";
|
||
if (target.isSame(today, 'day')) {
|
||
tips = '(今天)';
|
||
} else if (target.isSame(tomorrow, 'day')) {
|
||
tips = '(明天)';
|
||
} else if (target.isSame(dayAfterTomorrow, 'day')) {
|
||
tips = '(后天)';
|
||
} else {
|
||
tips = '';
|
||
}
|
||
return target.format('MM-DD ' + tips + ' HH:mm')
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 将传入的时间的分钟数 向上取整到最近的 5 的倍数
|
||
* 比如:1 → 5,6 → 10,58 → 00(且进位到下一小时),59 → 00(进位)
|
||
* @param {Date|number|string|dayjs} inputTime - 可以是时间戳、Date 对象、ISO 字符串、dayjs 对象
|
||
* @returns {dayjs} 返回调整后的 dayjs 对象,分钟是 5 的倍数,且进位正确
|
||
*/
|
||
function ceilMinuteToNext5(inputTime) {
|
||
const t = dayjs(inputTime) // 支持多种时间格式
|
||
|
||
const m = t.minute()
|
||
const s = t.second()
|
||
|
||
// 向上取整到最近的 5 的倍数
|
||
const nextMin = Math.ceil(m / 5) * 5
|
||
|
||
if (nextMin === 60) {
|
||
// 59 → 60 → 变成下一小时的 00 分
|
||
return t.add(1, 'hour').minute(0).second(0)
|
||
}
|
||
|
||
// 否则正常设置分钟,并清空秒
|
||
return t.minute(nextMin).second(0)
|
||
}
|
||
|
||
export { parseTimeString, formatTime, calculateTimeRange, getDayDescription, ceilMinuteToNext5 }
|