Discord Timestamp with Seconds

This script provides users with the capability to view seconds in the timestamps of Discord messages, allows users to view the time that has elapsed since a message was sent, and enhances the date formatting.

当前为 2024-07-22 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Discord Timestamp with Seconds
  3. // @namespace http://tampermonkey.net/
  4. // @version 3.3
  5. // @description This script provides users with the capability to view seconds in the timestamps of Discord messages, allows users to view the time that has elapsed since a message was sent, and enhances the date formatting.
  6. // @author Sam (and ChatGPT lol; yes, ChatGPT helped me with this. With the help of many others listed on the "History" section of the GreasyFork page of this script. (https://greasyfork.org/en/scripts/462588-discord-timestamp-with-seconds-and-date)
  7. // @match https://discord.com/*
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. // Function to format the timestamp with seconds
  16. function formatTimestampWithSeconds(datetime) {
  17. const date = new Date(datetime);
  18. const hours = date.getHours() % 12 || 12;
  19. const minutes = date.getMinutes().toString().padStart(2, '0');
  20. const seconds = date.getSeconds().toString().padStart(2, '0');
  21. const ampm = date.getHours() >= 12 ? 'PM' : 'AM';
  22. return `${hours}:${minutes}:${seconds} ${ampm}`;
  23. }
  24.  
  25. // Function to calculate the relative time
  26. function getRelativeTime(datetime) {
  27. const now = new Date();
  28. const date = new Date(datetime);
  29. const diff = now - date;
  30.  
  31. const seconds = Math.floor(diff / 1000);
  32. const minutes = Math.floor(seconds / 60);
  33. const hours = Math.floor(minutes / 60);
  34. const days = Math.floor(hours / 24);
  35. const weeks = Math.floor(days / 7);
  36. const months = Math.floor(days / 30);
  37. const years = Math.floor(days / 365);
  38.  
  39. if (seconds < 60) {
  40. return `${seconds} second${seconds !== 1 ? 's' : ''} ago`;
  41. } else if (minutes < 60) {
  42. return `${minutes} minute${minutes !== 1 ? 's' : ''} ago`;
  43. } else if (hours < 24) {
  44. return `${hours} hour${hours !== 1 ? 's' : ''} ago`;
  45. } else if (days < 7) {
  46. return `${days} day${days !== 1 ? 's' : ''} ago`;
  47. } else if (weeks < 4) {
  48. return `${weeks} week${weeks !== 1 ? 's' : ''} ago`;
  49. } else if (months < 12) {
  50. return `${months} month${months !== 1 ? 's' : ''} ago`;
  51. } else {
  52. return `${years} year${years !== 1 ? 's' : ''} ago`;
  53. }
  54. }
  55.  
  56. // Function to update timestamps
  57. function updateTimestamps() {
  58. const timeElements = document.querySelectorAll('time');
  59. timeElements.forEach(timeElement => {
  60. const datetime = timeElement.getAttribute('datetime');
  61. if (datetime) {
  62. const originalLabel = timeElement.getAttribute('aria-label');
  63. const formattedTime = formatTimestampWithSeconds(datetime);
  64. const relativeTime = getRelativeTime(datetime);
  65.  
  66. if (timeElement.parentElement.classList.contains('timestampVisibleOnHover_f9f2ca')) {
  67. // For hover timestamps, only show time without relative time
  68. timeElement.textContent = formattedTime;
  69. timeElement.setAttribute('aria-label', formattedTime);
  70. } else {
  71. // For normal timestamps, preserve the original format and add relative time
  72. if (!originalLabel.includes(formattedTime)) {
  73. timeElement.textContent = `${originalLabel.replace(/(\d+:\d+ [APM]{2})/, formattedTime)} (${relativeTime})`;
  74. timeElement.setAttribute('aria-label', `${originalLabel.replace(/(\d+:\d+ [APM]{2})/, formattedTime)} (${relativeTime})`);
  75. } else {
  76. // Update only the relative time
  77. const baseLabel = originalLabel.split(' (')[0];
  78. timeElement.textContent = `${baseLabel} (${relativeTime})`;
  79. timeElement.setAttribute('aria-label', `${baseLabel} (${relativeTime})`);
  80. }
  81. }
  82. }
  83. });
  84. }
  85.  
  86. // Observer to monitor DOM changes
  87. const observer = new MutationObserver(mutations => {
  88. for (const mutation of mutations) {
  89. if (mutation.type === 'childList' && mutation.addedNodes.length) {
  90. mutation.addedNodes.forEach(node => {
  91. if (node.nodeType === Node.ELEMENT_NODE) {
  92. const timeElements = node.querySelectorAll('time');
  93. timeElements.forEach(timeElement => {
  94. const datetime = timeElement.getAttribute('datetime');
  95. const originalLabel = timeElement.getAttribute('aria-label');
  96. if (datetime && originalLabel) {
  97. const formattedTime = formatTimestampWithSeconds(datetime);
  98. const relativeTime = getRelativeTime(datetime);
  99. if (timeElement.parentElement.classList.contains('timestampVisibleOnHover_f9f2ca')) {
  100. // For hover timestamps, only show time without relative time
  101. timeElement.textContent = formattedTime;
  102. timeElement.setAttribute('aria-label', formattedTime);
  103. } else {
  104. // For normal timestamps, preserve the original format and add relative time
  105. if (!originalLabel.includes(formattedTime)) {
  106. timeElement.textContent = `${originalLabel.replace(/(\d+:\d+ [APM]{2})/, formattedTime)} (${relativeTime})`;
  107. timeElement.setAttribute('aria-label', `${originalLabel.replace(/(\d+:\d+ [APM]{2})/, formattedTime)} (${relativeTime})`);
  108. } else {
  109. // Update only the relative time
  110. const baseLabel = originalLabel.split(' (')[0];
  111. timeElement.textContent = `${baseLabel} (${relativeTime})`;
  112. timeElement.setAttribute('aria-label', `${baseLabel} (${relativeTime})`);
  113. }
  114. }
  115. }
  116. });
  117. }
  118. });
  119. }
  120. }
  121. });
  122.  
  123. // Start observing the body for changes
  124. observer.observe(document.body, { childList: true, subtree: true });
  125.  
  126. // Refresh relative times every second
  127. setInterval(updateTimestamps, 1000);
  128.  
  129. // Initial timestamp update
  130. updateTimestamps();
  131.  
  132. })();