【问题标题】:Check if a datetime is in same week as other datetime检查日期时间是否与其他日期时间在同一周
【发布时间】:2014-11-05 20:43:23
【问题描述】:

假设我在表格中有一个日期列表。现在我想查找与作为参数提供的日期在同一周内的所有行。

假设我有一张桌子:

  • 2014-09-11
  • 2014-09-12
  • 2014-09-15

我给这个函数提供参数 2014-09-09,它必须从 monday->sunday 开始,并意识到 09-11 和 09-12 是一周的一部分,而不是 09-15。

究竟如何解决这个问题?

我考虑过检查年、月和周数,但你不能保证那个月是一样的......

那么你如何解决这样的问题呢?

【问题讨论】:

标签: c# datetime c#-4.0


【解决方案1】:

DxCk 的评论是有效的。即使一年中的第一周或最后一周跨越两个不同的年份,此解决方案也可以工作:

检查两个日期的一周的第一天是否在同一天。 代码如下:

    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;
    }

【讨论】:

  • 这仅在您希望一周从星期日开始时才有效。
  • @OllieP 你可以通过从星期几中减去1 轻松解决这个问题:date1.AddDays(-((int)date1.DayOfWeek-1))。这应该是 imo 接受的答案。
  • 我宁愿只创建一个小的帮助方法,它返回我所在的工作日的适当数字,而不是从 DayOfWeek 中“神奇地减去”,因为这需要人们知道内置的 Enum 开始于周日。
  • @Sparrow,您的解决方案在从星期一开始的国家/地区无法正常工作。在 2020 年 1 月 11 日和 2020 年 6 月 11 日尝试上面的代码
【解决方案2】:

检查 DateTime.Year 和 Calendar.GetWeekOfYear(DateTime, ...)。无需检查月份。

编辑:这是错误的,但我无法删除它。请参阅下面@Sparrow 的回答。

【讨论】:

  • 31/12/2015 和 01/01/2016 发生在同一周但不同年份怎么样?
【解决方案3】:

查找第一个日期所在周的开始日期和结束日期。然后检查第二个日期是否在这两者之间。

   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;
    }

【讨论】:

  • 我试过了,但日期有点问题,因为要检查的日期也包含时间。所以我添加了 startDateOfWeek.AddHours(-startDateOfWeek.Hour);删除小时,与分钟相同,然后是 endDateOfWeek = startDateOfWeek.AddDays(7d);所以我的日期从午夜开始,一周后在午夜结束。这对我来说很好。谢谢!
【解决方案4】:

我的要求是找到本周下降的 DOB。希望这对您的疑问有所帮助。基本上这段代码背后的思想如下:

  1. 将 DOB 更改为当年生日(例如:24-02-1988 改为 24-02-2018(当年)。
  2. 如果生日周同时包含 dec 和 jan,则添加年份
  3. 获取今天这一周的第一天。
  4. 获取今天这一周的最后一天。
  5. 检查当前年份的生日是否在今天一周的第一天和最后一天之间。

    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;
    
        }
    }
    

【讨论】:

    【解决方案5】:

    为什么不呢?

    bool AreFallingInSameWeek(DateTime date1, DateTime date2)
    {
        return date1.AddDays(-(int)date1.DayOfWeek) == date2.AddDays(-(int)date2.DayOfWeek);
    }
    

    如果您想使用星期日以外的任何一天作为一周的开始

    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)
    }
    

    【讨论】:

    • 您应该警惕在 .Net 核心中使用这些,因为 DateTime 上的毫秒数几乎总是会导致返回值 false,即 AreFallingInSameWeek(DateTime.Now, DateTime.Now, DayOfWeek.Monday)将返回 false,但您可以通过添加 .Date 来解决此问题,如下所示: date1.AddDays(-GetOffsetedDayofWeek(date1.DayOfWeek, (int)weekStartsOn)).Date == date2.AddDays(-GetOffsetedDayofWeek(date2.DayOfWeek, ( int)weekStartsOn)).Date;
    • 对于提出的两个解决方案中的第一个,您会得到错误,因为它也在比较时间。只需在两个值的末尾添加.Date 即可比较当天如下:return date1.AddDays(-(int)date1.DayOfWeek).Date == date2.AddDays(-(int)date2.DayOfWeek).Date;
    【解决方案6】:

    由于接受的答案包含评论中提到的@DxCK 错误,这是我的解决方案:

    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;
        }
    }
    

    这里还有link 的另一个正确解决方案,方法略有不同。

    【讨论】:

      【解决方案7】:

      如果你不想使用 Calendar 类,你可以使用这个函数:

      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;
      }
      

      【讨论】:

        【解决方案8】:

        使用:public virtual int GetWeekOfYear(DateTime time,CalendarWeekRule rule,DayOfWeek firstDayOfWeek)Calendar

        【讨论】:

          猜你喜欢
          • 2022-07-21
          • 1970-01-01
          • 1970-01-01
          • 2018-07-26
          • 2012-05-27
          • 1970-01-01
          • 2020-02-26
          • 2013-03-01
          • 1970-01-01
          相关资源
          最近更新 更多