首页 文章

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

提问于
浏览
4

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

  • 查找2012年6月1日星期二

  • 查找2008年3月的最后一个星期五

  • 2013年1月每周六查找

  • 查找2009年7月的第3个星期五

  • 在接下来的3个月内每周六查找一次

  • 查找2018年3月的每一天

结果应该返回 DateTimeList<DateTime> .

6 回答

  • 1

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

    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

    受这个问题的启发,制作允许您将日期视为序列并使用LINQ查询它们的内容似乎是一件有趣的事情 . 我做了一个简单的项目,可以从GitHub下载here . 唐't know if it was necessary to add it to source control as I doubt I'将会工作,但不得不将其上传到某个地方并将其上传到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

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

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

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

  • 0

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

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

  • 2

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

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

    使用诸如频率类型,频率间隔等之类的东西......真的可以很容易地计算代码中的值,但我猜有一个sproc为你做 . 我现在正在寻找 .

  • 4

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

    但严重的是 - 你应该能够编写相当容易的代码 . 如果没有,请在遇到问题时提出问题,我们会帮忙 . 但是你不需要任何外部程序集 - 只需要使用标准的C#class =)

相关问题