user1221996
user1221996

Reputation: 127

c# how to calculate the working days left in a month

Hi i am new to c# and programing in general i have been trying to learn from adapting other peoples code the code below i have changed the code as i want to calulate the amount of working days left in a month but the problem is the code runs over the amount of days in a month so this month has 29 days but the code errors as the code runs to the 30th I can not figure out which part of the code to change any help would be great

    private void days()
    {

        //Monday to Friday are business days.
        var weekends = new DayOfWeek[] { DayOfWeek.Saturday, DayOfWeek.Sunday };
        DateTime testing = DateTime.Now;



        string month1 = testing.ToString("M ");
        string year1 = testing.ToString("yyyy");
        int month = Convert.ToInt32(month1);
        int year = Convert.ToInt32(year1);


        //Fetch the amount of days in your given month.
        int daysInMonth = DateTime.DaysInMonth(year, month);
        string daysleft = testing.ToString("d ");
        int daystoday = Convert.ToInt32(daysleft);

        //Here we create an enumerable from 1 to daysInMonth,
        //and ask whether the DateTime object we create belongs to a weekend day,
        //if it doesn't, add it to our IEnumerable<int> collection of days.
        IEnumerable<int> businessDaysInMonth = Enumerable.Range(daystoday, daysInMonth)
                                               .Where(d => !weekends.Contains(new DateTime(year, month, d).DayOfWeek));

        //Pretty smooth.

        int count = 0;
        foreach (var day in businessDaysInMonth)
        {
            count = count + 1;
        }
        textBox9.Text = count.ToString();


    }
}

Upvotes: 1

Views: 3639

Answers (3)

CodesInChaos
CodesInChaos

Reputation: 108800

public static IEnumerable<int> Range(int start, int count)

As you can see the second parameter isn't the end, but the count.

The count you want is probably: daysInMonth - daystoday + 1

I'd rewrite your code as:

private static readonly DayOfWeek[] weekends = new DayOfWeek[] { DayOfWeek.Saturday, DayOfWeek.Sunday };

bool IsWorkDay(DateTime day)//Encapsulate in a function, to simplify dealing with holydays
{
    return !weekends.Contains(day.DayOfWeek);
}

int WorkDaysLeftInMonth(DateTime currentDate)
{
    var remainingDates = Enumerable.Range(currentDate.Day,DateTime.DaysInMonth(currentDate.Year,currentDate.Month)-currentDate.Day+1)
                        .Select(day=>new DateTime(currentDate.Year, currentDate.Month, day));
    return remainingDates.Count(IsWorkDay);
}

Upvotes: 10

user1054326
user1054326

Reputation: 318

private int GetWorkingDaysLeftInMonth()
    {
        // get the daysInMonth
        int daysInMonth = GetDaysInMonth();

        // locals
        int businessDaysInMonth = 0;
        int day = DateTime.Now.Day;
        bool isWeekDay = false;

        int currentDay = (int) DateTime.Now.DayOfWeek;
        DayOfWeek dayOfWeek = (DayOfWeek)currentDay;

        // iterate the days in month
        for (int x = day; x < daysInMonth; x++)
        {
            // increment the current day
            currentDay++;

            // if the day is greater than 7
            if (currentDay > 7)
            {
                // reset the currentDay
                currentDay = 1;
            }

            // get the dayOfWeek
            dayOfWeek = (DayOfWeek) currentDay;

            switch(dayOfWeek)
            {
                case DayOfWeek.Monday:
                case DayOfWeek.Tuesday:
                case DayOfWeek.Wednesday:
                case DayOfWeek.Thursday:
                case DayOfWeek.Friday:

                    // is a week day
                    isWeekDay = true;

                    // required
                    break;

                default:

                    // is a NOT week day
                    isWeekDay = true;

                    // required
                    break;
            }

            if (isWeekDay)
            {
                // increment the value
                businessDaysInMonth++;  
            }
        }

        // return value
        return businessDaysInMonth;
    }

    private int GetDaysInMonth()
    {
        // initial value
        int daysInMonth = 0;

        switch(DateTime.Now.Month)
        {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:

                daysInMonth = 31;

                // required;
                break;

            case 2:

                daysInMonth = 28;

                // to do (leap year)
                bool isLeapYear = IsLeapYear();

                // if isLeapYear
                if (isLeapYear)
                {
                    // set to 29
                    daysInMonth = 29;
                }

                // required
                break;

            case 4:
            case 6:
            case 9:
            case 11:

                daysInMonth = 30;

                // required;
                break;
        }

        // return value
        return daysInMonth;
    }

    private bool IsLeapYear()
    { 
        // initial value
        bool isLeapYear = false;

        int year = DateTime.Now.Year;

        //determine the year
        switch(year)
        {
            case 2012:
            case 2016:
            case 2020:
            // to do: Go as far out as you need to

                // set to true
                isLeapYear = true;

                // required
                break;
        }

        // return value
        return isLeapYear;
    }

Upvotes: 0

roken
roken

Reputation: 3994

There's no need to convert your date to a string and then parse the components back to integer values. Check out the 'Month', 'Day', and 'Year' properties of the DateTime "testing."

(CodeInChaos has your answer, but this is a fun fact that will simplify your code greatly.)

Upvotes: 4

Related Questions