function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Nihar SharmaNihar Sharma 

Subtract (Using Number Field) business days(exclude weekends) from a given date

Hi all,

Using Apex, did you ever had to subtract the business days from any given date? 
Like for ex: if I have to subtract from today Estimated_Ship_Week__c(e.g 9/1/2015) - Mfg_Cycle_Time_Target__c (12)(This is Number field) days, it should exclude all the weekends and give me the final date 9/14/2015 .
Please let me know if you have any function related to this requirement.
Thanks for looking into this.

Regards,
Nihar
Best Answer chosen by Nihar Sharma
Abhishek BansalAbhishek Bansal
Hi Nihar,

I am very sorry for repeating mistakes.
Please update your code and this time it will surely work.

public Date calculateWeekDays(Date EstimatedDate, Integer targetDays){
    Date finalDate = EstimatedDate.addDays(-targetDays);
    
    Integer nonWorkingDays = 0;
    Integer currentDay;
    for(Integer i=0; i <= finalDate.daysBetween(EstimatedDate); i++) {
        currentDay = Math.MOD(Date.newInstance(1990,1,7).daysBetween(finalDate.addDays(i)),7);
        if(currentDay == 6 || currentDay == 0) {
            nonWorkingDays++;
        }
    }
    
    finalDate = finalDate.addDays(-nonWorkingDays);
    
    Datetime dt = DateTime.newInstance(finalDate.year(), finalDate.month(), finalDate.day());
    if(dt.format('E') == 'Sat'){
        finalDate = finalDate.adddays(-1);
    }
    else if(dt.format('E') == 'Sun'){
        finalDate = finalDate.adddays(-2);
    }
    
    return finalDate;
}


Hope this will help you.

Thanks,
Abhishek

All Answers

Abhishek BansalAbhishek Bansal
Hi Nihar,

Can you please clear your requirement a bit more.
Like if you are subtracting 12 from 9/1/2015 how can you get 9/14/2015.
Please clear it with a proper example so that i can help you out.

Thanks,
Abhishek
Nihar SharmaNihar Sharma
Hi Abhishek,

Thanks for reply.

9/14/2015 getting my final result because i am excluding weekend days (like : satureday & sunday)

so, I need this date code.


Regards,
Nihar
Abhishek BansalAbhishek Bansal
Hi Nihar,

Still not clear with your requirement .
My concern is how can you get 14(9/14/2015) if you subtract 12 from 1(1/9/2015)

Please give a live example by filling value in below fields

1. Estimated_Ship_Week__c (Provide a value with any date)
2. Mfg_Cycle_Time_Target__c (Any number which will be subtracted from above date field)
3. Final date (Your expected result after excluding all weekends)

Thanks,
Abhishek
Nihar SharmaNihar Sharma
Hey Abhishek,

let's say :
Release_Date_Target__c = Estimated_Ship_Week__c - 
Mfg_Cycle_Time_Target__c; 

1) I am getting this :
9/20/2015 = 9/1/2015 - 12;

2) for example (this is what i am expecting) : 
9/14/2015 = 9/1/2015 - 12;

so, I need second date result (it is excluding weekend days) (Working day is 5).

I hope this would be understandable.

Regards,
Nihar
Nihar SharmaNihar Sharma
Hey so sorry.

please read this ( i am doing mistake to put month)

its 8/20/2015 = 9/1/2015 - 12

and 8/14/2015 = 9/1/2015 - 12

Now, it should be clear hopefully.

Regards,
Nihar
Abhishek BansalAbhishek Bansal
Hi Nihar,

Please find the code below as per your requirement :

public Date calculateWeekDays(Date EstimatedDate, Integer targetDays){
    Date finalDate = EstimatedDate.addDays(-targetDays);
    
    Integer workingDays = 0;
    Integer currentDay;
    for(Integer i=0; i <= EstimatedDate.daysBetween(finalDate); i++) {
        currentDay = Math.MOD(Date.newInstance(1990,1,7).daysBetween(EstimatedDate.addDays(i)),7);
        if(currentDay != 6 && currentDay != 0) {
            workingDays++;
        }
    }
    
    finalDate = finalDate.addDays(-workingDays);
    
    Datetime dt = DateTime.newInstance(finalDate.today().year(), finalDate.today().month(), finalDate.today().day());
    if(dt.format('E') == 'Sat'){
        finalDate = finalDate.adddays(-1);
    }
    else if(dt.format('E') == 'Sun'){
        finalDate = finalDate.adddays(-2);
    }
    
    return finalDate;
}


Just pass your Date and Integer in to this method and it will return you the final date.
Let me know if you face any issue .

Thanks,
Abhishek
Abhishek BansalAbhishek Bansal
Hi Nihar,

There was some mistakes in code which was posted previosly.
Please update the code as follows :

public Date calculateWeekDays(Date EstimatedDate, Integer targetDays){
    Date finalDate = EstimatedDate.addDays(-targetDays);
    
    Integer nonWorkingDays = 0;
    Integer currentDay;
    for(Integer i=0; i <= finalDate.daysBetween(EstimatedDate); i++) {
        currentDay = Math.MOD(Date.newInstance(1990,1,7).daysBetween(finalDate.addDays(i)),7);
        if(currentDay == 6 || currentDay == 0) {
            nonWorkingDays++;
        }
    }
    
    finalDate = finalDate.addDays(-nonWorkingDays);
    
    Datetime dt = DateTime.newInstance(finalDate.today().year(), finalDate.today().month(), finalDate.today().day());
    if(dt.format('E') == 'Sat'){
        finalDate = finalDate.adddays(-1);
    }
    else if(dt.format('E') == 'Sun'){
        finalDate = finalDate.adddays(-2);
    }
    
    return finalDate;
}


