// ==UserScript==
// @name 日期格式转换
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 将多种英文日期格式转换为“年月日”格式
// @author Akirami
// @license MIT
// @match *://*/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
// 正则表达式匹配常见日期格式
const dateRegexList = [
/\b(\d{1,2})\/(\d{1,2})\/(\d{4})\b/g, // 18/11/2024
/\b(\d{1,2})\s(\w+)\s(\d{4})\b/g, // 18 November 2024
/\b(\w+)\s(\d{1,2}),\s(\d{4})\b/g // November 18, 2024
];
// 英文月份与数字映射
const monthMap = {
January: 1, Jan: 1,
February: 2, Feb: 2,
March: 3, Mar: 3,
April: 4, Apr: 4,
May: 5,
June: 6, Jun: 6,
July: 7, Jul: 7,
August: 8, Aug: 8,
September: 9, Sep: 9,
October: 10, Oct: 10,
November: 11, Nov: 11,
December: 12, Dec: 12
};
// 替换函数,根据正则匹配的日期格式处理
function replaceDate(match, p1, p2, p3, regexIndex) {
switch (regexIndex) {
case 0: // 18/11/2024
return `${p3}年${parseInt(p1)}月${parseInt(p2)}日`;
case 1: // 18 November 2024
return `${p3}年${monthMap[p2]}月${parseInt(p1)}日`;
case 2: // November 18, 2024
return `${p3}年${monthMap[p1]}月${parseInt(p2)}日`;
}
}
// 使用 TreeWalker 遍历文本节点
function processTextNodes(root) {
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false);
let node;
while ((node = walker.nextNode())) {
let textContent = node.textContent;
let modified = false;
dateRegexList.forEach((regex, index) => {
if (regex.test(textContent)) {
textContent = textContent.replace(regex, (match, p1, p2, p3) =>
replaceDate(match, p1, p2, p3, index)
);
modified = true;
}
});
// 只有在内容变化时更新节点,减少不必要的 DOM 修改
if (modified) {
node.textContent = textContent;
}
}
}
// 对页面的所有文本节点进行处理
function processPage() {
processTextNodes(document.body);
}
// 监听动态内容变化,仅处理新增或更改的部分
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
processTextNodes(node);
} else if (node.nodeType === Node.TEXT_NODE) {
let textContent = node.textContent;
let modified = false;
dateRegexList.forEach((regex, index) => {
if (regex.test(textContent)) {
textContent = textContent.replace(regex, (match, p1, p2, p3) =>
replaceDate(match, p1, p2, p3, index)
);
modified = true;
}
});
if (modified) {
node.textContent = textContent;
}
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
// 初始处理
processPage();
})();