-1

I've the following problem: I'm try to calculate the days between the first day of the actuall month and a week and his week day. For example: actually it's february. I'll have the days between the first day of this month and the second wednesday. How I can do this as clean as possible?

Marcel Hoffmann
  • 973
  • 1
  • 8
  • 15
  • 2
    Do you have any code to show of what isn't working for you? – Mark C. Feb 12 '15 at 14:06
  • My brain isn't working. I've no idea how I can practise this. Can someone give me a hint. – Marcel Hoffmann Feb 12 '15 at 14:08
  • Read about CultureInfo.InvariantCulture.Calendar.GetWeekOfYear. This is half the way to the solution. – Veverke Feb 12 '15 at 14:08
  • [TimeSpan](https://msdn.microsoft.com/en-us/library/system.timespan(v=vs.110).aspx) could be interesting too. – Claudio P Feb 12 '15 at 14:10
  • Naive approach: start at `new DateTime(year, month, 1)`, see if `DayOfWeek` is what you want, if so increase found counter, add a day, repeat until found counter is what you want and return how many days you added. – Corak Feb 12 '15 at 14:10

3 Answers3

1

Well, you can get the first day of current month like;

DateTime firstDay = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);

And you can get second wednesday like;

DateTime secondWednesday = firstDay.AddDays(7);

while(secondWednesday.DayOfWeek != DayOfWeek.Wednesday)
{
   secondWednesday = secondWednesday.AddDays(1);
}

Since we try to get second wednesday, at worst case scenario, second wednesday will be number 8 of the current month. If the 1st day is Wednesday, then second wednesday will be 8th of the month. Other than that, day number will be bigger than 8.

This is the most logical option that I can imagine at least..

I found great answer by Mark Ransom on this question;

The language-agnostic version:

To get the first particular day of the month, start with the first day of the month: yyyy-mm-01. Use whatever function is available to give a number corresponding to the day of the week. Subtract that number from the day you are looking for; for example, if the first day of the month is Wednesday (2) and you're looking for Friday (4), subtract 2 from 4, leaving 2. If the answer is negative, add 7. Finally add that to the first of the month; for my example, the first Friday would be the 3rd.

To get the last Friday of the month, find the first Friday of the next month and subtract 7 days.

Community
  • 1
  • 1
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
0

Here's an extension method that finds the first day of the month:

public static DateTime FirstDayOfMonth(this DateTime datetime)
{
    return datetime.AddDays(-(datetime.Day - 1));
}

Here's one that finds the next of any weekday:

public static DateTime Next(this DateTime datetime, DayOfWeek day)
{
    return datetime.AddDays(datetime.DayOfWeek < day ?
        day - datetime.DayOfWeek :
        7 + day - datetime.DayOfWeek);
}

Here's one that finds the first of any weekday in a month:

public static DateTime FirstDayOfMonth(this DateTime datetime, DayOfWeek day)
{
    DateTime first = datetime.FirstDayOfMonth();
    return first.DayOfWeek == day ? first : first.Next(day);
}

Now to find the second wednesday after the first day of the month:

DateTime now = DateTime.Now;
DateTime firstWednesday = now.FirstDayOfMonth(DayOfWeek.Wednesday);
DateTime secondWednesday = firstWednesday.AddDays(7);

int difference = secondWednesday.Day - 1;
Dennis_E
  • 8,751
  • 23
  • 29
0

Here's a solution without loops or conditionals:

DateTime NthWeekdayInCurrentMonth(int n, DayOfWeek day)
{
    var firstOfMonth = DateTime.Now.AddDays(-(DateTime.Now.Day-1));
    var firstWeekDay = firstOfMonth.AddDays(day - firstOfMonth.DayOfWeek);
    var NthWeekDay = firstWeekDay.AddDays(7*(n-1));
}

You might want to add some bounds checking on n to make sure your result is always in the current month.

You can easily get the number of days between the resulting date and the first of the month as follow:

NthWeekdayInCurrentMonth(2, DayOfWeek.Wednesday).Day-1
Rik
  • 28,507
  • 14
  • 48
  • 67