简体   繁体   中英

Get List of 1st and 3rd Saturday of month if 2nd Saturday Appear in first 9 days

I want to get List of all 2nd & 4th Saturdays of an year. But if 2nd Saturday appear in first 9 days of a month then return list of 3rd and 5th Saturday of that month. So far i get list of all 2nd & 4th Saturday of whole year. But I'm not able to get 3rd and 5th Saturday if 2nd Saturday appear in first 9 days of a month.

class Program
{
    static void Main(string[] args)
    {
        List<DateTime> MyCalendar = new List<DateTime>(); //create list
        DateTime currDate = new DateTime(2017, 1, 1); //initial value
        //add days to MyCalendar
        while (currDate <= new DateTime(2017, 12, 31))
        {
            MyCalendar.Add(currDate);
            currDate = currDate.AddDays(1);
        }
        //method to get 2. and 4. saturday in month
        var result = MyCalendar.Where(x => x.DayOfWeek == DayOfWeek.Saturday)
                        .GroupBy(x => x.Month)
                        .SelectMany(grp =>
                            grp.Select((d, counter) => new
                            {
                                Month = grp.Key,
                                PosInMonth = counter + 1,
                                Day = d
                            }))

                        .Where(x => x.PosInMonth == 2 || x.PosInMonth == 4)
                        .ToList();

        foreach (var d in result)
        {
            Console.WriteLine("{0} {1} {2}", d.Month, d.PosInMonth, d.Day);
        }

        Console.Read();

    }

}

Out Put of the Program

Out of Program

Another method

            DateTime currDate = new DateTime(2017, 1, 1); //initial value
            int dayOfWeek = (int)currDate.DayOfWeek;
            currDate = currDate.AddDays(6 - dayOfWeek);
            //add days to MyCalendar
            while (currDate <= new DateTime(2017, 12, 31))
            {
                MyCalendar.Add(currDate);
                currDate = currDate.AddDays(7);
            }
            var result = MyCalendar.GroupBy(x => x.Month).Select(x => x.Skip(1).First().Day <= 9 ? new DateTime[] { x.Skip(2).First(), x.Skip(4).First() } : new DateTime[] { x.Skip(1).First(), x.Skip(3).First() }).SelectMany(x => x).ToList();

            foreach (var d in result)
            {
                Console.WriteLine("{0} {1}", d.Month, d.Day);
            }

            Console.Read();

How about this?

using System;
using System.Collections.Generic;

namespace Demo
{
    class Program
    {
        static void Main()
        {
            foreach (var saturday in FilteredSaturdays(DateTime.Now, new DateTime(2017, 12, 31)))
            {
                Console.WriteLine(saturday);
            }
        }

        public static IEnumerable<DateTime> FilteredSaturdays(DateTime start, DateTime end)
        {
            DateTime startMonth = new DateTime(start.Year, start.Month, 1);
            DateTime endMonth = new DateTime(end.Year, end.Month, 1).AddMonths(1);

            for (DateTime month = startMonth; month < endMonth; month = month.AddMonths(1))
            {
                // Work out date of last saturday in the month.

                DateTime lastDayOfMonth = month.AddMonths(1).AddDays(-1);
                DateTime lastSaturdayOfMonth = lastDayOfMonth.AddDays(-(((int)lastDayOfMonth.DayOfWeek+1)%7));

                // Return saturday 2 weeks before last saturday of month, and last saturday of month.

                yield return lastSaturdayOfMonth.AddDays(-14);
                yield return lastSaturdayOfMonth;
            }
        }
    }
}

This is going to be more efficient than looking at every single day of the year to see if it's a Saturday!

[EDIT] It seems that the actual requirement is that you want the last Saturday in every month and the Saturday two weeks before that Saturday, so I have updated my solution accordingly.

Here is a quick and dirty solution; I admit that it could be more optimized.

Method which will do the lookup:

private static IEnumerable<DateTime> GetWeekDayOfMonth(DateTime monthToCheck, DayOfWeek weekDayToFind)
{
    var year = monthToCheck.Year;
    var month = monthToCheck.Month;
    var dayCount = DateTime.DaysInMonth(year, month);
    var daysList = Enumerable.Range(1, dayCount)
                                    .Select(day => new DateTime(year, month, day))
                                    .Where(date => date.DayOfWeek == weekDayToFind)
                                    .ToList<DateTime>();
    // Loop with 2 increment
    int lookupStart = 1;
    int loopCount = 0;
    if (daysList[1].Day <= 9)
    {
        lookupStart = 2;
    }

    for (var i = lookupStart; i < daysList.Count(); i = i + 2) 
    {
        if (loopCount < 2)
        {
            yield return daysList[i];
            loopCount++;
        }
    }
}

Here is the code to call it:

private static void FindWeekDays()
{
    DateTime dateToCheck = new DateTime(2017, 1, 1);
    List<DateTime> dayList = new List<DateTime>();
    while (dateToCheck.Year <= 2017)
    {
        dayList.AddRange(GetWeekDayOfMonth(dateToCheck, DayOfWeek.Saturday));
        dateToCheck = dateToCheck.AddMonths(1);
    }

    dayList.ForEach(date => Console.WriteLine(date.ToString()));
}

And the Main:

static void Main(string[] args)
{
    FindWeekDays();
}

Will give you the following result for the year 2017 (It can be changed):

日期

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM