您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Converts IMVU Pacific timestamps to local time with optional manual offset and 24-hour toggle
// ==UserScript== // @name IMVU Dev Report Local Time // @namespace https://example.local/ // @version 2.0 // @description Converts IMVU Pacific timestamps to local time with optional manual offset and 24-hour toggle // @match https://www.imvu.com/catalog/developer_report.php* // @grant GM_registerMenuCommand // @grant GM_getValue // @grant GM_setValue // ==/UserScript== (function () { 'use strict'; const IMVU_TZ = 'America/Los_Angeles'; const DATETIME_RE = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/; let force24h = GM_getValue('imvu_force24h', true); let manualOffsetHours = GM_getValue('imvu_manualOffsetHours', 0); const pacificDtf = new Intl.DateTimeFormat('en-US', { timeZone: IMVU_TZ, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }); function pad(n) { return String(n).padStart(2, '0'); } function formatLocalISO(d) { return ( d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()) + ' ' + pad(d.getHours()) + ':' + pad(d.getMinutes()) + ':' + pad(d.getSeconds()) ); } function pacificToLocal(s) { const [datePart, timePart] = s.split(' '); if (!datePart || !timePart) return s; const [y, mo, d] = datePart.split('-').map(Number); const [hh, mm, ss] = timePart.split(':').map(Number); // epoch0 = treat the components as if UTC const epoch0 = Date.UTC(y, mo - 1, d, hh, mm, ss); // Map epoch0 into Pacific wall time const parts = pacificDtf.formatToParts(new Date(epoch0)); const obj = {}; for (const p of parts) if (p.type !== 'literal') obj[p.type] = p.value; const asUTC = Date.UTC( +obj.year, +obj.month - 1, +obj.day, +obj.hour, +obj.minute, +obj.second ); const tzOffsetMs = asUTC - epoch0; const pacificEpoch = epoch0 - tzOffsetMs; // Apply manual adjustment const correctedEpoch = pacificEpoch + manualOffsetHours * 3600 * 1000; const localDate = new Date(correctedEpoch); return force24h ? formatLocalISO(localDate) : localDate.toLocaleString(); } function convertOnce() { document.querySelectorAll('td.pi_data').forEach(td => { const txt = (td.dataset.imvuOriginal || td.textContent || '').trim(); if (!DATETIME_RE.test(txt)) return; if (!td.dataset.imvuOriginal) td.dataset.imvuOriginal = txt; const orig = td.dataset.imvuOriginal; const localStr = pacificToLocal(orig); td.textContent = localStr; td.title = `IMVU (Pacific): ${orig} → Local: ${localStr} (offset: ${manualOffsetHours}h)`; }); } function toggle24h() { force24h = !force24h; GM_setValue('imvu_force24h', force24h); convertOnce(); alert(`24-hour ISO format: ${force24h ? 'ON' : 'OFF'}`); } function adjustOffset(delta) { manualOffsetHours += delta; GM_setValue('imvu_manualOffsetHours', manualOffsetHours); convertOnce(); alert(`Manual offset now: ${manualOffsetHours} hours`); } function resetOffset() { manualOffsetHours = 0; GM_setValue('imvu_manualOffsetHours', 0); convertOnce(); alert(`Manual offset reset to 0 hours`); } function registerMenus() { GM_registerMenuCommand( `Toggle 24-hour ISO (currently: ${force24h ? 'ON' : 'OFF'})`, toggle24h ); GM_registerMenuCommand('Convert IMVU times now', convertOnce); GM_registerMenuCommand(`Current offset: ${manualOffsetHours}h`, () => {}); GM_registerMenuCommand('Offset +1h', () => adjustOffset(1)); GM_registerMenuCommand('Offset -1h', () => adjustOffset(-1)); GM_registerMenuCommand('Reset offset', resetOffset); } registerMenus(); convertOnce(); })();