Full Date format for Youtube

Show full upload dates in DD/MM/YYYY HH:MMam/pm format

当前为 2024-11-13 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name              Full Date format for Youtube
// @version           0.4.5
// @description       Show full upload dates in DD/MM/YYYY HH:MMam/pm format
// @author            Ignacio Albiol
// @namespace         https://greasyfork.org/en/users/1304094
// @match             https://www.youtube.com/*
// @iconURL           https://seekvectors.com/files/download/youtube-icon-yellow-01.jpg
// @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;
    }

    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;
    }

    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];
    }

    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);
        });
    }

    function isoToDate(iso) {
        let date = new Date(iso);

        // Format date components
        let day = ("0" + date.getDate()).slice(-2);
        let month = ("0" + (date.getMonth() + 1)).slice(-2);
        let year = date.getFullYear();

        // Format time components
        let hours = date.getHours();
        let minutes = ("0" + date.getMinutes()).slice(-2);
        let ampm = hours >= 12 ? 'pm' : 'am';

        // Convert hours to 12-hour format
        hours = hours % 12;
        hours = hours ? hours : 12; // Convert 0 to 12

        // Combine all components
        return `${day}/${month}/${year} ${hours}:${minutes}${ampm}`;
    }

    function startTimers() {
        /* video page description */
        setInterval(() => {
            let uploadDate = getUploadDate();
            if (!uploadDate) {
                return;
            }

            uploadDate = isoToDate(uploadDate);
            let isLiveBroadcast = getIsLiveBroadcast();

            if (isLiveBroadcast) {
                document.body.classList.add('ytud-description-live');
            } else {
                document.body.classList.remove('ytud-description-live');
            }

            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);

        /* 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);
                getRemoteUploadDate(videoId, (uploadDate) => {
                    uploadDate = isoToDate(uploadDate);
                    holder.firstChild.nodeValue = uploadDate;
                    el.setAttribute('data-text', uploadDate);
                });
            })
        }, 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);
                getRemoteUploadDate(videoId, (uploadDate) => {
                    uploadDate = isoToDate(uploadDate);
                    holder.firstChild.nodeValue = uploadDate;
                    el.setAttribute('data-text', uploadDate);
                });
            })
        }, 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);
                getRemoteUploadDate(videoId, (uploadDate) => {
                    uploadDate = isoToDate(uploadDate);
                    holder.firstChild.nodeValue = uploadDate;
                    el.setAttribute('data-text', uploadDate);
                });
            })
        }, 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);
                getRemoteUploadDate(videoId, (uploadDate) => {
                    uploadDate = isoToDate(uploadDate);
                    holder.firstChild.nodeValue = uploadDate;
                    el.setAttribute('data-text', uploadDate);
                });
            })
        }, 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);
                getRemoteUploadDate(videoId, (uploadDate) => {
                    uploadDate = isoToDate(uploadDate);
                    holder.firstChild.nodeValue = uploadDate;
                    el.setAttribute('data-text', uploadDate);
                });
            })
        }, 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);
                getRemoteUploadDate(videoId, (uploadDate) => {
                    uploadDate = isoToDate(uploadDate);
                    holder.firstChild.nodeValue = prefix + uploadDate;
                    el.setAttribute('data-text', uploadDate);
                });
            })
        }, 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);
                getRemoteUploadDate(videoId, (uploadDate) => {
                    uploadDate = isoToDate(uploadDate);
                    holder.firstChild.nodeValue = uploadDate;
                    el.setAttribute('data-text', uploadDate);
                });
            })
        }, 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);
                getRemoteUploadDate(videoId, (uploadDate) => {
                    uploadDate = isoToDate(uploadDate);
                    holder.firstChild.nodeValue = uploadDate;
                    el.setAttribute('data-text', uploadDate);
                });
            })
        }, 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);
                getRemoteUploadDate(videoId, (uploadDate) => {
                    uploadDate = prefix + isoToDate(uploadDate);
                    holder.firstChild.nodeValue = uploadDate;
                    el.setAttribute('data-text', uploadDate);
                });
            })
        }, 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);
})();