【问题标题】:Find all quarters between 2 dates查找 2 个日期之间的所有季度
【发布时间】:2013-01-15 16:42:14
【问题描述】:

我正在尝试查找 2 个给定日期之间的所有季度。

例如,如果当前日期是今天(2013 年 1 月 15 日)并且过去的日期是 2012 年 1 月 1 日,我应该得到以下结果: 2012 年 12 月 2012 年 9 月 2012 年 6 月 2012 年 3 月

我可以从当前日期开始继续减去 3 个月,但这并不准确,因为下面的测试表明:

  [TestMethod]
        public void FindAllQuaters_FromAGivenDate_TillAPastDate()
        {
            var dateFinder = new FindQuarter();
            //Between Feb 2013 & Jan 2012
            var dates = dateFinder.GetAllQuarters(new DateTime(2013, 02, 01), new DateTime(2012, 01, 01)).ToList();

            Assert.IsTrue(dates.Count == 4);
            Assert.IsTrue(dates.First().Month == 12);
            Assert.IsTrue(dates.First().Year == 2012);

            Assert.IsTrue(dates.Skip(1).First().Month == 9);
            Assert.IsTrue(dates.Skip(1).First().Year == 2012);

            Assert.IsTrue(dates.Skip(2).First().Month == 6);
            Assert.IsTrue(dates.Skip(2).First().Year == 2012);

            Assert.IsTrue(dates.Skip(3).First().Month == 3);
            Assert.IsTrue(dates.Skip(3).First().Year == 2012);
        }
    }

    public class FindQuarter
    {
        public IEnumerable<DateTime> GetAllQuarters(DateTime current, DateTime past)
        {
            while (current > past)
            {
                current = current.AddMonths(-3);
                yield return current;
            }
        }
    }

我怎样才能做到这一点?季度定义为 3 月、6 月、9 月和 12 月。我还需要那个月的最后一个日期(我希望很快)。

编辑:这不起作用,因为它一直从给定日期减去 3 个月,例如,如果当前日期是 2013 年 2 月并且我减少了 3 个月,我得到 2012 年 11 月而不是 2012 年 12 月。

  • 一月、二月、三月的任何日期都属于第一季度,即三月

  • 4、5、6 月的任何日期都属于第二季度,即 6 月

  • 7、8、9 月的任何日期都属于第三季度,即 9 月

  • 10 月、11 月、12 月的任何日期都属于第四季度,即 12 月

【问题讨论】:

  • 对不起,我可能遗漏了一些东西,但它是如何/为什么不起作用?
  • 2012 年 12 月 15 日属于哪个季度?
  • 一年的一个季度应该是 3 个月(12 除以 4),而不是 4 个月。称为“2012 年 12 月”的季度是否包含 2012 年 10 月、2012 年 11 月和 2012 年 12 月的日历月?只是想理解定义。

标签: c# .net


【解决方案1】:

这似乎有效。

        public IEnumerable<DateTime> GetAllQuarters(DateTime current, DateTime past)
        {
            var curQ = (int)Math.Ceiling(current.Month / 3.0M);
            var lastQEndDate = new DateTime(current.Year, curQ * 3, 1).AddMonths(-2).AddDays(-1);

            do
            {
                yield return lastQEndDate;
                lastQEndDate = lastQEndDate.AddMonths(-3);
            } while (lastQEndDate > past);
        }

【讨论】:

    【解决方案2】:

    你可以使用我写的some time ago下面的类:

    DateTime dt1 = new DateTime(2012, 1, 1);
    DateTime dt2 = new DateTime(2013, 1, 15);
    long countQuarters = Quarter.GetQuarters(dt1, dt2); // outputs 4
    

    季度:

    public class Quarter
    {
        public static long GetQuarters(DateTime dt1, DateTime dt2)
        {
            double d1Quarter = GetQuarter(dt1.Month);
            double d2Quarter = GetQuarter(dt2.Month);
            double d1 = d2Quarter - d1Quarter;
            double d2 = (4 * (dt2.Year - dt1.Year));
            return Round(d1 + d2);
        }
    
        private static int GetQuarter(int nMonth)
        {
            if (nMonth <= 3)
                return 1;
            if (nMonth <= 6)
                return 2;
            if (nMonth <= 9)
                return 3;
            return 4;
        }
    
        private static long Round(double dVal)
        {
            if (dVal >= 0)
                return (long)Math.Floor(dVal);
            return (long)Math.Ceiling(dVal);
        }
    }
    

    DEMO

    【讨论】:

      【解决方案3】:

      我认为您可以使用% 运算符。例如:

      if (dt1.Month % 3 == 0)
      {
          // it is a quarter end, else it's not. 
      }
      

      【讨论】:

        【解决方案4】:

        我知道这是一个旧线程,但这里有一个 Lambda 表达式可以为您提供这些信息:

            private static List<Tuple<DateTime, DateTime>> GetQuarterDates(DateTime startDate, DateTime endDate)
            {
                List<Tuple<DateTime, DateTime>> quarterDates = new List<Tuple<DateTime, DateTime>>();
        
                quarterDates = Enumerable.Range(0, (endDate - startDate).Days)
                    .Where(x => startDate.AddMonths(x).Date == new DateTime(startDate.AddMonths(x).Year, (((startDate.AddMonths(x).Month - 1) / 3 + 1) - 1) * 3 + 1, 1))
                    .Select(x => new Tuple<DateTime, DateTime>(startDate.AddMonths(x), startDate.AddMonths(x + 3).AddDays(-1)))
                    .Where(x => x.Item2 <= endDate).ToList();
        
                return quarterDates;
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-05-05
          • 1970-01-01
          • 2021-03-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多