I make a countdown timer, the timer should start on the 1st day of the month, countdown for 3 days. After 3 days - run again. Every 1st day of the new month should be reset.

(function timer() { var today = new Date(); var start = new Date(2016, 3, 1); var end = new Date(today.getFullYear(), today.getMonth(), start.getDate() + 3); if ( today.getDate() == end.getDate() || today.getDate() == 1 ) { end.setDate( today.getDate() + 3 ); end.setHours(0, 0, 0, 0); } var differenceTime, dd, hh, mm, ss, str; differenceTime = end - new Date(); dd = parseInt( differenceTime / (1000 * 60 * 60 * 24) ); hh = parseInt( differenceTime / (60 * 60 * 1000) ) % 24; mm = parseInt( differenceTime / (1000 * 60) ) % 60; ss = parseInt( differenceTime / 1000 ) % 60; console.log(dd, hh, mm, ss); setTimeout(timer, 1000); })(); 

Here's what I got. But I'm not sure if I did the right thing. Please indicate errors.

    1 answer 1

    1. Error: The current month is written directly in the code. In May, this code will be disabled. We must take the current date and find out what month it is.

    2. the next end of the period: what comes first - the 1st day of the next month, or the next day of this month, a multiple of 3 + 1. Do not overlook the change of year.

    3. Finally, if you want a second countdown, note that the JS timer is very inaccurate: with setTimeout( ..., 1000) some seconds can be skipped. Therefore, it is better to set a lower value, and update the display of the remaining time more often.

     (function(){ var timer = function() { var today = new Date(), end = new Date(), dd, hh, mm, ss; end.setDate( 1 + Math.ceil(end.getDate()/3) * 3); // 1,4,7,.. if( end.getMonth() !== today.getMonth()) end.setDate(1); end.setHours(0); end.setMinutes(0); end.setSeconds(0); ss = Math.round((end.getTime() - today.getTime())/1000); // осталось, в секундах dd = Math.floor( ss / 86400); // суток ss -= dd * 86400; hh = Math.floor( ss / 3600); // часов ss -= hh * 3600; mm = Math.floor( ss / 60); // минут ss -= mm * 60; document.body.innerText = 'До ' + end.toString() +' '+ dd+' д. и ' + [ pad(hh), pad(mm), pad(ss)].join(':'); }; var pad = function(i) { return ('0' + i).slice(-2); }; window.setInterval(timer, 200); })(); 

    There is one mistake: if the day has already started, when the timer is reset, the end is incorrectly considered in the past: the beginning of the same day. Think about how to fix it.

    • Thank you for the answer. Could you fix my code? I just did not quite understand. - Aleksandr
    • Just take and do the job / training assignment for you? Not. What exactly do you not quite understand? - let me explain in more detail. - Sergiks
    • You wrote that you need to take the current date and find out what month it is. In my code: var end = new Date(today.getFullYear(), today.getMonth(), start.getDate() + 3); - The current date is taken, just when 3 days expire, another 3 days are added. And why find out the current month? - Aleksandr
    • It seems to have reached me. Take a look, please: jsbin.com/negerupufo/edit?js,output - Aleksandr
    • A month is needed in order not to get the 31st in February. Expressions start = new Date(2016, 3, 1); and start.getDate() + 3 do not make much sense, because start.getDate() is just a number 1 - you can just hold a variable with an integer value. - Sergiks