-
-
Save PantheraRed/2e65c48cdfa6fba49473913300cc8b12 to your computer and use it in GitHub Desktop.
'use strict'; // Remove this if you don't wish to use strict mode | |
function ms(t) { | |
let year, | |
month, | |
day, | |
hour, | |
minute, | |
second; | |
second = Math.floor(t / 1000); | |
minute = Math.floor(second / 60); | |
second = second % 60; | |
hour = Math.floor(minute / 60); | |
minute = minute % 60; | |
day = Math.floor(hour / 24); | |
hour = hour % 24; | |
month = Math.floor(day / 30); | |
day = day % 30; | |
year = Math.floor(month / 12); | |
month = month % 12; | |
return { year, month, day, hour, minute, second }; | |
} | |
module.exports = ms; | |
// Usage: ms(1627297964704) returns { year: 52, month: 3, day: 24, hour: 11, minute: 12, second: 44 } |
@PantheraRed Sure! So calculating the time duration between two dates is a bit sticky. Especially if they are far apart from each other. In your specific ms()
function this can easily deviate in months of errors.
Background story & idea
Again, that is because a timestamp by itself isn't really easy to convert directly to a year, months and day of a difference. At least not accurately. After all, not every year as the same amount of days. And not every month has the same amount of days.
You could try to use the math that is explained here for longeterm
conversion accuracy (but it will never be a golden solution, but might improve the accuracy):
https://github.com/moment/luxon/blob/master/docs/math.md#casual-vs-longterm-conversion-accuracy
(See the table)
My current Solution
Currently I'm using the Luxon library instead, with two Luxon DateTime objects and then using the diff()
method.
An example for a date: 2012-03-13 6:30:24 PM UTC, see ISO string below. This would result in 1331663424000
epoch timestamp in milliseconds. I will later come back to this epoch timestamp.
const { DateTime } = require('luxon'); // Importing Luxon
const start = DateTime.fromISO('2012-03-13T18:30:24.000Z'); // Just an example time from the past, using the ISO standard
const end = DateTime.now(); // Current time
const diff = end.diff(start, ['years', 'months', 'days', 'hours', 'minutes', 'seconds', 'milliseconds'])
// Let's print the difference object to a Javascript object: https://moment.github.io/luxon/api-docs/index.html#datetimetoobject
console.log(diff.toObject())
This should give you the following JS object in the console (this is correct. You can count the years, months and days manually if you would like):
{
years: 10,
months: 9,
days: 21,
hours: 3,
minutes: 27,
seconds: 38,
milliseconds: 389
}
Using the diff()
from Luxon is the only way to have a result really accurately and thus correct.
Bonus - Testing your function
Let's compare that to your function. I will first calculate the diff of 1331663424000
with the current timestamp in ms, that would be:
Date.now() - 1331663424000
That results into: 341119598771
. Now I will use your function using the 341119598771
as input:
ms(341119598771)
Your function returns:
{ year: 10, month: 11, day: 18, hour: 3, minute: 26, second: 38 }
That is an error of around 2 months!?
I hope this helps you and others.
@Danger89 Thank you for such a great explanation. This will definitely help me improve the gist in future. I personally found luxon a better alternative.
As I stated in my explanation, I'm using Luxon now.
Hello @Danger89, mind elaborating? Would like to correct this gist. :)