import { dismantleDate } from '../../utils/common';
/**
* 友好的时间显示
* @author lz-freedom <https://github.com/lz-freedom>
* @category time
* @alias time_friendlyDateStr
* @param {string|Date|number} sTime 待格式化的时间, 可传递时间戳(秒、毫秒)、日期对象、日期字符串(YYYY-MM-DD HH:mm:SS)
* @param {string} type 类型 normal | blur | full | ymd | other
* @returns {string|null} 格式化后的字符串
*
* @example
* // 示例: 刚刚
* console.log(time_friendlyDateStr('2024-08-02 10:36:30', 'normal')) // 输出: 刚刚
*
* @example
* // 示例: 1分钟前
* console.log(time_friendlyDateStr('2024-08-02 10:35:30', 'normal')) // 输出: 1分钟前
*
* @example
* // 示例: 3小时前
* console.log(time_friendlyDateStr('2024-08-02 07:35:30', 'blur')) // 输出: 3小时前
*/
export default (sTime, type = 'normal') => {
if (!sTime) {
console.error('Unknown time format.');
return null;
}
// 处理各种类型的时间
let date;
switch (typeof sTime) {
case 'number':
// 秒级时间戳转毫秒级
if (sTime.toString().length === 10) {
sTime *= 1000;
}
date = new Date(sTime);
break;
case 'string':
const regexMapping = {
'YYYY-MM-DD HH:mm:SS': /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/
};
const match = sTime.match(regexMapping['YYYY-MM-DD HH:mm:SS']);
if (!match) {
console.error('Invalid Time string.');
return null;
}
date = new Date(sTime);
break;
case 'object':
if (!(sTime instanceof Date) || isNaN(sTime.getTime())) {
console.error('Invalid Date object.');
return null;
}
date = sTime;
break;
default:
console.error('Unknown time format.');
return null;
}
// 计算时间差
const cTimestamp = Math.floor(Date.now() / 1000); // 当前时间戳(单位:秒)
const sTimestamp = Math.floor(date.getTime() / 1000); // 源时间戳(单位:秒)
const dTimestamp = cTimestamp - sTimestamp; // 时间差
const sDate = new Date(sTimestamp * 1000);
const cDate = new Date(cTimestamp * 1000);
const dDay = Math.floor((cDate - sDate) / (24 * 3600 * 1000)); // 日期差
const dYear = cDate.getFullYear() - sDate.getFullYear(); // 年份差
// 精确的时间显示
if (type === 'normal') {
if (dTimestamp < 60) {
if (dTimestamp < 10) {
return '刚刚';
} else {
return `${Math.floor(dTimestamp / 10) * 10}秒前`;
}
} else if (dTimestamp < 3600) {
return `${Math.floor(dTimestamp / 60)}分钟前`;
} else if (dYear === 0 && dDay === 0) {
return `今天${sDate.getHours()}:${sDate.getMinutes()}`;
} else if (dYear === 0) {
const { year, month, day, hours, minutes, seconds } = dismantleDate(sDate);
return `${sDate.getMonth() + 1}月${sDate.getDate()}日 ${hours}:${minutes}:${seconds}`;
} else {
const { year, month, day, hours, minutes, seconds } = dismantleDate(sDate);
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
}
// 相对模糊的时间显示
if (type === 'blur') {
if (dTimestamp < 60) {
return `${dTimestamp}秒前`;
} else if (dTimestamp < 3600) {
return `${Math.floor(dTimestamp / 60)}分钟前`;
} else if (dTimestamp >= 3600 && dDay === 0) {
return `${Math.floor(dTimestamp / 3600)}小时前`;
} else if (dDay > 0 && dDay <= 7) {
return `${dDay}天前`;
} else if (dDay > 7 && dDay <= 30) {
return `${Math.floor(dDay / 7)}周前`;
} else if (dDay > 30) {
return `${Math.floor(dDay / 30)}个月前`;
}
}
// 完整的时间显示
if (type === 'full') {
const { year, month, day, hours, minutes, seconds } = dismantleDate(sDate);
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
// 年月日的时间显示
if (type === 'ymd') {
const { year, month, day } = dismantleDate(sDate);
return `${year}-${month}-${day}`;
}
// 兜底显示
if (dTimestamp < 60) {
return `${dTimestamp}秒前`;
} else if (dTimestamp < 3600) {
return `${Math.floor(dTimestamp / 60)}分钟前`;
} else if (dTimestamp >= 3600 && dDay === 0) {
return `${Math.floor(dTimestamp / 3600)}小时前`;
} else {
const { year, month, day, hours, minutes, seconds } = dismantleDate(sDate);
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
};