Alec Pojidaev's InfoPath Blog
Stuff published for no reason (cool codeless infopath solutions mostly)

Work (business) days calculations with C#

If you think it’s a decent solution vote for it! :)

 

Work days between 2 dates:

public static double GetBusinessDays(DateTime startD, DateTime endD)

{

double calcBusinessDays =

1 + ((endD-startD).TotalDays * 5 –

(startD.DayOfWeek-endD.DayOfWeek) * 2) / 7;

if (endD.DayOfWeek == DayOfWeek.Saturday) calcBusinessDays –;

if (startD.DayOfWeek == DayOfWeek.Sunday) calcBusinessDays –;

return calcBusinessDays;

}

 

Note 1: Some changes are made to comply with the changes made by admins of StackOverflow.com site. They did removed unnecessary cast to int.

Note 2: Another useful input from the same site: Just to remark, with the ‘1+’ it assumes start of first day until end of last day, without the ‘1+’ it assumes end of first day until end of last day. Took me a while to figure that out, since I was assuming start of first day until start of last day, which made more sense to me. – Jeffry van de Vuurst Oct 23 ’15 at 9:21

Note 3: The code is relying on the fact that by default in C# (int)DayOfWeek.Saturday is 6 and (int)DayOfWeek.Sunday is 0. This option might be different in your region so the code should be refactored accordingly. Looks like both “ifs” could be removed if Monday would be  0 (if week starts Monday). Need to be tested though.

Add work days to a start date:

DateTime startD = new DateTime(2000, 5, 28);

double businessDays = 2300;

int DoW = (int)startD.DayOfWeek;

double temp = businessDays + DoW + 1;

if (DoW != 0) temp –;

DateTime calcendD = startD.AddDays(

Math.Floor(temp / 5)*2-DoW + temp

– 2* Convert.ToInt32(temp % 5 == 0)) ;

15 Responses to “Work (business) days calculations with C#”

  1. What is the logic behind. Could you pls explain?
    thanks,
    burak.

    • I got that formula after simplifying more complex expression so I don’t know the meanings of the multiplyers. The initial formula was just math expression that anybody can construct if they have basic logic skills and familiar with concept of modulus.

  2. The above code fragment does not even compile, let alone calculate the figure suggested.

    • It’s working. The WordPress site is replacing the minus sign with something different when spaces are from both sides of the minus sign. I’ve removed spaces and now copy paste won’t get you into troubles anymore. Anyway thanks.

      The downside of that fix is this post won’t be serving as a test for people’s basic troubleshooting skills anylonger :P

  3. Very well done.
    I tried it for each month of 2010, and it is good.

    Here the convert I used in VB.NET :

    Public Shared Function GetBusinessDays(ByVal startD As DateTime, ByVal endD As DateTime) As Double
    Dim calcBusinessDays As Double = 1 + ((endD - startD).TotalDays * 5 - (startD.DayOfWeek - endD.DayOfWeek) * 2) / 7
    If CInt(endD.DayOfWeek) = 6 Then calcBusinessDays -= 1
    If CInt(startD.DayOfWeek) = 0 Then calcBusinessDays -= 1
    Return calcBusinessDays
    End Function

    Thanks

  4. It’s probably prudent to use a Math.Floor around TotalDays… I would expect a whole number of business days. Especially useful when I need to multiply by the (average/expected) number of hours worked per day.

    double calcBusinessDays =
    1 + (Math.Floor((endD-startD).TotalDays) * 5 –
    (startD.DayOfWeek-endD.DayOfWeek) * 2) / 7;

    • No need to use any rounding function here. There will be no reminder after division operation. That is some little math magic for you.

      But using rounding function as it is in your example is especially pointless (its impossible to get “not round” figures as a result of multiplication/substraction of whole numbers)

  5. Thanks alec… it works like a charm!!!

  6. This is a nice, elegant solution. Wrote up some unit tests to verify it and feel good about it. Thanks man!

  7. why adding one work day in your second part “Add work days to a start date” gives the same date as a result?

  8. First of all, great functions!

    Just wondering if you knew of a formula for work days plus Saturdays (M-Sa)? I’ve altered the work days between two dates as follows:

    public static double GetBusinessDays(DateTime startD, DateTime endD)
    {
    double calcBusinessDays =
    1 + ((endD-startD).TotalDays * 6 –
    (startD.DayOfWeek-endD.DayOfWeek)) / 7;
    if ((int)startD.DayOfWeek == 0) calcBusinessDays –;
    return calcBusinessDays;
    }

    My initial testing seems to be positive. Any feedback would be greatly appreciated. Thanks

  9. Made up this ColdFusion Function from this thread. Helped me a lot, thanks! Changes that i’ve made:

    > Named it “workingDateDiff”, according to ColdFusion’s built-in “dateDiff” function.
    > Used ColdFusions built-in “local”-scope for functions (also re-initializing it for older CF-Versions).
    > Since ColdFusions “dayOfWeek”-function returns values from 1 to 7 (other than C# 0 to 6), I changed that too.

  10. The day-adding function is good but doesn’t quite work when subtracting. For example, adding 5 days to 2015-12-01 gives 2015-12-08, but adding -5 days to 2015-12-08 doesn’t give 2015-12-01.

    I’ve fixed this bug in my implementation at https://gist.github.com/batterseapower/586a925a34ba2a85f51a (assumes you have epoch dates as from e.g. the Java 8 LocalDate class)


Leave a comment