用于确定一个月的第一天,一个月的最后一天等的功能。

时间:2009-10-01 20:46:57

标签: c# .net datetime scheduler

我正在创建一个调度程序,需要能够在C#中执行以下操作:

  1. 查找2012年6月1日星期二
  2. 查找2008年3月的最后一个星期五
  3. 查找2013年1月的每个星期六
  4. 查找2009年7月的第3个星期五
  5. 在接下来的3个月内查找每周六
  6. 查找2018年3月的每一天
  7. 结果应该返回DateTimeList<DateTime>

6 个答案:

答案 0 :(得分:4)

以下是查找给定月份中第一个/最后一个指定星期几的方法:

public DateTime GetFirstDayOfWeekInMonth(int year, int month, DayOfWeek dayOfWeek)
{
    DateTime dt = new DateTime(year, month, 1);
    int first = (int)dt.DayOfWeek;
    int wanted = (int)dayOfWeek;
    if (wanted < first)
        wanted += 7;
    return dt.AddDays(wanted - first);
}

public DateTime GetLastDayOfWeekInMonth(int year, int month, DayOfWeek dayOfWeek)
{
    int daysInMonth = CultureInfo.CurrentCulture.Calendar.GetDaysInMonth(year, month);
    DateTime dt = new DateTime(year, month, daysInMonth);
    int last = (int)dt.DayOfWeek;
    int wanted = (int)dayOfWeek;
    if (wanted > last)
        last += 7;
    return dt.AddDays(wanted - last);
}

通过这些,您可以轻松找到其他问题的答案...只需添加7天即可找到您正在寻找的那一天的下一次出现


编辑:更多地考虑它,以扩展方法的形式提供它是非常方便的,例如:

Console.WriteLine("Next monday : {0}", DateTime.Today.Next(DayOfWeek.Monday));
Console.WriteLine("Last saturday : {0}", DateTime.Today.Previous(DayOfWeek.Saturday));

以下是实施:

public static class DateExtensions
{
    public static DateTime Next(this DateTime from, DayOfWeek dayOfWeek)
    {
        int start = (int)from.DayOfWeek;
        int wanted = (int)dayOfWeek;
        if (wanted < start)
            wanted += 7;
        return from.AddDays(wanted - start);
    }

    public static DateTime Previous(this DateTime from, DayOfWeek dayOfWeek)
    {
        int end = (int)from.DayOfWeek;
        int wanted = (int)dayOfWeek;
        if (wanted > end)
            end += 7;
        return from.AddDays(wanted - end);
    }
}

它可能比我建议的第一种方法更灵活...有了它,你可以很容易地做到这样的事情:

// Print all Sundays between 2009/01/01 and 2009/03/31
DateTime from = new DateTime(2009, 1, 1);
DateTime to = new DateTime(2009, 3, 31);
DateTime sunday = from.Next(DayOfWeek.Sunday);
while(sunday <= to)
{
   Console.WriteLine(sunday);
   sunday = sunday.AddDays(7);
}

答案 1 :(得分:2)

受这个问题的启发,制作允许您将日期视为序列并使用LINQ查询它们的内容似乎是一件有趣的事情。我做了一个简单的项目,可以从GitHub下载here。不知道是否有必要将它添加到源代码控制中,因为我怀疑我会继续处理它,但是必须将其上传到某个地方并将其上传到RapidShare似乎有点狡猾:)

我的“Linq-to-DateTime”解决了您的第一个问题:

  /*
   *    1. Find the 1st Tuesday of June 2012
        2. Find the last Friday of March 2008
        3. Find every Saturday in January 2013
        4. Find the 3rd Friday in July 2009
        5. Find every Saturday over the next 3 months
        6. Find every day in March 2018
  */

  var firstTuesday = (from d in DateSequence.FromYear(2012).June()
                    where d.DayOfWeek == DayOfWeek.Tuesday
                    select d).First();

  var lastFriday = (from d in DateSequence.FromYear(2008).March()
                    where d.DayOfWeek == DayOfWeek.Friday
                    select d).Last();

  var saturdays = (from d in DateSequence.FromYear(2013).January()
                   where d.DayOfWeek == DayOfWeek.Saturday
                   select d);

  var thirdFriday = (from d in DateSequence.FromYear(2009).July()
                     where d.DayOfWeek == DayOfWeek.Friday
                     select d).Skip(2).First();

  var nextSaturdays = (from d in DateSequence.FromDates(DateTime.Today, DateTime.Today.AddMonths(3))
                       where d.DayOfWeek == DayOfWeek.Saturday
                       select d);

  var allDays = (from d in DateSequence.FromYear(2018).March()
                 select d);

此示例中未显示您可以选择查询的粒度。这意味着如果你这样做:

  var days = (from d in DateSequence.FromYears(2001, 2090).AsYears()
              where d.Year % 2 == 0
              select d.Year).ToList();

您将以一年的增量迭代日期。如果您未指定任何内容,则默认为AsDays()。

该项目非常准确,没有评论或单元测试,但我希望这仍然可以帮助你。如果没有,那么无论如何写作都很有趣:)

答案 2 :(得分:1)

这是一个如何做一个月的第一天的例子。

public enum Month
{
    January = 1,
    Febuary = 2,
    March = 3,
    April = 4,
    May = 5,
    June = 6,
    July = 7,
    August = 8,
    September = 9,
    October = 10,
    November = 11,
    December = 12
}

public static Nullable<DateTime> FindTheFirstDayOfAMonth(DayOfWeek dayOfWeek, Month month, int year)
{
    // Do checking of parameters here, i.e. year being in future not past

    // Create a DateTime object the first day of that month
    DateTime currentDate = new DateTime(year, (int)month, 1);

    while (currentDate.Month == (int)month)
    {
        if (currentDate.DayOfWeek == dayOfWeek)
        {
            return currentDate;
        }

        currentDate = currentDate.AddDays(1);
    }

    return null;
}

你称之为

Nullable<DateTime> date = Program.FindTheFirstDayOfAMonth(DayOfWeek.Monday, Month.September, 2009);

所以你明白了。你必须做各种功能才能实现你想要达到的目标。

答案 3 :(得分:1)

YO YO YO - 你们这样做太难了:

int DaysinMonth = DateTime.DaysInMonth(DateTime.Now.Year,DateTime.Now.Month);

答案 4 :(得分:0)

当我编写调度程序时,我几乎复制了SQL Servers sysschedules表

http://msdn.microsoft.com/en-us/library/ms178644.aspx

使用频率类型,频率间隔等等......确实可以很容易地计算出代码中的值,但我猜测有一个特殊功能可以为你做。我现在正在寻找。

答案 5 :(得分:-2)

是的,.NET Framework会毫无问题地支持;)

但严重的是 - 您应该能够编写能够轻松完成此操作的代码。如果没有,请在遇到问题时提出问题,我们会帮忙。但是你不需要任何外部程序集 - 只需使用标准的C#class =)