Discussions » Creation Requests

User script for changing relative timestamps to absolute timestamps?

§
Posted: 2021-03-14

Greetings, Greasyfork community! I was wondering if there was a possibility of designing a userscript that could convert relative timestamps to absolute timestamps for various sites. I was specifically looking at tsn.ca/nhl as an example, where stories are often listed as being "15m ago" or "1h ago" instead of an absolute 12-hour format such as "4:32" or "6:11".

My search of Greasyfork only found one similar script (https://greasyfork.org/en/scripts/1036-what-cd-relative-to-absolute-time), however that appeared to only be specific to an old website. I also found similar scripts on StackExchange (https://stackapps.com/questions/2528/display-absolute-timestamps-in-local-time) and (https://stackapps.com/questions/7379/regional-12-hour-timestamps), but they appeared to only be for StackApps websites.

I would definitely appreciate guidance on this topic!

§
Posted: 2021-03-15

I have visited the website and I did not find any precise timestamps. How can you make "12-hour format such as 4:32" if all what you see is approximate values?

Such as

  • *m ago - minutes
  • *h ago - hours
  • Mar 13 - some day
§
Posted: 2021-03-15

Your request doesn't make sense.

Do you want to convert
13 minutes ago
to something like
today hour:minute:secs
?

I personally think that 13 minutes ago is much better than hour:minute:sec

§
Posted: 2021-03-15

Yes, I was hoping for something along the lines of hour:minute rather than the relative timestamps. I suppose it might be inaccurate for values greater than one hour ago...but even if it could be done for values less than one hour ago I'd be interested.

I know different people prefer different things. I've read a lot of debates on the Internet about relative vs absolute timestamps and there's camps of people that prefer either one, so I thought it might be possible with a userscript. Thanks for considering!

§
Posted: 2021-03-15
Edited: 2021-03-15

That seems to be kind of easy to do, the most complex thing would be to create a regex to correctly match this...

The problem is that probably any minute/minutes/hour/hours words would be changed to your local time, that's why it's kind off not good to do this

§
Posted: 2021-03-15

I'd be totally fine with it working in local time! If anything it's an interesting experiment and might give me a way to learn a little more about Javascript by studying the code. I've had some dabbles in C++ and R in college but it's been a while and Javascript is a bit of a different language.

Thanks again for your consideration! If there is a way to adapt it to other websites as well I know there is definitely a class of people on the Internet that might prefer it, strange though it may seem.

§
Posted: 2021-03-17

// ==UserScript==
// @name Change relative timestamps to absolute timestamps (Not correctly working yet)
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Change relative timestamps to absolute timestamps.
// @author hacker09
// @include *
// @grant none
// @run-at document-end
// ==/UserScript==

(function() {
'use strict';
var now= new Date();
var result = [];

(function scanSubTree(node){
if(node.childNodes.length)
for(var i = 0; i < node.childNodes.length; i++)
scanSubTree(node.childNodes[i]);
else if(node.nodeType == Node.TEXT_NODE)
result.push(node);
})(document);

result.forEach(function(node){
node.nodeValue = node.nodeValue.replace(/\d+ ? ?days? ?ago|\d+ ? ?hours? ?ago|\d+ ? ?hrs? ?ago|\d+ ? ?minutes? ?ago|\d+ ? ?m ?ago|\d+ ? ?mins? ?ago/g, now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds());
});

})();

§
Posted: 2021-03-17
Edited: 2021-03-17

For now it just replaces the relative timestamps with your actual local time (The conversion isn't correct at all)

But please use it for a while, so you can understand how it will look/work like.

Also I obviously don't know how every single website on the internet displays their relative timestamps, so sometimes the script will be unable to detect/match the relative time stamps, on these cases please send the me text or website that didn't work/(wasn't matched)

§
Posted: 2021-03-19

Thanks for the update! Something like that would definitely work great!

So I guess the remaining challenge then is to find a way to subtract from the current local time based on the relative timestamp? So in the specific case of tsn.ca/nhl, it would be finding a way to subtract anything to the left of the "m" in minutes from the local time?

§
Posted: 2021-03-19
Edited: 2021-03-19

The math is very easy to do because I already did it in some of my scripts, the hard part is to detect when its minutes or hours and how to get the number only, but I can do this too.

The truly hardest thing will be related to time zones... I might be wrong but I guess that I need to know what's your local time zone...

Please open this
https://jsfiddle.net/0v7Ly843/
and tell me if the hours and minutes are correct or not.

§
Posted: 2021-03-24

Sorry for the late reply - the time there is correct, although it is in "military time". So it shows 22:52 right now even though my time is 10:52pm at the moment.

§
Posted: 2021-03-25
Edited: 2021-03-25

Keep in mind that I haven't added support for years ago in the script.
The script will display the dates and time even if the relative timestamp text didn't have dates or didn't have time in hours/minutes.
In case the timestamp text doesn't have minutes/hours the script will just show your current local time. (I could easily make the script not show your local time, but I don't know if you want this or not, so I didn't make the script hide your local time)

Even if the relative timestamp text doesn't have days in it, the script will just show your actual local month/day/year too. (I could easily make the script not show your local date, but I don't know if you want this or not, so I didn't make the script hide your date)



// ==UserScript==
// @name Change relative timestamps to absolute timestamps
// @namespace RelativeTimestampsTOAbsolute
// @version 0.2
// @description Change relative timestamps to absolute timestamps.
// @author hacker09
// @include *
// @grant none
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
//Set the variables below
var now = new Date();
var result = [];
//***************************************************************************************************************************************************************************
//Start the function to correctly format the date and time
function formatDateTime(date) { //Starts the function
var year = date.getFullYear(); //Get the actual year
var month = date.getMonth() + 1; //Get the actual month
var day = date.getDate(); //Get the actual date
var hh = date.getHours(); //Get the actual hours
var m = date.getMinutes(); //Get the actual minutes
var s = date.getSeconds(); //Get the actual seconds
var dd = "AM";
var h = hh;

if (h >= 12) {
h = hh - 12;
dd = "PM";
}
if (h == 0) {
h = 12;
}

month = month < 10 ? "0" + month : month;
day = day < 10 ? "0" + day : day;
m = m < 10 ? "0" + m : m;
s = s < 10 ? "0" + s : s;
h = h < 10 ? "0" + h : h;

var display = month + "/" + day + "/" + year + " " + h + ":" + m;
display += ":" + s;
display += " " + dd;

return display; //Returns the formated results
} //Finishes the function
//***************************************************************************************************************************************************************************
//Start the function to scan the page for text nodes
(function scanSubTree(node) { //Get all page nodes
if (node.childNodes.length) //For all page nodes child nodes
for (var i = 0; i < node.childNodes.length; i++) //For all page nodes child nodes
scanSubTree(node.childNodes[i]);
else if (node.nodeType == Node.TEXT_NODE) //If the node is a text type node
result.push(node); //Add the node to the result array
})(document);

//Start the codes to correctly match the relative date and time timestamps
var Regex = new RegExp('\\d+ ? ?days? ?ago|\\d+ ? ?hours? ?ago|\\d+ ? ?hrs? ?ago|\\d+ ? ?minutes? ?ago|\\d+ ? ?m ?ago|\\d+ ? ?mins? ?ago', 'gi'); //Regex to match days,hrs,mins
var NodeText, NodeDays, NodeHours, NodeMinutes; //Create new global blank variables

result.forEach(function(node) { //For each text node in the result array
if (node.nodeValue.match(Regex) !== null) { //If the text node matches the regex
NodeText = node.nodeValue.match(Regex)[0]; //Add the whole text node to a variable

if (NodeText.match(/days?/gi) !== null) { //If the text node has days
NodeDays = parseInt(node.nodeValue.match(Regex)[0].match(/\d+/)[0]); //Add the days number to a variable
} //Finishes the if condition
if (NodeText.match(/hours?|hrs?/gi) !== null) { //If the text node has hours
NodeHours = parseInt(node.nodeValue.match(Regex)[0].match(/\d+/)[0]); //Add the hours number to a variable
} //Finishes the if condition
if (NodeText.match(/minutes?|mins?|m/gi) !== null) { //If the text node has minutes
NodeMinutes = parseInt(node.nodeValue.match(Regex)[0].match(/\d+/)[0]); //Add the minutes number to a variable
} //Finishes the if condition
//***************************************************************************************************************************************************************************
//Start the function to correctly subtract the relative date and time timestamps from the actual date and time
var hoursStart = now.getHours(); //Get the actual hours
var minutesStart = now.getMinutes(); now.getHours(); //Get the actual mins
var daysEnd = NodeDays; //Get the relative timestamp days number
var hoursEnd = NodeHours; //Get the relative timestamp hours number
var minutesEnd = NodeMinutes; //Get relative timestamp minutes number
var amPMStart = 'PM'; //Set the actual time as PM
var hours24FormatStart = hoursStart; //Add the actual hours to another variable

if ((amPMStart == "PM" && hoursStart < 12) || (amPMStart == "AM" && hoursStart == 12)) { //If actual hours is AM or PM and it's on the 24 hours timezones
hours24FormatStart = hoursStart + 12; //Convert from 24 hrs to max 12 hrs only
} //Finishes the if condition

function convertToZero(field) { //Creates a new function to convert nan values to 0
if (isNaN(field)) { //If the value is nan
return 0; //Make the value be 0
} //Finishes the if condition
return field; //Return our new modified value
} //Finishes the function

daysEnd = convertToZero(daysEnd); //Check and convert nan values to 0
hoursEnd = convertToZero(hoursEnd); //Check and convert nan values to 0
minutesEnd = convertToZero(minutesEnd); //Check and convert nan values to 0

var start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hours24FormatStart, minutesStart);
var end = daysEnd * 60 * 60 * 24 + hoursEnd * 60 * 60 + minutesEnd * 60;

start.setSeconds(start.getSeconds() - end);
//***************************************************************************************************************************************************************************
node.nodeValue = NodeText.replace(Regex, formatDateTime(start)); //For all relative timestamp node texts on the page, change the relative timestamp to absolute
} //Finishes the if conditon
}); //Finishes the foreach conditon
})();

