findme-miniprogram-frontend/utils/formatDate.js
2025-12-27 17:16:03 +08:00

197 lines
6.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 工具函数:格式化日期
// 参数:
// - date: 可传入 时间戳毫秒、Date对象、日期字符串如 "2024-09-12"
// - format: 格式化模板(默认 "YYYY-MM-DD"
function formatDate(date, format = "YYYY-MM-DD") {
// 处理输入:统一转为 Date 对象
if (!date) {
date = new Date(); // 默认当前时间
} else if (typeof date === "number") {
date = new Date(date); // 时间戳转 Date
} else if (typeof date === "string") {
date = new Date(date); // 日期字符串转 Date
}
// 处理无效日期
if (isNaN(date.getTime())) {
console.error("无效的日期格式");
return "";
}
// 提取日期部分
const year = date.getFullYear();
const month = date.getMonth() + 1; // 月份从 0 开始,需 +1
const day = date.getDate();
const hour = date.getHours();
const minute = date.getMinutes();
const second = date.getSeconds();
// 补零函数(将 1 转为 "01"
const padZero = (num) => String(num).padStart(2, "0");
// 替换格式模板
return format
.replace("YYYY", year)
.replace("MM", padZero(month))
.replace("DD", padZero(day))
.replace("HH", padZero(hour))
.replace("mm", padZero(minute))
.replace("ss", padZero(second));
}
/**
* 计算n年前的日期
* @param {number} n - 年前数如1表示1年前2表示2年前
* @param {Date|number|string} [baseDate] - 基准日期(可选,默认当前日期)
* @returns {Date} 计算后的Date对象
*/
function getNYearsAgo(n, baseDate) {
// 处理基准日期(默认当前日期)
let date;
if (!baseDate) {
date = new Date(); // 默认以今天为基准
} else if (typeof baseDate === 'number') {
date = new Date(baseDate); // 时间戳转Date
} else if (typeof baseDate === 'string') {
date = new Date(baseDate); // 日期字符串转Date
} else {
date = new Date(baseDate); // 传入Date对象
}
// 校验日期有效性
if (isNaN(date.getTime())) {
console.error('无效的基准日期');
return null;
}
// 获取基准日期的年、月、日
const year = date.getFullYear();
const month = date.getMonth(); // 月份从0开始0=1月11=12月
const day = date.getDate();
// 计算n年前的年份
const targetYear = year - n;
// 创建目标日期(直接设置年份)
const targetDate = new Date(targetYear, month, day);
// 特殊情况处理如果目标日期的月份与原月份不一致如2月29日跨年到非闰年
if (targetDate.getMonth() !== month) {
// 说明原日期在目标年份中不存在如2024-02-29 → 2023年没有2月29日
// 自动调整为目标月份的最后一天
targetDate.setDate(0); // setDate(0) 表示上个月的最后一天
}
return targetDate;
}
/**
* 根据出生日期计算年龄
* @param {string|Date} birthDate - 出生日期(支持字符串如"1990-05-15"或Date对象
* @returns {number} 年龄如28若日期无效则返回-1
*/
function calculateAge(birthDate) {
// 处理出生日期输入转为Date对象
let birth;
if (birthDate instanceof Date) {
birth = birthDate;
} else if (typeof birthDate === 'string') {
birth = new Date(birthDate);
} else {
console.error('出生日期格式错误');
return -1;
}
// 校验出生日期有效性
if (isNaN(birth.getTime())) {
console.error('无效的出生日期');
return -1;
}
// 获取当前日期和出生日期的年/月/日
const today = new Date();
const birthYear = birth.getFullYear();
const birthMonth = birth.getMonth(); // 月份从0开始0=1月
const birthDay = birth.getDate();
const currentYear = today.getFullYear();
const currentMonth = today.getMonth();
const currentDay = today.getDate();
// 计算年份差(初步年龄)
let age = currentYear - birthYear;
// 调整年龄若今年生日尚未过则年龄减1
if (
currentMonth < birthMonth || // 当前月份 < 出生月份 → 生日未过
(currentMonth === birthMonth && currentDay < birthDay) // 同月份但当前日期 < 出生日期 → 生日未过
) {
age--;
}
// 年龄不能为负数(如出生日期在未来)
return age < 0 ? 0 : age;
}
/**
* 根据生日计算星座
* @param {number|string} month - 月份1-12
* @param {number|string} day - 日期1-31
* @returns {string} 星座名称,如"白羊座"、"金牛座"等
*/
function calculateConstellation(month, day) {
// 确保 month 和 day 是数字类型
const m = typeof month === 'string' ? parseInt(month, 10) : month;
const d = typeof day === 'string' ? parseInt(day, 10) : day;
// 验证输入
if (!m || !d || m < 1 || m > 12 || d < 1 || d > 31) {
return '';
}
// 根据月份和日期判断星座
if ((m === 3 && d >= 21) || (m === 4 && d <= 19)) return "白羊座";
if ((m === 4 && d >= 20) || (m === 5 && d <= 20)) return "金牛座";
if ((m === 5 && d >= 21) || (m === 6 && d <= 21)) return "双子座";
if ((m === 6 && d >= 22) || (m === 7 && d <= 22)) return "巨蟹座";
if ((m === 7 && d >= 23) || (m === 8 && d <= 22)) return "狮子座";
if ((m === 8 && d >= 23) || (m === 9 && d <= 22)) return "处女座";
if ((m === 9 && d >= 23) || (m === 10 && d <= 23)) return "天秤座";
if ((m === 10 && d >= 24) || (m === 11 && d <= 22)) return "天蝎座";
if ((m === 11 && d >= 23) || (m === 12 && d <= 21)) return "射手座";
if ((m === 12 && d >= 22) || (m === 1 && d <= 19)) return "摩羯座";
if ((m === 1 && d >= 20) || (m === 2 && d <= 18)) return "水瓶座";
return "双鱼座";
}
/**
* 根据生日字符串计算星座
* @param {string} birthday - 生日字符串格式YYYY-MM-DD
* @returns {string} 星座名称,如"白羊座"、"金牛座"等
*/
function calculateConstellationFromBirthday(birthday) {
if (!birthday || typeof birthday !== 'string') {
return '';
}
try {
const parts = birthday.split('-');
if (parts.length !== 3) {
return '';
}
const month = parseInt(parts[1], 10);
const day = parseInt(parts[2], 10);
return calculateConstellation(month, day);
} catch (error) {
console.error('计算星座失败:', error);
return '';
}
}
module.exports = {
formatDate: formatDate,
getNYearsAgo: getNYearsAgo,
calculateAge: calculateAge,
calculateConstellation: calculateConstellation,
calculateConstellationFromBirthday: calculateConstellationFromBirthday
}