Check if a datetime is in same week as other datet

2020-08-13 06:19发布

问题:

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:

  1. Change the DOB to current year birthday (eg; 24-02-1988 to 24-02-2018(current year).
  2. Add a year, if the brithday week contains both dec and jan
  3. Get the first day of today's week.
  4. Get last day of today's week.
  5. 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;
    }