您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
显示具体日期而不是“2 星期前”,“1 年前”这种
// ==UserScript== // @name 以绝对时间 (yyyy-mm-dd) 显示 YouTube 的视频上传日期 // @name:en Display YouTube video upload dates as absolute dates (yyyy-mm-dd) // @version 0.4.1 // @description 显示具体日期而不是“2 星期前”,“1 年前”这种 // @description:en Show full upload dates, instead of "1 year ago", "2 weeks ago", etc. // @author InMirrors // @namespace https://gf.qytechs.cn/users/518374 // @match https://www.youtube.com/* // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAACXBIWXMAAAsTAAALEwEAmpwYAAAEtklEQVR4nO2cTWhcVRTH/8Zq0YLVLjQuhPpBKv1QJKJx5pz3oGmgC1GsdCOoxGLFVdq6cCH4DYIuNLUouhCtLvzYVKugqKWaggtLjbTV4mdtrBVt1Yo10OD85b15E8YibSbvztx7k/ODA2EIw5zze2/m3nfvPYBhGIZhGIZhGIZhGIZhGIZhGIZhGA7hAOZR0MMEygSrWMUdTHAPBY9Q8DQVL1PwNhU7qNhJxV4qvs1D8BMVv+UhGKeCedT/rr+uODj5/4o9xXuMULGVis1UbKTgYQrWUzDIKm5iFcIKLmUfzopaNntxRp5IggEq7qLgcQpeoWI7BV9S8edk0UINwe+5dMGHuTDBYxTcSUE/BZcwxRyEAhUXFlfvluIKnfBeQG27oIki1y0UbGCK7s4Xvg8LqHhmVhRcTxnHKdhEwXmdKb7gCgq+DyBxBhWC75hiaXuLn+IyCn72nqwGGoJfWcGi9hR/Mc6kYLf3JDX4+DyrlXsB2Q+O/+QYSaxzW/zVOJ2CAwEkxkjiBwJd7gQorgkgKUYVFVztTkA2a/SdkEYWgvXuBCie856QRhfPuxMg+CiAhBhZjLgUYGN/bVGA4LC7p5f+ryZGGX1YUF5Aisu9J6KRRoKrygsQrPCaxKfvk7ctiVXAKhcCBr0mkTFxnHxjmFw5339RWwnBBhcC7vMuoMHRw+TwEJl2+S/u1GKjCwFPBSOgwb6d5N0V38U9dQheKy9A8VJwAjJqNXLb6+TNF4UsYJsLAVuDFNBg/C/yhQfJ5XNDFLDbhYAdQQto8OPX5P2rQxNwyIWAvVEIaBDSsDVbMwdOKytgf1QCQhu29uLscgLqm6HiEhDSsLXsbonsoVK0AkIYtpbdN0TF0egF+By2plhY9g4YnxECfA1by25ToeKfGSWg08PWKq40Af/H2Ffkvde3X0CCZfYV5HfmfHHZO2Dm/Ai/u5m8sbuzn/86nF/2DrBhqJYQMIB5s3ciduQQ+cRanxOxWukdcnE/ijjH3+eux7FSxS8E7InuYdyti30XvhEHXQgYiULAWIeGla3FaHkBgjeDFjAe8IKM4gMXAl4MUkDN07CylRC86kLAk8EJ2BfNovymmbUt5Yj3YWWrAh4oL0Bxu3cBE8EMK1sVMOjiDuj3msQn75C39Pgv5vQE9JcXUMEi74lopCHoKS/AtqdzmgJqpRfkJyXYAQ16mQVPCsi6nfi+nTWycLEtsUmAHdLTlgU8606AHVOl72OqdlBbWxbQ604A0JUfv/f9varRxH6nrQpyCfY1xCkLSDDktPi5gBRzKNgVwNXFwGM0653nXEAuIWvIZ3MCnqT4vziZ/Z5UQoqlRUtI31caA4tvWMWStha/ScK5ef/NrGGd/8TpObIaDHMF5nek+CeI6C4aoNbbVs4GIdLUtlKxjtfiAoRC/kOdYiEVy6lYQ8Wj+SlLwXv57grfm7x0SgX+g4IvTmjcujbvGBBa49bpwJWYW0iqMMEN+YJPgqFs9Shf/szWoOtX1/ai7fBnTa2LDzS1KD7WVLi/m1oajzW1Lh7N30PwMRVvFa2Lh6l46D+ti7M2yllHSFdPLw3DMAzDMAzDMAzDMAzDMAzDMAzDQJ1/AVPQr4Mf/K4RAAAAAElFTkSuQmCC // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; function getUploadDate() { let el = document.body.querySelector('player-microformat-renderer script'); if (el) { let parts = el.textContent.split('"startDate":"',2); if (parts.length == 2) { return parts[1].split('"',1)[0]; } parts = el.textContent.split('"uploadDate":"',2); if (parts.length == 2) { return parts[1].split('"',1)[0]; } } return null; } // Check if the video is a live broadcast function getIsLiveBroadcast() { let el = document.body.querySelector('player-microformat-renderer script'); if (!el) { return null; } let parts = el.textContent.split('"isLiveBroadcast":',2); if (parts.length != 2) { return false; } let isLiveBroadcast = !!parts[1].split(',',1)[0]; if (!isLiveBroadcast) { return false; } parts = el.textContent.split('"endDate":"',2); if (parts.length == 2) { return false; } return true; } // Extract video id from the URL function urlToVideoId(url) { let parts = url.split('/shorts/',2); if (parts.length === 2) { url = parts[1]; } else { url = parts[0]; } parts = url.split('v=',2); if (parts.length === 2) { url = parts[1]; } else { url = parts[0]; } return url.split('&',1)[0]; } // Retrieve the upload date from a remote source using the video id and invoke the callback with the result function getRemoteUploadDate(videoId, callback) { let body = {"context":{"client":{"clientName":"WEB","clientVersion":"2.20240416.01.00"}},"videoId":videoId}; fetch('https://www.youtube.com/youtubei/v1/player?prettyPrint=false', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { let object = data.microformat.playerMicroformatRenderer; if (object.liveBroadcastDetails?.isLiveNow) { callback(object.liveBroadcastDetails.startTimestamp); return; } else if (object.publishDate) { callback(object.publishDate); return; } callback(object.uploadDate); }) .catch(error => { console.error('There was a problem with the fetch operation:', error); }); } // Convert ISO date string to a localized date string function isoToDate(iso) { let date = new Date(iso); // let options = { day: 'numeric', month: 'short', year: 'numeric' }; // let lang = navigator.language ? navigator.language : 'en-US'; // change the locale to use yyyy-mm-dd format let options = { year: 'numeric', month: '2-digit', day: '2-digit', separator: '-' }; let lang = 'zh-CN'; return date.toLocaleDateString(lang, options).replaceAll('/', '-'); // another way to format the date // let year = date.getFullYear(); // let month = ("0" + (date.getMonth() + 1)).slice(-2); // Months are zero based // let day = ("0" + date.getDate()).slice(-2); // return `${year}-${month}-${day}`; // returns date in 'yyyy-mm-dd' format } /** * Process and update upload date info for a video element * @param {string} videoId - YouTube video ID * @param {HTMLElement} holder - DOM element that holds the date * @param {HTMLElement} container - Container with data-text attribute * @param {string} originalDateText - The original relative time text */ function fetchAndUpdateUploadDate(videoId, holder, container, originalDateText) { getRemoteUploadDate(videoId, (uploadDate) => { const formattedDate = isoToDate(uploadDate); let displayText; const oldUploadRegex = /days?|weeks?|months?|years?|天|周|週|月|年/; if (!oldUploadRegex.test(originalDateText)) { // Keep original + formatted date for recent uploads displayText = `${originalDateText} · ${formattedDate}`; } else { // Show only absolute date displayText = formattedDate; } holder.firstChild.nodeValue = displayText; container.setAttribute('data-text', displayText); }); } // Update the upload date and display style of video descriptions on the page function startTimers() { /* video page description */ setInterval(() => { // Retrieve the upload date let uploadDate = getUploadDate(); if (!uploadDate) { return; } // Format the date and check if it's a live broadcast uploadDate = isoToDate(uploadDate); let isLiveBroadcast = getIsLiveBroadcast(); if (isLiveBroadcast) { document.body.classList.add('ytud-description-live'); } else { document.body.classList.remove('ytud-description-live'); } // Update the upload date in the video description let el = document.querySelector('#info-container > #info > b'); if (!el) { let span = document.querySelector('#info-container > #info > span:nth-child(1)'); if (!span) { return; } el = document.createElement('b'); el.textContent = uploadDate; span.insertAdjacentElement('afterend', el); } else { if (el.parentNode.children[1] !== el) { let container = el.parentNode; el = container.removeChild(el); container.children[0].insertAdjacentElement('afterend', el); } if (el.firstChild.nodeValue === uploadDate) { return; } el.firstChild.nodeValue = uploadDate; } }, 1000); // More similar intervals for updating upload dates in various sections of the page /* video page sidebar list */ setInterval(() => { let vids = document.querySelectorAll('#items.ytd-watch-next-secondary-results-renderer ytd-compact-video-renderer'); if (vids.length === 0) { return; } vids.forEach((el) => { let holders = el.querySelectorAll('#metadata-line > span'); let holder; if (holders.length === 1) { let copy = document.createElement('span'); copy.className = 'inline-metadata-item style-scope ytd-video-meta-block'; let textNode = document.createTextNode(''); copy.appendChild(textNode); holders[0].insertAdjacentElement('afterend', copy); holder = copy; } else { holder = holders[1]; } let dateText = holder.firstChild.nodeValue; let text = el.getAttribute('data-text'); if (text !== null && text == dateText) { return; } el.setAttribute('data-text', dateText); let link = el.querySelector('a#thumbnail').getAttribute('href'); let videoId = urlToVideoId(link); fetchAndUpdateUploadDate(videoId, holder, el, dateText); }) }, 1000); /* homepage list - videos */ setInterval(() => { let vids = document.querySelectorAll('#content > ytd-rich-grid-media > #dismissible > #details > #meta > ytd-video-meta-block > #metadata'); if (vids.length === 0) { return; } vids.forEach((el) => { let holders = el.querySelectorAll('#metadata-line > span'); if (holders.length === 0) { return; } let holder; if (holders.length === 1) { let copy = document.createElement('span'); copy.className = 'inline-metadata-item style-scope ytd-video-meta-block'; let textNode = document.createTextNode(''); copy.appendChild(textNode); holders[0].insertAdjacentElement('afterend', copy); holder = copy; } else { holder = holders[1]; } let dateText = holder.firstChild.nodeValue; let text = el.getAttribute('data-text'); if (text !== null && text === dateText) { return; } el.setAttribute('data-text', dateText); let link = el.closest('#meta').querySelector('h3 > a#video-title-link').getAttribute('href'); let videoId = urlToVideoId(link); fetchAndUpdateUploadDate(videoId, holder, el, dateText); }) }, 1000); /* homepage list - shorts */ setInterval(() => { let vids = document.querySelectorAll('#content > ytd-rich-grid-slim-media > #dismissible > #details > ytd-video-meta-block > #metadata'); if (vids.length === 0) { return; } vids.forEach((el) => { let holders = el.querySelectorAll('#metadata-line > span'); if (holders.length === 0) { return; } let holder; if (holders.length === 1) { let copy = document.createElement('span'); copy.className = 'inline-metadata-item style-scope ytd-video-meta-block'; let textNode = document.createTextNode(''); copy.appendChild(textNode); holders[0].insertAdjacentElement('afterend', copy); holder = copy; } else { holder = holders[1]; } let dateText = holder.firstChild.nodeValue; let text = el.getAttribute('data-text'); if (text !== null && text === dateText) { return; } el.setAttribute('data-text', dateText); let link = el.closest('#details').querySelector('h3 > a').getAttribute('href'); let videoId = urlToVideoId(link); fetchAndUpdateUploadDate(videoId, holder, el, dateText); }) }, 1000); /* search list - videos */ setInterval(() => { let vids = document.querySelectorAll('#contents ytd-video-renderer #metadata'); if (vids.length === 0) { return; } vids.forEach((el) => { let holders = el.querySelectorAll('#metadata-line > span'); if (holders.length === 0) { return; } let holder; if (holders.length === 1) { let copy = document.createElement('span'); copy.className = 'inline-metadata-item style-scope ytd-video-meta-block'; let textNode = document.createTextNode(''); copy.appendChild(textNode); holders[0].insertAdjacentElement('afterend', copy); holder = copy; } else { holder = holders[1]; } let dateText = holder.firstChild.nodeValue; let text = el.getAttribute('data-text'); if (text !== null && text === dateText) { return; } el.setAttribute('data-text', dateText); let link = el.closest('#dismissible').querySelector('a#thumbnail').getAttribute('href'); let videoId = urlToVideoId(link); fetchAndUpdateUploadDate(videoId, holder, el, dateText); }) }, 1000); /* search list - shorts */ setInterval(() => { let vids = document.querySelectorAll('#scroll-container > #items > ytd-reel-item-renderer > #dismissible > #details > ytd-video-meta-block > #metadata'); if (vids.length === 0) { return; } vids.forEach((el) => { let holders = el.querySelectorAll('#metadata-line > span'); if (holders.length === 0) { return; } let holder; if (holders.length === 1) { let copy = document.createElement('span'); copy.className = 'inline-metadata-item style-scope ytd-video-meta-block'; let textNode = document.createTextNode(''); copy.appendChild(textNode); holders[0].insertAdjacentElement('afterend', copy); holder = copy; } else { holder = holders[1]; } let dateText = holder.firstChild.nodeValue; let text = el.getAttribute('data-text'); if (text !== null && text === dateText) { return; } el.setAttribute('data-text', dateText); let link = el.closest('#details').querySelector('h3 > a').getAttribute('href'); let videoId = urlToVideoId(link); fetchAndUpdateUploadDate(videoId, holder, el, dateText); }) }, 1000); /* search list - topic in sidebar */ setInterval(() => { let vids = document.querySelectorAll('#contents > ytd-universal-watch-card-renderer > #sections > ytd-watch-card-section-sequence-renderer > #lists > ytd-vertical-watch-card-list-renderer > #items > ytd-watch-card-compact-video-renderer'); if (vids.length === 0) { return; } vids.forEach((el) => { let holders = el.querySelectorAll('div.text-wrapper > yt-formatted-string.subtitle'); if (holders.length === 0) { return; } let holder = holders[0]; let separator = ' • '; let parts = holder.firstChild.nodeValue.split(separator, 2); if (parts.length < 2) { return; } let prefix = parts[0] + separator; let dateText = parts[1]; let text = el.getAttribute('data-text'); if (text !== null && text === dateText) { return; } el.setAttribute('data-text', dateText); let link = el.querySelector('a#thumbnail').getAttribute('href'); let videoId = urlToVideoId(link); fetchAndUpdateUploadDate(videoId, holder, el, dateText); }) }, 1000); /* channel page - home (featured video) */ setInterval(() => { let vids = document.querySelectorAll('#contents > ytd-channel-video-player-renderer > #content > #metadata-container > ytd-video-meta-block > #metadata'); if (vids.length === 0) { return; } vids.forEach((el) => { let holders = el.querySelectorAll('#metadata-line > span'); if (holders.length === 0) { return; } let holder = holders[1]; let dateText = holder.firstChild.nodeValue; let text = el.getAttribute('data-text'); if (text !== null && text === dateText) { return; } el.setAttribute('data-text', dateText); let link = el.closest('#metadata-container').querySelector('yt-formatted-string > a').getAttribute('href'); let videoId = urlToVideoId(link); fetchAndUpdateUploadDate(videoId, holder, el, dateText); }) }, 1000); /* channel page - home (for you videos) */ setInterval(() => { let vids = document.querySelectorAll('#dismissible > #details > #text-metadata > #meta > #metadata-container > #metadata'); if (vids.length === 0) { return; } vids.forEach((el) => { let holders = el.querySelectorAll('#metadata-line > span'); if (holders.length === 0) { return; } let holder; if (holders.length === 1) { let copy = document.createElement('span'); copy.className = 'style-scope ytd-grid-video-renderer'; let textNode = document.createTextNode(''); copy.appendChild(textNode); holders[0].insertAdjacentElement('afterend', copy); holder = copy; } else { holder = holders[1]; } let dateText = holder.firstChild.nodeValue; let text = el.getAttribute('data-text'); if (text !== null && text === dateText) { return; } el.setAttribute('data-text', dateText); let link = el.closest('#meta').querySelector('h3 > a#video-title').getAttribute('href'); let videoId = urlToVideoId(link); fetchAndUpdateUploadDate(videoId, holder, el, dateText); }) }, 1000); /* video playlist */ setInterval(() => { let vids = document.querySelectorAll('#content > #container > #meta > ytd-video-meta-block > #metadata > #byline-container'); if (vids.length === 0) { return; } vids.forEach((el) => { let holders = el.querySelectorAll('#video-info > span'); if (holders.length <= 1) { return; } let holder; let prefix = ''; if (holders.length === 2) { let copy = document.createElement('span'); copy.className = 'style-scope yt-formatted-string'; copy.setAttribute('dir', 'auto'); let textNode = document.createTextNode(''); copy.appendChild(textNode); holders[1].insertAdjacentElement('afterend', copy); holder = copy; prefix = ' • '; } else { holder = holders[2]; } let dateText = holder.firstChild.nodeValue; let text = el.getAttribute('data-text'); if (text !== null && text === dateText) { return; } el.setAttribute('data-text', dateText); let link = el.closest('#meta').querySelector('h3 > a').getAttribute('href'); let videoId = urlToVideoId(link); fetchAndUpdateUploadDate(videoId, holder, el, dateText); }) }, 1000); } startTimers() let styleTag = document.createElement('style'); let cssCode = "#info > span:nth-child(3) {display:none !important;}" + "#info > span:nth-child(4) {display:none !important;}" + "#info > b {font-weight:500 !important;margin-left:6px !important;}" + "#date-text {display:none !important;}" + ".ytud-description-live #info > span:nth-child(1) {display:none !important;}" + ".ytud-description-live #info > b {margin-left:0 !important;margin-right:6px !important;}"; styleTag.textContent = cssCode; document.head.appendChild(styleTag); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址