§
Posted: 2021-03-26

Awesome - thanks again for the update! This looks really cool and must have taken a fair amount of time to work on. Some minor things I'm noticing:

1. The time for "hours ago" seems to be slightly off by around 12 minutes for some reason. For example, right now it's 1:36am my time (I'm in EST if it matters) and your post is showing up as "Edited: 03/24/2021 07:23:00 AM". I'm sure "hours ago" is never going to be exactly accurate, though.

2. Sometimes there are relative timestamps for "sec ago" or "s ago" - can that be added too? I might even be able to deduce how to add it myself given your template.

§
Posted: 2021-03-26

Just using this page as a test - right now it is 1:43am my time, but my comment is showing up as "Posted: 03/24/2021 07:37:00 AM" even though it says I wrote it "6 minutes ago".

I know the minute will always vary a little bit depending on how many seconds have passed since the current - that's totally fine! I was just curious if I'm doing something wrong on my end for it to be off in terms of the hour. I copied/pasted it exactly into Tampermonkey.

§
Posted: 2021-03-26

Also, one last thing - it looks like the script is specifically set to look for the word "ago", but in the case of sites like tsn.ca/nhl the timestamps simply show up as "4m" or "4h". So, it doesn't appear the script is recognizing it as a timestamp. I was realllly hoping that this script would work for that, so is there a way to adjust for that?

