0

What we need:

example Customer start date is 11th March 2019 - 28 working days equals to 18th April , the 18th April becomes the month 1 end date, Month 2 start date is 18th April (month 1 end date + 1) which is equal to 19th April, then month 2 end date is +28 working days ... so forth for the next 12 months we need the end and start dates.

Can we also have it so its just the dates displayed and not (time and greenwhich) at the end of the date

I have so far a simple js 28-working day script that works ... but I don't know how to do the complex bit, I tried grabbing the element with html and re doing the script but it didn't work as planned.

May someone help with this struggule. Many thanks.

var startDate = "2019-03-11";
startDate = new Date(startDate.replace(/-/g, "/"));
var endDate = "", noOfDaysToAdd = 28, count = 0;
while(count < noOfDaysToAdd){
    endDate = new Date(startDate.setDate(startDate.getDate() + 1));
    if(endDate.getDay() != 0 && endDate.getDay() != 6){
       count++;
    }
}

document.getElementById("month1end").value = endDate;
  • Each month does not necessarily have 28 working days... so adding 28 working days at the end of one month does not necessarily give you the last working day of the second month. – Terry Mar 11 '19 at 21:00
  • @terry I know, thats fine, but I need to be able to get the end date of month 1 and add 1 day to it, then calculate the date (28 working days from that date) and display it as month 2 end.. so forth for 12 months forecast – George Richardson Mar 11 '19 at 21:03
  • You know eventually that's going to run out of sync with the month, right? And by "end date" do you mean the last working day? The last calendar day? – Terry Mar 11 '19 at 21:03
  • @Terry, why? I am just adding 28 days to the date – George Richardson Mar 11 '19 at 21:04
  • There are battle tested JS libs that can handle such logic for you. [MomnetJS](https://momentjs.com/) for example. Consider using one. – Guy Yogev Mar 11 '19 at 21:04
  • No its jsut the end date after 28 days have been added, not ethe end date of the actual calendar – George Richardson Mar 11 '19 at 21:05
  • 1
    A working day is Monday to Friday. There is not a single month where you have 28 of those days. I think you will need to either describe your requirement in better detail, or provide some kind of figure/diagram/example to show us what you actually need. – Terry Mar 11 '19 at 21:05
  • 28 working days is how the business is run, we need to get the first date for a customer, work out 28 working days (not include sat/sun) then that becomes month 1 end date.... then month 2 start is the end 1 date + 1 day ... so forth so forth @Terry – George Richardson Mar 11 '19 at 21:06
  • just wondering... How do you know how many working days are withing a time frame? what about holydays and such? – Guy Yogev Mar 11 '19 at 21:08
  • @Terry - example Customer start date is 11th March 2019 - 28 working days equals to 18th April , the 18th April becomes the month 1 end date, Month 2 end date is 18th April (month 1 end date + 1) which is equal to 19th April, then end date is +28 working days ... so forth for the next 12 months we need the end and start dates – George Richardson Mar 11 '19 at 21:08
  • @GuyYogev Our business is 28 working days, our business operates every day of the year besides saturday and sunday. – George Richardson Mar 11 '19 at 21:09
  • 1
    Great: now put that information in your question so that others can actually see it, without going through the comments thread. – Terry Mar 11 '19 at 21:09
  • @Terry, I have done thanks – George Richardson Mar 11 '19 at 21:11
  • There seems to be a calculation error. If 11 March is the first day of the month, then 18 April is indeed 28 days *later*, but that means it is the 29th day. So the month should run from 11 March to 17(!) April, and the next month should start at 18 April. – trincot Mar 11 '19 at 21:42
  • any date can be any start date, not necessarily 11th march, could be 3rd june, then 28 working days is the date of the month end , month two start date is +1 day from the month 1 end date @trincot – George Richardson Mar 11 '19 at 21:45
  • If you tell me that if 11 March is the start date, that then the end date must be 18 April, then you have a month with 29 working days. Is that really what you want? I am saying that for 11 March the end date should be 17 April (if you want months of 28 working days). – trincot Mar 11 '19 at 21:47

2 Answers2

1

Here is how you could do it. Note that to get the last day of a "month" of 28 working days, you need to add 27 working days to the first day (not 28). Adding 28 will give you the first day of the next month.

I would suggest using a function that adds a number of working days to a give date (object). It will ensure the result is a working day. So even if you add 0 days, it might change the date (when it was a weekend day).

Here is the function, and the additional code to generate the 12 months, and also support for bank holidays. Just define them in the first assignment:

const bankHolidays = new Set([
    Date.parse("April, 19 2019"), 
    Date.parse("April, 22 2019")
]);
function addWorkingDays(date, days) {
    function workingDay(date) {
        while (true) {
            let day = (date.getDay() + 1) % 7;
            if (day < 2) date.setDate(date.getDate() + 2 - day);
            if (!bankHolidays.has(date.getTime())) break; 
            date.setDate(date.getDate()+1);
        }
    }
    workingDay(date);
    while(days--) {
        date.setDate(date.getDate() + 1);
        workingDay(date);
    }
    return date;
}

document.querySelector("button").addEventListener("click", function() {
    const dateStr = document.querySelector("#startdate").value.replace(/-/g, "/");
    const date = new Date(dateStr);
    addWorkingDays(date, 0); // Make sure it is a working day
    const td = document.querySelectorAll("td");
    for (let i = 0; i < 12; i++) {
        td[i*2].textContent = date.toDateString();
        td[i*2+1].textContent = addWorkingDays(date, 27).toDateString();
        addWorkingDays(date, 1);
    }
});
table, tr, td, th {
  border: 1px solid;
  border-collapse: collapse;
}
<label>Start date: <input id="startdate"></label>
<button>Generate months</button>

<table>
    <tr><th>start</th><th>end</th></tr>
    <tr><td></td><td></td></tr>
    <tr><td></td><td></td></tr>
    <tr><td></td><td></td></tr>
    <tr><td></td><td></td></tr>
    <tr><td></td><td></td></tr>
    <tr><td></td><td></td></tr>
    <tr><td></td><td></td></tr>
    <tr><td></td><td></td></tr>
    <tr><td></td><td></td></tr>
    <tr><td></td><td></td></tr>
    <tr><td></td><td></td></tr>
    <tr><td></td><td></td></tr>
</table>
trincot
  • 317,000
  • 35
  • 244
  • 286
  • That question is answered [here](https://stackoverflow.com/questions/23593052/format-javascript-date-to-yyyy-mm-dd) – trincot Mar 11 '19 at 21:49
  • Can we prevent sun and saturdays? e.g. I can input Sunday Jan 2019... we don't want saturday and sundays – George Richardson Mar 11 '19 at 21:57
  • There was a little error in the formula which I just corrected. When you enter a Saturday or Sunday, the table starts from the next Monday. – trincot Mar 11 '19 at 22:00
  • Sorry, can you please remove / excslude these dates 19th April 2019 22nd April 2019 6th May 2019 27th May 2019 26th August 2019 25th December 2019 26th December 2019 – George Richardson Mar 11 '19 at 22:10
  • Did you try doing yourself? What issues you encounter? Try to put these exceptional days in an array, and test for them in the nested `workingDay` function. If you cannot make it to work, don't hesitate to ask a new question. – trincot Mar 11 '19 at 22:14
  • To be completely honest with you, I know little to no JS, I only know PHP, which to some degree maybe similar, I think I know how to do an array, – George Richardson Mar 11 '19 at 22:18
  • Added support for holidays in my answer. But now you should really deal with any follow-up questions you might have, as comments are not intended for those. Just ask a new question when you have an issue you cannot resolve yourself. – trincot Mar 11 '19 at 22:31
  • Had to apply a fix after having added the bank holidays feature. – trincot Mar 11 '19 at 23:13
0

Since this date can be converted to milisecounds by signing it to variable, you can just simply add one day in ms, so you will get your '19th April', or try this endDate.setDate(endDate.getDate() + 1) - will work as well i think.

If you want to do this automatically for 12 month just put your code in a loop and change start day after each iteration.

Hope i helped.

Tomal
  • 127
  • 10