日期格式转换

将多种英文日期格式转换为“年月日”格式

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==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();
})();