Thanks,
Abhishek
Abhishek BansalAbhishek Bansal
Hi Nihar,

I am very sorry for repeating mistakes.
Please update your code and this time it will surely work.

public Date calculateWeekDays(Date EstimatedDate, Integer targetDays){
    Date finalDate = EstimatedDate.addDays(-targetDays);
    
    Integer nonWorkingDays = 0;
    Integer currentDay;
    for(Integer i=0; i <= finalDate.daysBetween(EstimatedDate); i++) {
        currentDay = Math.MOD(Date.newInstance(1990,1,7).daysBetween(finalDate.addDays(i)),7);
        if(currentDay == 6 || currentDay == 0) {
            nonWorkingDays++;
        }
    }
    
    finalDate = finalDate.addDays(-nonWorkingDays);
    
    Datetime dt = DateTime.newInstance(finalDate.year(), finalDate.month(), finalDate.day());
    if(dt.format('E') == 'Sat'){
        finalDate = finalDate.adddays(-1);
    }
    else if(dt.format('E') == 'Sun'){
        finalDate = finalDate.adddays(-2);
    }
    
    return finalDate;
}


Hope this will help you.

Thanks,
Abhishek
This was selected as the best answer
Nihar SharmaNihar Sharma
Abhishek,

I am doing this with trigger.

can i use this code to my trigger ?

Regards,
Nihar
Abhishek BansalAbhishek Bansal
Yes Nihar, you can use this method anywhere in apex class or trigger.
Nihar SharmaNihar Sharma
Abhishek,

How can replace my fields with your given code ?
Abhishek BansalAbhishek Bansal
Nihar,

Follow the steps :

1. Paste this method in your trigger.
2. Than call the method with following syntax :
     Release_Date_Target__c = calculateWeekDays(Estimated_Ship_Week__c, Mfg_Cycle_Time_Target__c); 
3. Now you will have the required date value in Release_Date_Target__c variable.

Thanks,
Abhishek
Nihar SharmaNihar Sharma
Abhishek,

It is working. Thanks a lot,

I also used BusinessHour.addgmt() method. but i think your code is much better then for me.

One more thing i need to ask, i know this code is for subtracting but if i want addition then what should i have to do ?

let me send code for addition (check it if i am goes wrong then please let me know).

Regards,
Nihar
Nihar SharmaNihar Sharma
Here is the code :

public static Date calculateWeekDaysmfgTarget(Date EstimatedDate, Integer targetDays){
                Date mfgTarget = EstimatedDate.addDays(targetDays);
                
                Integer nonWorkingDays = 0;
                Integer currentDay;
                for(Integer i=0; i <= mfgTarget.daysBetween(EstimatedDate); i++) {
                    currentDay = Math.MOD(Date.newInstance(1990,1,7).daysBetween(mfgTarget.addDays(i)),7);
                    if(currentDay == 6 || currentDay == 0) {
                        nonWorkingDays++;
                    }
                }
                
                mfgTarget = mfgTarget.addDays(nonWorkingDays);
                
                Datetime dt = DateTime.newInstance(mfgTarget.year(), mfgTarget.month(), mfgTarget.day());
                if(dt.format('E') == 'Sat'){
                    mfgTarget = mfgTarget.adddays(2);
                }
                else if(dt.format('E') == 'Sun'){
                    mfgTarget = mfgTarget.adddays(1);
                }
                
                return mfgTarget;
        }


Regards,
Nihar
Abhishek BansalAbhishek Bansal
Great work Nihar :)
Nihar SharmaNihar Sharma
Actually it will store regular days (i mean with weekends),

that is why i asked you. i am not sure that it is correct.
Abhishek BansalAbhishek Bansal
Nihar you are almost correct but there are few things which you need to update.
So please change your addition code as follows :

public static Date calculateWeekDaysmfgTarget(Date EstimatedDate, Integer targetDays){
        Date mfgTarget = EstimatedDate.addDays(targetDays);
        
        Integer nonWorkingDays = 0;
        Integer currentDay;
        for(Integer i=0; i <= EstimatedDate.daysBetween(mfgTarget); i++) {
            currentDay = Math.MOD(Date.newInstance(1990,1,7).daysBetween(EstimatedDate.addDays(i)),7);
            if(currentDay == 6 || currentDay == 0) {
                nonWorkingDays++;
            }
        }
        
        mfgTarget = mfgTarget.addDays(nonWorkingDays);
        
        Datetime dt = DateTime.newInstance(mfgTarget.year(), mfgTarget.month(), mfgTarget.day());
        if(dt.format('E') == 'Sat'){
            mfgTarget = mfgTarget.adddays(2);
        }
        else if(dt.format('E') == 'Sun'){
            mfgTarget = mfgTarget.adddays(1);
        }
        
        return mfgTarget;
}



 
Nihar SharmaNihar Sharma
Ohhhh. got it.

I am doing very silly mistake. only replace that variable in for loop (may i know what is the difference ?)

confusing with only that variable, why we change ? (i was thinking that the arithmatic functionality is same in both case but how would it changed ?)

for subtract : 
for(Integer i=0; i <= ReleaseDate.daysBetween(EstimatedDate); i++) 

for Addition :
 for(Integer i=0; i <= EstimatedDate.daysBetween(mfgTarget); i++) 
Abhishek BansalAbhishek Bansal
Nihar the daysBetween method will return same value in both caes but the difference would of Sign ( - or +).
Since we are using for loop so we must right postive value in i <= smallerDate.DaysBetween(greaterDate)

If we use greaterDate.daysBetween(smallerDate) than it will reurn a negative value and our loop executes for more time.

Hope everything is clear now.
 
Nihar SharmaNihar Sharma
Thank you so much Abhishek.

Now, everything is clear. :)

Thanks again for your valuable time.

Reagrds,
Nihar