【问题标题】:first occurrence of day of week in month月中第一次出现星期几
【发布时间】:2015-06-07 13:10:21
【问题描述】:

我想用DateTime date 配置一个事件。

我想在每个月的同一周和同一天重复该活动。

例如,此事件发生在 2015 年 4 月 2 日(4 月的第一周的星期四)。

我想在每个月的第一周的每个星期四再重复一次。

如何计算每次的下一个日期?

【问题讨论】:

  • 我会使用石英来做到这一点quartz-scheduler.net
  • 你有没有尝试过?
  • 定义“第一周”。
  • 真正的想法是“每月的第二个星期一”、“每月的第一个星期日”、“每月的第三个星期三”...
  • 我在运行 Windows 服务的情况下管理事件,但这不是问题,只是确定下一个日期。

标签: c#


【解决方案1】:

从每月的第一天开始,递增直到获得所需的星期几,然后递增 7 倍 n-1,其中 n 是该月中所需的一周中的第 n 天。

public static DateTime(int year, int month, DayOfWeek weekDay, int nth)
{
    DateTime result = new DateTime(year, month, 1);
    while(result.DatOfWeek != weekDay)
        result = result.AddDays(1);
    return result.AddDays(7 * (nth-1));
}

请注意,您需要添加对参数的检查,并确保最终结果不会延续到下个月。

如果您还需要从DateTime 中确定DayOfWeeknth 的值,则可以执行以下操作。

DateTime now = DateTime.Now;
DayOfWeek dayOfWeek = now.DayOfWeek;
int nth = 0;
int month = now.Month;
int year = now.Year;
while(now.Year == year && now.Month == month)
{
    now = now.AddDays(-7);
    nth++;
}

请注意,有可能一个月会有第 5 个星期三,但下个月只有 4 个,因此您必须确定在这些情况下该怎么做。

【讨论】:

    【解决方案2】:

    我开发了一个小函数,可以查找一个月中的任何第 n 天。

    private static DateTime Next(int year, int month, DayOfWeek dayOfWeek, int occurrence)
            {
                return Enumerable.Range(1, 7).
                            Select(day => new DateTime(year, month, day)).
                            First(dateTime => (dateTime.DayOfWeek == dayOfWeek))
                            .AddDays(7 * (occurrence - 1));
            }
    

    【讨论】:

      【解决方案3】:

      我为我的项目开发的方法。它正在添加所有边缘案例并在生产中工作。

              /// <summary>
              /// Calculates and returns the date from specifed month based on weekday and week number passed in.
              /// </summary>
              /// <param name="month">any date of the month as base referece</param>
              /// <param name="dayOfWeek">day of week Mon/Tues/Wed/Thu/Fri etc..</param>
              /// <param name="requiredWeek">!st wqeek = 1,2nd week =2,3,4,5,last etc</param>
              /// <returns></returns>
              public static DateTime GetFirstOccuringWeekDayFromMonth(DateTime month, DayOfWeek dayOfWeek, ReccurrenceEnum requiredWeek)
              {
                  if (requiredWeek == ReccurrenceEnum.First || requiredWeek == ReccurrenceEnum.Second
                      || requiredWeek == ReccurrenceEnum.Third || requiredWeek == ReccurrenceEnum.Forth || requiredWeek == ReccurrenceEnum.Last)
                  {
                      DateTime current;
                      int requiredweekno = (int)requiredWeek;
                      int foundDayInstanceCount = 0;
                      if (requiredWeek == ReccurrenceEnum.Last)
                      {
                          DateTime lastDayofMonth = new DateTime(month.AddMonths(1).Year, month.AddMonths(1).Month, 1).AddDays(-1);
                          DateTime firstDayofMonth = new DateTime(month.Year, month.Month, 1);
                          current = lastDayofMonth;
                          //skip until required day is reached.
                          while (current.DayOfWeek != dayOfWeek && current >= firstDayofMonth)
                              current = current.AddDays(-1);
                          return current;
                      }
                      else
                      {
                          DateTime firstDayofMonth = new DateTime(month.Year, month.Month, 1);
                          DateTime lastDayofMonth = new DateTime(month.AddMonths(1).Year, month.AddMonths(1).Month, 1).AddDays(-1);
                          current = firstDayofMonth;
                          if (current.DayOfWeek == dayOfWeek)
                              foundDayInstanceCount++;
                          //skip until required week is reached.
                          while (foundDayInstanceCount < requiredweekno && current <= lastDayofMonth)
                          {
                              current = current.AddDays(1);
                              if (current.DayOfWeek == dayOfWeek)
                                  foundDayInstanceCount++;
                          }
                          //skip until required day is reached.
                          while (current.DayOfWeek != dayOfWeek && current <= lastDayofMonth)
                              current = current.AddDays(1);
                          return current;
                      }
                  }
                  else
                      throw new Exception("Exception, wrong week recurrence specified!");
              }
      
      public enum ReccurrenceEnum
          {
              First = 1,
              Second = 2,
              Third = 3,
              Forth = 4,
              Last = 5,
          }
      

      【讨论】:

        猜你喜欢
        • 2021-09-06
        • 1970-01-01
        • 1970-01-01
        • 2014-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-05
        • 2021-12-09
        相关资源
        最近更新 更多