How would I get last week Wednesday and next week Wednesday\'s date in C#:
public Form1()
{
InitializeComponent();
CurrentDate.Text = \"Today\'s Date: \" +
To find the next Wednesday just keep adding days until you find one. To find the previous Wednesday just keep subtracting days until you get to one.
DateTime nextWednesday = DateTime.Now.AddDays(1);
while (nextWednesday.DayOfWeek != DayOfWeek.Wednesday)
nextWednesday = nextWednesday.AddDays(1);
DateTime lastWednesday = DateTime.Now.AddDays(-1);
while (lastWednesday.DayOfWeek != DayOfWeek.Wednesday)
lastWednesday = lastWednesday.AddDays(-1);
private static DateTime FindPreviousDayOfWeek(DateTime fromDate, DayOfWeek findDay,
bool skipSame = false)
{
if (fromDate.DayOfWeek < findDay)
fromDate = fromDate.AddDays(-((int)fromDate.DayOfWeek - 1 + (int)findDay));
else if (fromDate.DayOfWeek > findDay)
fromDate = fromDate.AddDays(-((int)fromDate.DayOfWeek - (int)findDay));
else if (fromDate.DayOfWeek == findDay && skipSame == true)
fromDate = fromDate.AddDays(-7);
return fromDate;
}
the skipSame variable does not include the current day if it is the saem as the desired day.
Here is a one-liner to accomplish the same. It is somewhat mind-boggling to understand how that actually works but it does:
Getting next Wednesday:
dt.AddDays(-(int)(dt.AddDays(-4).DayOfWeek) + 6);
Getting last Wednesday
dt.AddDays(-(int)(dt.AddDays(-3).DayOfWeek));
In both cases, it will return the day itself when it is Wednesday. This works for any weekdays, just adjust the number in the AddDays() call. For example for Friday:
Getting next Friday
dt.AddDays(-(int)(dt.AddDays(-6).DayOfWeek) + 6);
Getting last Friday
dt.AddDays(-(int)(dt.AddDays(-5).DayOfWeek));
One of the problems with some of the answers is that the DayoyOfWeek is an enum with values 0-6. When a subsequent day of week equates to Sunday (enum value = 0), but you gave a Tuesday (enum value=2), and you want next tuesday, the calculation goes wrong if you just peform a calculation.
The class with two methods which I cam up with for my own use on a project I am working on is.
public static class DateHelper
{
public static DateTime GetDateForLastDayOfWeek(DayOfWeek DOW, DateTime DATE)
{
int adjustment = ((int)DATE.DayOfWeek < (int)DOW ? 7 : 0);
return DATE.AddDays(0- (((int)(DATE.DayOfWeek) + adjustment) - (int)DOW));
}
public static DateTime GetDateForNextDayOfWeek(DayOfWeek DOW, DateTime DATE)
{
int adjustment = ((int)DATE.DayOfWeek < (int)DOW ? 0 : 7);
return DATE.AddDays(((int)DOW) - ((int)(DATE.DayOfWeek)) + adjustment);
}
}
The XUnit tests proving the code above works.
public class DateHelperUnitTests
{
[Theory]
[InlineData(2020, 1, 7, 2020, 1, 7)]
[InlineData(2020, 1, 8, 2020, 1, 7)]
[InlineData(2020, 1, 9, 2020, 1, 7)]
[InlineData(2020, 1, 10, 2020, 1, 7)]
[InlineData(2020, 1, 11, 2020, 1, 7)]
[InlineData(2020, 1, 12, 2020, 1, 7)]
[InlineData(2020, 1, 13, 2020, 1, 7)]
[InlineData(2020, 1, 14, 2020, 1, 14)]
[InlineData(2020, 1, 15, 2020, 1, 14)]
public void GetDateForLastDayOfWeek_MultipleValues_Pass(
int InputYear, int InputMonth, int InputDay,
int ExpectedYear, int ExpectedMonth, int ExpectedDay)
{
DateTime DateToTest = new DateTime(InputYear, InputMonth, InputDay);
DateTime NewDate = DateHelper.GetDateForLastDayOfWeek(DayOfWeek.Tuesday, DateToTest);
DateTime DateExpected = new DateTime(ExpectedYear,ExpectedMonth,ExpectedDay);
Assert.True(0 == DateTime.Compare(DateExpected.Date, NewDate.Date));
}
[Theory]
[InlineData(2020, 1, 7, 2020, 1, 14)]
[InlineData(2020, 1, 8, 2020, 1, 14)]
[InlineData(2020, 1, 9, 2020, 1, 14)]
[InlineData(2020, 1, 10, 2020, 1, 14)]
[InlineData(2020, 1, 11, 2020, 1, 14)]
[InlineData(2020, 1, 12, 2020, 1, 14)]
[InlineData(2020, 1, 13, 2020, 1, 14)]
[InlineData(2020, 1, 14, 2020, 1, 21)]
[InlineData(2020, 1, 15, 2020, 1, 21)]
public void GetDateForNextDayOfWeek_MultipleValues_Pass(
int InputYear, int InputMonth, int InputDay,
int ExpectedYear, int ExpectedMonth, int ExpectedDay)
{
DateTime DateToTest = new DateTime(InputYear, InputMonth, InputDay);
DateTime NewDate = DateHelper.GetDateForNextDayOfWeek(DayOfWeek.Tuesday, DateToTest);
DateTime DateExpected = new DateTime(ExpectedYear, ExpectedMonth, ExpectedDay);
Assert.True(0 == DateTime.Compare(DateExpected.Date, NewDate.Date));
}
}
DateTime.Now.AddDays(7)
and DateTime.Now.AddDays(-7)
is how you can do arithmetic, assuming you are on Wednesday. If you aren't, what you would need to do is use the DayOfWeek
property to determine the number of days (positive and negative) that you would need to determine which day is 'Wednesday'. Then you can pass that value into AddDays
.
For instance, if today was tuesday, you would AddDays(-6)
for last Wednesday and AddDays(8)
for next Wednesday.
I'll leave you the task of calculating those.
Based on Servy's answer, here's an extension method which will return the desired day/date:
public static DateTime GetPrevious(this DateTime date, DayOfWeek dayOfWeek)
{
var lastDay = date.AddDays(-1);
while (lastDay.DayOfWeek != dayOfWeek)
{
lastDay = lastDay.AddDays(-1);
}
return lastDay;
}
public static DateTime GetNext(this DateTime date, DayOfWeek dayOfWeek)
{
var nextDay = date.AddDays(+1);
while (nextDay.DayOfWeek != dayOfWeek)
{
nextDay = nextDay.AddDays(+1);
}
return nextDay;
}