I’ve written a UserScript that formats GitHub’s relative time elements to show absolute dates with hours, minutes, and seconds - except in commit history views where relative dates are more useful.
The Problem
GitHub shows relative times like “2 hours ago” or “3 days ago” throughout the interface. While this works well for commit history where you want to understand the flow of changes, it’s less helpful for other areas like issue timestamps, PR creation dates, or release dates where absolute timestamps provide better context.
I’m aware of existing solutions like the GitHub Static Time userscripts, but they don’t give me the granular control I wanted - specifically the ability to keep relative dates in commit history while showing absolute dates everywhere else.
The Solution
Here’s the UserScript that handles this:
// ==UserScript==
// @name Format Relative Time Elements
// @namespace http://tampermonkey.net/
// @version 1.1
// @description Automatically format relative-time elements to show datetime with hours, minutes, and seconds
// @author Shane Dowling
// @match https://github.com/*
// @grant none
// @run-at document-idle
// ==/UserScript==
(function() {
'use strict';
function formatRelativeTimeElements() {
const elements = document.querySelectorAll("relative-time");
console.log(`Found ${elements.length} relative-time elements`);
elements.forEach(function (element) {
// Skip commit timestamps in the file/folder listing
if (element.closest('.react-directory-commit-age') ||
element.closest('.DirectoryContent-module__Table--DNJx9')) {
console.log('Skipping commit timestamp element');
return;
}
console.log('Processing element:', element);
console.log('Has shadowRoot:', !!element.shadowRoot);
// Try to format even without shadowRoot check first
try {
element.format = "datetime";
element.hour = "numeric";
element.minute = "2-digit";
element.second = "2-digit";
console.log('Applied formatting to element');
} catch (e) {
console.log('Error formatting element:', e);
}
});
}
// Multiple attempts to run the script
function tryFormat() {
formatRelativeTimeElements();
// Try again after a short delay in case elements aren't ready
setTimeout(formatRelativeTimeElements, 100);
setTimeout(formatRelativeTimeElements, 500);
setTimeout(formatRelativeTimeElements, 1000);
}
// Run immediately
tryFormat();
// Run when DOM is fully loaded
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', tryFormat);
}
// Run when page is fully loaded
window.addEventListener('load', tryFormat);
// Watch for dynamically added elements
const observer = new MutationObserver(function(mutations) {
let shouldUpdate = false;
mutations.forEach(function(mutation) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach(function(node) {
if (node.nodeType === Node.ELEMENT_NODE) {
if (node.tagName === 'RELATIVE-TIME' ||
(node.querySelector && node.querySelector('relative-time'))) {
shouldUpdate = true;
}
}
});
}
});
if (shouldUpdate) {
console.log('New relative-time elements detected, formatting...');
setTimeout(formatRelativeTimeElements, 10);
}
});
// Start observing when body is available
function startObserver() {
if (document.body) {
observer.observe(document.body, {
childList: true,
subtree: true
});
console.log('MutationObserver started');
} else {
setTimeout(startObserver, 100);
}
}
startObserver();
console.log('Relative time formatter userscript loaded');
})();
How It Works
The script targets GitHub’s <relative-time>
elements and modifies their formatting properties to show absolute dates. The key feature is the selective skipping logic:
// Skip commit timestamps in the file/folder listing
if (element.closest('.react-directory-commit-age') ||
element.closest('.DirectoryContent-module__Table--DNJx9')) {
return;
}
This ensures that commit timestamps in repository file listings maintain their relative format (“2 days ago”), which is more useful for understanding the recency of changes, while converting timestamps elsewhere to absolute format.
Installation
To use this UserScript:
- Install a userscript manager like Tampermonkey or Greasemonkey
- Copy the script above into a new userscript
- Save and enable it
The script will automatically run on GitHub pages and includes multiple timing strategies and a MutationObserver to handle GitHub’s dynamic content loading.
Benefits
- Selective formatting: Keeps relative dates where they’re useful (commit history) while showing absolute dates elsewhere
- Detailed timestamps: Shows hours, minutes, and seconds for precise timing
- Dynamic compatibility: Works with GitHub’s single-page application behavior
- GitHub-specific: Runs only on GitHub for focused functionality
This gives me exactly the control I wanted over GitHub’s timestamp display without losing the contextual benefits of relative dates in commit history.