skip to Main Content

I am trying to make a function that is, effectively, the opposite of getTime(); it takes a number of milliseconds as an input and converts the number into years, days, hours, seconds, and milliseconds, and then returns a Date object with those values. The conversion works perfectly, but when I try to create the Date object, things go wrong.

The code for the conversion itself is this:

function milliConvert(milliseconds){
const second = 1000;
    const minute = 1000 * 60;
    const hour = minute * 60;
    const day = hour * 24;
    const year = day * 365;
    let years2 = Math.floor(milliseconds / year);
    let days = Math.floor(milliseconds / day)-(years2*365);
    let hours = Math.floor((milliseconds / hour)-(((years2*365))*24+(days*24)));
    let minutes = Math.floor((milliseconds / minute)-(((years2*365))*24*60+60*(days*24)+((hours)*60)));
    let seconds= Math.floor((milliseconds / second)-((years2*365*24*60*60)+(days*24*60*60)+(hours*60*60)+(minutes*60)));
    let outMilli= Math.floor((milliseconds)-((years2*365*24*60*60)+(days*24*60*60)+(hours*60*60)+(minutes*60)+(seconds*1000)));
    console.log(years2+":"+days+":"+hours+":"+minutes+":"+seconds)
//the rest of this function is in the next code snippet

Like I said earlier, it works as expected. But I had to do a lot of troubleshooting with the code for converting it into a Date object, and it still doesn’t work.
My first iteration would always give me a large negative number, but I realized that that was because the years2 value was below 1970, so I made sure to increment it by 1970. After that, it still didn’t work, because the day and hour values had been, for some unknown reason, increased by 30 and 5 respectively. My current code for creating the date object is this:


return(new Date(years2+1970,1,days-30,hours-5,minutes,seconds,outMilli));
}

It works fine with smaller dates, but if I set milliseconds to Date.now(), the value of the date is "2078-08-14T17:48:43.764Z" (according to the VSCode console, when the command was run the time and date were 2024-04-27 15:29:03). My goal is for milliConvert(x).getTime() to equal X. I am aware that other people have answered similar questions before, but I would still like to know why this specifically doesn’t work, as I think it will help further my understanding of the Date object.
Thanks in advance!

2

Answers


  1. The Date class has a constructor that accepts a timestamp

    So you can just do new Date(milliseconds)

    Login or Signup to reply.
  2. Date calculations are more complex than one would expect at first glance. Given that your stated goal is "a better understanding", and not a practical replacement of the date object, I can show you some changes you can make to your code to help improve your understanding. Note that this will still produce incorrect results after the year 2100, so don’t treat it as anything production-worthy, but purely as an exercise in better understanding dates and times!

    function milliConvert(milliseconds){
        const second = 1000;
        const minute = 1000 * 60;
        const hour = minute * 60;
        const day = hour * 24;
        const year1 = day * 365;
        const year4 = day * 4 * 365 + day;
        let years4 = Math.floor(milliseconds / year4);
        let remains = milliseconds-years4*year4;
        let yearsIncludesLeapDay = (remains > year1 * 3 + day) ? 1 : 0;
        let years1 = Math.floor((remains-yearsIncludesLeapDay*day) / year1);
        remains -= years1*year1 + yearsIncludesLeapDay*day;
        let days = Math.floor(remains / day);
        remains -= days * day;
        let hours = Math.floor(remains / hour);
        remains -= hours * hour;
        let minutes = Math.floor(remains / minute);
        remains -= minutes * minute;
        let seconds = Math.floor(remains / second);
        let outMilli = remains - seconds * second;
        console.log((1970 + years4*4 + years1)+":"+days+":"+hours+":"+minutes+":"+seconds);
        console.log(new Date(milliseconds));
    }
    

    Note that because leap years between 1970 and 2100 occur every 4 years, we can treat each 4-year block as containing an extra day. Since 1970 is the starting point and 1972 was the first leap year in positive milliseconds, a leap day would exist in year 3 of your final block to calculate, so your years1 value takes a leap day into account only if the last block has at least 365*3+1 days in it.

    This breaks down at year 2100 because leap years occur every 4 years except for every 100 years unless the year is also divisible by 400. So, the year 2000 had a leap year but the year 2100 won’t.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search