动态格式化时间

203 阅读2分钟

需求

很多时候我们都需要对时间进行格式化的处理,不同的模块可能需要不同的时间格式甚至是不同的时间长度。

我认为最合理的处理时间的方式是在存储的时候存储时间戳,这样方便今后转换为任何时间格式,然后我简单封装了一个时间格式的处理方法,支持我们获取任意长度,任意格式的时间

格式时间

占位符描述示例
YYYY四位年份2023
MM两位月份(补零)03, 12
M月份(不补零)3, 12
DD两位日期(补零)05, 28
D日期(不补零)5, 28
hh两位小时(24小时制,补零)09, 23
h小时(24小时制,不补零)9, 23
mm两位分钟(补零)07, 59
m分钟(不补零)7, 59
ss两位秒钟(补零)03, 55
s秒钟(不补零)3, 55
w(小写)星期几0, 1, 2, 3, 4, 5, 6
W(大写)季度(中文表述,如“日, 一, 二”等,示例表述可能需结合实际场景规范,这里按原内容)日, 一, 二, 三, 四, 五, 六, 七
q(小写)季度1, 2, 3, 4
Q(大写)季度(中文表述,如“一, 二”等 )一, 二, 三, 四
t时间戳(毫秒)1678900000000

我们可以采取任何时间场地或任何形式进行拼接,例如:YYYY-MM-DD hh-mm-ss或者YYYY年MM月,该方法会自动识别其中的时间字段进行替换,从而保留其他拼接字符,注意不要使用代表时间格式的字符进行接

export const formatDate = (
  dateTemplate = "YYYY-MM-DD hh:mm:ss",
  date
) => {
  if (!date) {
    date = new Date();
  }
  // 中文星期映射表
  const WeekZhCnMap = {
    0: "日",
    1: "一",
    2: "二",
    3: "三",
    4: "四",
    5: "五",
    6: "六",
  };
  const QuarterZhCnMap = { 1: "一", 2: "二", 3: "三", 4: "四" }

  try {
    // 处理日期输入,转换为Date对象
    let targetDate;
    if (date instanceof Date) {
      targetDate = date;
    } else {
      targetDate = new Date(date);
    }

    // 检查日期有效性
    if (isNaN(targetDate.getTime())) {
      throw new Error("您传入的不是有效的日期格式!");
    }

    // 提取日期组件
    const year = targetDate.getFullYear();
    const month = targetDate.getMonth() + 1;
    const dateNum = targetDate.getDate();
    const hours = targetDate.getHours();
    const minutes = targetDate.getMinutes();
    const seconds = targetDate.getSeconds();
    const quarter = Math.floor(month / 3) + 1;
    const quarterZhCh = QuarterZhCnMap[quarter];
    const week = targetDate.getDay();
    const WeekZhCh = WeekZhCnMap[week];
    const stamp = targetDate.getTime();

    // 定义替换规则映射表
    const replacements = {
      YYYY: year,
      YY: String(year).slice(-2),
      MM: String(month).padStart(2, "0"),
      M: month,
      DD: String(dateNum).padStart(2, "0"),
      D: dateNum,
      hh: String(hours).padStart(2, "0"),
      h: hours,
      mm: String(minutes).padStart(2, "0"),
      m: minutes,
      ss: String(seconds).padStart(2, "0"),
      s: seconds,
      q: quarter, // 新增季度支持
      Q: quarterZhCh,
      w: week,
      W: WeekZhCh,
      t: stamp,
    };
    // 执行替换:根据映射表将模板中的占位符替换为实际值
    return Object.entries(replacements).reduce((str, [key, value]) => {
      return str.replace(new RegExp(key, "g"), value);
    }, dateTemplate);
  } catch (error) {
    console.error("日期格式化错误:", error.message);
    return '日期格式化错误: ' + error.message; // 明确返回null表示格式化失败
  }
};