The function of determining the first day of the month, the last day of the month, etc.

I am creating a scheduler and should be able to do the following in C #:

  • Find the 1st Tuesday of June 2012.
  • Find the last Friday of March 2008.
  • Find every Saturday in January 2013
  • Find the third Friday of July 2009.
  • Find every Saturday for the next 3 months
  • Find every day in March 2018.

Results should be returned as DateTime or List<DateTime> .

+4
source share
6 answers

The following are methods for finding the first / last specified day of the week in a given month:

 public DateTime GetFirstDayOfWeekInMonth(int year, int month, DayOfWeek dayOfWeek) { DateTime dt = new DateTime(year, month, 1); int first = (int)dt.DayOfWeek; int wanted = (int)dayOfWeek; if (wanted < first) wanted += 7; return dt.AddDays(wanted - first); } public DateTime GetLastDayOfWeekInMonth(int year, int month, DayOfWeek dayOfWeek) { int daysInMonth = CultureInfo.CurrentCulture.Calendar.GetDaysInMonth(year, month); DateTime dt = new DateTime(year, month, daysInMonth); int last = (int)dt.DayOfWeek; int wanted = (int)dayOfWeek; if (wanted > last) last += 7; return dt.AddDays(wanted - last); } 

From them you can easily find answers to other questions ... just add 7 days to find the next occurrence of the day you are looking for


EDIT: thinking about this, it would be very convenient to have this in the form of extension methods, such as:

 Console.WriteLine("Next monday : {0}", DateTime.Today.Next(DayOfWeek.Monday)); Console.WriteLine("Last saturday : {0}", DateTime.Today.Previous(DayOfWeek.Saturday)); 

Here is the implementation:

 public static class DateExtensions { public static DateTime Next(this DateTime from, DayOfWeek dayOfWeek) { int start = (int)from.DayOfWeek; int wanted = (int)dayOfWeek; if (wanted < start) wanted += 7; return from.AddDays(wanted - start); } public static DateTime Previous(this DateTime from, DayOfWeek dayOfWeek) { int end = (int)from.DayOfWeek; int wanted = (int)dayOfWeek; if (wanted > end) end += 7; return from.AddDays(wanted - end); } } 

This is probably more flexible than the first methods I suggested ... With this, you can easily do something like this:

 // Print all Sundays between 2009/01/01 and 2009/03/31 DateTime from = new DateTime(2009, 1, 1); DateTime to = new DateTime(2009, 3, 31); DateTime sunday = from.Next(DayOfWeek.Sunday); while(sunday <= to) { Console.WriteLine(sunday); sunday = sunday.AddDays(7); } 
+4
source

Inspired by this question, it seemed fun to do something that allows you to treat dates as sequences and query them using LINQ. I made a simple project that can be downloaded here from GitHub. I don’t know if I need to add it to the original control, since I doubt that I will work on it, but he needed to upload it somewhere and upload it to RapidShare, it seemed a little quirky :)

Your first questions are resolved with my Linq-to-DateTime:

  /* * 1. Find the 1st Tuesday of June 2012 2. Find the last Friday of March 2008 3. Find every Saturday in January 2013 4. Find the 3rd Friday in July 2009 5. Find every Saturday over the next 3 months 6. Find every day in March 2018 */ var firstTuesday = (from d in DateSequence.FromYear(2012).June() where d.DayOfWeek == DayOfWeek.Tuesday select d).First(); var lastFriday = (from d in DateSequence.FromYear(2008).March() where d.DayOfWeek == DayOfWeek.Friday select d).Last(); var saturdays = (from d in DateSequence.FromYear(2013).January() where d.DayOfWeek == DayOfWeek.Saturday select d); var thirdFriday = (from d in DateSequence.FromYear(2009).July() where d.DayOfWeek == DayOfWeek.Friday select d).Skip(2).First(); var nextSaturdays = (from d in DateSequence.FromDates(DateTime.Today, DateTime.Today.AddMonths(3)) where d.DayOfWeek == DayOfWeek.Saturday select d); var allDays = (from d in DateSequence.FromYear(2018).March() select d); 

This example does not show that you can select the granularity of your queries. This means that if you do this:

  var days = (from d in DateSequence.FromYears(2001, 2090).AsYears() where d.Year % 2 == 0 select d.Year).ToList(); 

You will go through dates in increments of a year. AsDays () is used by default if you did not specify anything.

The project is quite simple with no comments or unit tests, but I hope this helps you anyway. If not, then it was still interesting to write :)

+2
source

Here is an example of how to make the first day of the month.

 public enum Month { January = 1, Febuary = 2, March = 3, April = 4, May = 5, June = 6, July = 7, August = 8, September = 9, October = 10, November = 11, December = 12 } public static Nullable<DateTime> FindTheFirstDayOfAMonth(DayOfWeek dayOfWeek, Month month, int year) { // Do checking of parameters here, ie year being in future not past // Create a DateTime object the first day of that month DateTime currentDate = new DateTime(year, (int)month, 1); while (currentDate.Month == (int)month) { if (currentDate.DayOfWeek == dayOfWeek) { return currentDate; } currentDate = currentDate.AddDays(1); } return null; } 

You call it

 Nullable<DateTime> date = Program.FindTheFirstDayOfAMonth(DayOfWeek.Monday, Month.September, 2009); 

So you get the idea. You will need to perform various functions in order to get what you want to achieve.

+1
source

YO YO YO - You guys do it too hard:

int DaysinMonth = DateTime.DaysInMonth (DateTime.Now.Year, DateTime.Now.Month);

+1
source

When I wrote the scheduler, I pretty much copied the SQL Server sysschedules table

http://msdn.microsoft.com/en-us/library/ms178644.aspx

Using things like Frequency Type, Frequency Interval, etc., really made it easier to calculate the values ​​in the code, but I assume it will be sproc for you. I'm looking for it now.

0
source

Yes, the .NET Framework will support this without any problems;)

But seriously - you should be able to write code that makes this pretty easy. If not, ask when you get stuck and we will help. But you don't need any external assemblies - just go with the standard C # = class)

-2
source

All Articles