您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Converts chat timestamps on milkywayidle.com from 12-hour AM/PM to 24-hour format, preserving the date if present.
// ==UserScript== // @name MilkyWayIdle 24hr Timestamps // @namespace http://tampermonkey.net/ // @version 1.1 // @description Converts chat timestamps on milkywayidle.com from 12-hour AM/PM to 24-hour format, preserving the date if present. // @author Opzon - Prompted on Gemini Pro // @match https://www.milkywayidle.com/* // @match https://test.milkywayidle.com/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; /** * Converts a 12-hour time string (e.g., "9:31:23 PM") to 24-hour format. * @param {string} time12hr - The 12-hour time string (e.g., "HH:MM:SS AM/PM"). * @returns {string} The 24-hour time string (e.g., "HH:MM:SS"). */ function convertTo24Hour(time12hr) { // We'll create a dummy date object to leverage Date's parsing and formatting capabilities. // The date part doesn't matter for the conversion of the time itself. const dummyDate = new Date(`2000/01/01 ${time12hr}`); if (isNaN(dummyDate.getTime())) { // If parsing failed, return original or an error indicator console.warn('Failed to parse time string for 24-hour conversion:', time12hr); return time12hr; } // Use toLocaleTimeString with appropriate options for 24-hour format const options = { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false // This is the key for 24-hour format }; // 'en-US' locale usually provides straightforward results return dummyDate.toLocaleTimeString('en-US', options); } /** * Processes a single timestamp span element, converting its content. * Handles both "[HH:MM:SS AM/PM]" and "[M/D HH:MM:SS AM/PM]" formats. * @param {HTMLElement} spanElement - The span element containing the timestamp. */ function processTimestampSpan(spanElement) { const originalText = spanElement.textContent; // Regex to capture the timestamp content inside brackets. // Group 1: Optional date part (e.g., "5/22"). The `?:` makes this a non-capturing group. // The inner `()` around `(\d{1,2}\/\d{1,2})` makes the date itself capturable as match[1]. // Group 2: The time part (e.g., "9:31:23 PM"). const match = originalText.match(/^\[(?:(\d{1,2}\/\d{1,2})\s+)?(\d{1,2}:\d{2}:\d{2} [AP]M)\]/); if (match) { const datePart = match[1]; // Will be undefined if no date was found const time12hr = match[2]; // This is the mandatory time part if (time12hr) { const time24hr = convertTo24Hour(time12hr); let newTimestampText = ''; if (datePart) { // If a date was present, reconstruct as "[M/D HH:MM:SS]" newTimestampText = `[${datePart} ${time24hr}]`; } else { // Otherwise, reconstruct as "[HH:MM:SS]" newTimestampText = `[${time24hr}]`; } spanElement.textContent = newTimestampText; } } } /** * Finds and processes all existing timestamp elements on the page. */ function processAllExistingTimestamps() { document.querySelectorAll('.ChatMessage_timestamp__1iRZO').forEach(processTimestampSpan); } // --- MutationObserver Setup --- // This will watch for new chat messages and whispers being added to the DOM. const observer = new MutationObserver((mutationsList) => { for (const mutation of mutationsList) { if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { mutation.addedNodes.forEach(addedNode => { // Check if the added node is an element and if it contains timestamps if (addedNode.nodeType === Node.ELEMENT_NODE) { // If the added node itself is a timestamp span if (addedNode.classList.contains('ChatMessage_timestamp__1iRZO')) { processTimestampSpan(addedNode); } // If the added node contains timestamp spans (e.g., a whole chat message div) addedNode.querySelectorAll('.ChatMessage_timestamp__1iRZO').forEach(processTimestampSpan); } }); } } }); // Start observing the document body for changes. // 'childList': true means observe direct children additions/removals. // 'subtree': true means observe changes in any descendant of the target node. observer.observe(document.body, { childList: true, subtree: true }); // Initial run: Process all timestamps that are already on the page when the script loads. processAllExistingTimestamps(); })();