可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Let's say I have a list of dates in a table. Now I want to find all rows, which is in the same week as the date provided as an argument.
Let's say I have a table with:
- 2014-09-11
- 2014-09-12
- 2014-09-15
And I give this function the argument 2014-09-09, it has to look from monday->sunday, and realize that 09-11 and 09-12 is part of the week, but not 09-15.
How on earth to solve this?
I have thought on making a check on year, month and weeknumber, but you cannot guarantee that month is the same...
So how do you solve a problem like this?
回答1:
DxCk's comment is valid. This solution will work even if the first or last week of the year cross two different years:
Check that the first day of the week for both dates fall on the same day.
Here is the code:
private bool DatesAreInTheSameWeek(DateTime date1, DateTime date2)
{
var cal = System.Globalization.DateTimeFormatInfo.CurrentInfo.Calendar;
var d1 = date1.Date.AddDays(-1 * (int)cal.GetDayOfWeek(date1));
var d2 = date2.Date.AddDays(-1 * (int)cal.GetDayOfWeek(date2));
return d1 == d2;
}
回答2:
why not?
bool AreFallingInSameWeek(DateTime date1, DateTime date2)
{
return date1.AddDays(-(int)date1.DayOfWeek) == date2.AddDays(-(int)date2.DayOfWeek);
}
if you want to use any day other than Sunday as start of the week
bool AreFallingInSameWeek(DateTime date1, DateTime date2, DayOfWeek weekStartsOn)
{
return date1.AddDays(-GetOffsetedDayofWeek(date1.DayOfWeek, (int)weekStartsOn)) == date2.AddDays(-GetOffsetedDayofWeek(date2.DayOfWeek, (int)weekStartsOn));
}
int GetOffsetedDayofWeek(DayOfWeek dayOfWeek, int offsetBy)
{
return (((int)dayOfWeek - offsetBy + 7) % 7)
}
回答3:
Check the DateTime.Year and Calendar.GetWeekOfYear(DateTime, ...). No need to check for the month.
EDIT: This is wrong but I can't delete it. See @Sparrow's answer below.
回答4:
Use: public virtual int GetWeekOfYear(DateTime time,CalendarWeekRule rule,DayOfWeek firstDayOfWeek)
of Calendar class
回答5:
My requirement was to find DOBs falling on the current week. Hope this helps with your doubt. Basically the idea behind this code is as follows:
- Change the DOB to current year birthday (eg; 24-02-1988 to 24-02-2018(current year).
- Add a year, if the brithday week contains both dec and jan
- Get the first day of today's week.
- Get last day of today's week.
check if the current year birthday falls between first day and last day of today's week.
private bool DatesAreInTheSameWeek(DateTime birthday)
{
if (birthday == DateTime.MinValue)
{
return false;
}
else
{
var birtdayWithCurrentYear = new DateTime(DateTime.Today.Year, birthday.Month, birthday.Day);
if (birthday.Month == 1 && DateTime.Today.Month != 1)
{
birtdayWithCurrentYear = birtdayWithCurrentYear.AddYears(1);
}
DateTime firstDayInWeek = DateTime.Today.Date;
while (firstDayInWeek.DayOfWeek != CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek)
firstDayInWeek = firstDayInWeek.AddDays(-1);var lastDayInWeek = firstDayInWeek.AddDays(7);
return birtdayWithCurrentYear < lastDayInWeek && birtdayWithCurrentYear >= firstDayInWeek;
}
}
回答6:
If you don't want to use the Calendar class you can use this function:
public static int WeekOfYear(DateTime dt)
{
int startDays = 0;
// first day of the year
DateTime firstJanuary = new DateTime(dt.Year, 1, 1);
if (firstJanuary.DayOfWeek == DayOfWeek.Tuesday)
{
startDays = 1;
}
else if (firstJanuary.DayOfWeek == DayOfWeek.Wednesday)
{
startDays = 2;
}
else if (firstJanuary.DayOfWeek == DayOfWeek.Thursday)
{
startDays = 3;
}
else if (firstJanuary.DayOfWeek == DayOfWeek.Friday)
{
startDays = 4;
}
else if (firstJanuary.DayOfWeek == DayOfWeek.Saturday)
{
startDays = 5;
}
else if (firstJanuary.DayOfWeek == DayOfWeek.Sunday)
{
startDays = 6;
}
if (DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek == DayOfWeek.Sunday)
{
startDays++;
startDays = startDays % 7;
}
return ((dt.DayOfYear + startDays - 1) / 7) + 1;
}
回答7:
Since the accepted answer contains error as @DxCK mentioned in comment, here is my solution for this:
public static class DateExtensions
{
private static void Swap<T>(ref T one, ref T two)
{
var temp = one;
one = two;
two = temp;
}
public static bool IsFromSameWeek(this DateTime first, DateTime second, DayOfWeek firstDayOfWeek = DayOfWeek.Monday)
{
// sort dates
if (first > second)
{
Swap(ref first, ref second);
}
var daysDiff = (second - first).TotalDays;
if (daysDiff >= 7)
{
return false;
}
const int TotalDaysInWeek = 7;
var adjustedDayOfWeekFirst = (int)first.DayOfWeek + (first.DayOfWeek < firstDayOfWeek ? TotalDaysInWeek : 0);
var adjustedDayOfWeekSecond = (int)second.DayOfWeek + (second.DayOfWeek < firstDayOfWeek ? TotalDaysInWeek : 0);
return adjustedDayOfWeekSecond >= adjustedDayOfWeekFirst;
}
}
Also here is link to another correct solution with slightly different approach.
回答8:
Find start and end dates for the first date's week. Then check if the second date is between those two.
public static bool DateInsideOneWeek(DateTime date1, DateTime date2)
{
DayOfWeek firstDayOfWeek = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
DateTime startDateOfWeek = date1.Date;
while(startDateOfWeek.DayOfWeek != firstWeekDay)
{ startDateOfWeek = startDateOfWeek.AddDays(-1d); }
DateTime endDateOfWeek = startDateOfWeek.AddDays(6d);
return date2 >= startDateOfWeek && date2 <= endDateOfWeek;
}