function padLeft(val, len) {
  return String(val).padStart(len || 2, "0");
}
function dateTimeFormat(date, opts) {
  return new Intl.DateTimeFormat("en-US", opts).format(date);
}
function getOrdinalSuffix(day) {
  if (day > 3 && day < 21) {
    return "th";
  }
  switch (day % 10) {
    case 1:
      return "st";
    case 2:
      return "nd";
    case 3:
      return "rd";
    default:
      return "th";
  }
}
function timezone(date, together) {
  let offset = date.getTimezoneOffset();
  let prefix;
  if (offset <= 0) {
    prefix = "+";
    offset = Math.abs(offset);
  } else {
    prefix = "-";
  }
  return `${prefix}${padLeft(Math.floor(offset / 60))}${together ? "" : ":"}${padLeft(Math.floor(offset % 60))}`;
}
const FORMAT_MAP = {
  // 年份
  yyyy: (d) => d.getFullYear(),
  YYYY: (d) => d.getFullYear(),
  YY: (d) => padLeft(d.getFullYear() % 100),
  // 月份
  MMMM: (d) => dateTimeFormat(d, { month: "long" }),
  MMM: (d) => dateTimeFormat(d, { month: "short" }),
  MM: (d) => padLeft(d.getMonth() + 1),
  M: (d) => d.getMonth() + 1,
  // 日期
  DD: (d) => padLeft(d.getDate()),
  D: (d) => d.getDate(),
  Do: (d) => {
    const day = d.getDate();
    return String(day) + getOrdinalSuffix(day);
  },
  // 星期
  dddd: (d) => dateTimeFormat(d, { weekday: "long" }),
  ddd: (d) => dateTimeFormat(d, { weekday: "short" }),
  dd: (d) => dateTimeFormat(d, { weekday: "narrow" }),
  // 时间
  HH: (d) => padLeft(d.getHours()),
  H: (d) => d.getHours(),
  hh: (d) => padLeft(d.getHours() % 12 || 12),
  h: (d) => d.getHours() % 12 || 12,
  mm: (d) => padLeft(d.getMinutes()),
  m: (d) => d.getMinutes(),
  ss: (d) => padLeft(d.getSeconds()),
  s: (d) => d.getSeconds(),
  SSS: (d) => padLeft(d.getMilliseconds(), 3),
  // 其他
  A: (d) => d.getHours() >= 12 ? "PM" : "AM",
  a: (d) => d.getHours() >= 12 ? "pm" : "am",
  Z: (d) => timezone(d),
  ZZ: (d) => timezone(d, true)
};
const tokens = Object.keys(FORMAT_MAP).sort((a, b) => b.length - a.length).join("|");
const pattern = new RegExp(
  `${tokens}|\\[([^\\]]*)]`,
  "g"
);
function format(date, formatString) {
  if (!formatString || formatString === "ISO") {
    return date.toISOString();
  }
  return formatString.replace(pattern, (match, escapeContent) => {
    if (escapeContent) {
      return escapeContent;
    }
    const formatter = FORMAT_MAP[match];
    return formatter ? formatter(date) : match;
  });
}
export {
  format as default
};