I'm guessing the extra challenge there would be to identify a substring where there's a number next to an "m" or "h" as opposed to regular text? And it probably would mean that some regular text, such as something about the company 3M, could get changed...but I can live with that risk haha.

Again, greatly appreciate your help and I'm definitely learning a lot of things studying the script!

§
Posted: 2021-03-27
Edited: 2021-03-27
1. The time for "hours ago" seems to be slightly off by around 12 minutes for some reason.

I don't really know why either, and I don't think that I will keep working on this so I will probably never figure out why this bug is happening, but I migt consider one day to return here and give a look into it.

2. "sec ago" or "s ago" - can that be added too

Yes, but I doubt I will...
You will need to give a look into this to add secs
https://pastebin.com/N9wSD3NJ

I didn't notice that hours bug either, but it's the same thing I told you above for the minutes bug.

So, it doesn't appear the script is recognizing it as a timestamp. I was realllly hoping that this script would work for that, so is there a way to adjust for that?

Just erase the words "ago" on this line

var Regex = new RegExp('\\d+ ? ?days? ?ago|\\d+ ? ?hours? ?ago|\\d+ ? ?hrs? ?ago|\\d+ ? ?minutes? ?ago|\\d+ ? ?m ?ago|\\d+ ? ?mins? ?ago', 'gi'); //Regex to match days,hrs,mins


I'm guessing the extra challenge there would be to identify a substring where there's a number next to an "m" or "h" as opposed to regular text?

Just erase the words "ago" as I said and this will work as you want.

§
Posted: 2021-03-27
Edited: 2021-03-27

You will also need to give a look into this too to add secs

https://pastebin.com/wFVuexL2

§
Posted: 2021-03-31

Thanks for your help - in the case of tsn.ca/nhl, adjusting the Regex to look for ?h? ?ago instead of ?hrs? ?ago? worked! The extra thing was to add "|h?" to the NodeText that checked for hours. So instead of "(NodeText.match(/hours?|hrs?/gi)", changing to "(NodeText.match(/hours?|hrs?|h/gi)" makes the script pick it up.

I'll still have to play around with it to see if I can figure out why it's off by a little bit or why the AM/PM is flipped. I could always look on other sites or play around on W3Schools. If I can figure it out I'll post here or if you get a chance to look that would be great, but I can understand if you don't want to spend more time on it as well. Thanks!

Post reply

Sign in to post a reply.