高级javascript日期范围函数,用于调整参考起始月/期间范围

高级javascript日期范围函数,用于调整参考起始月/期间范围,javascript,jquery,math,datetime,Javascript,Jquery,Math,Datetime,解释这一点很棘手,但找到最简单的方法可能是一个有趣的挑战,我昨天花了几个小时试图重构.NETC#位代码,但没有想出任何优雅的方法 因此,任何一个有着良好的JavaScript、数学和解决日期问题头脑的人都可能有一个很好的灯泡时刻 我基本上需要能够生成日期范围的开始(和结束)。i、 e.过去12个月、过去6个月、过去24个月等 但这不仅仅是一个简单的CurrentDate减去年份类型的问题 我们使用期间范围来可视化我们呈现的数据,即每月、双月、季度、半年。但我们也有一个参考月,期间范围应基于,即期

解释这一点很棘手,但找到最简单的方法可能是一个有趣的挑战,我昨天花了几个小时试图重构.NETC#位代码,但没有想出任何优雅的方法

因此,任何一个有着良好的JavaScript、数学和解决日期问题头脑的人都可能有一个很好的灯泡时刻

我基本上需要能够生成日期范围的开始(和结束)。i、 e.过去12个月、过去6个月、过去24个月等

但这不仅仅是一个简单的CurrentDate减去年份类型的问题

我们使用期间范围来可视化我们呈现的数据,即每月、双月、季度、半年。但我们也有一个参考月,期间范围应基于,即期间范围应始终从7月开始。因此,无论当前日期是什么,从7月1日开始到9月30日,你总能得到一个干净的季度

考虑到这一点,我们总是希望开始日期考虑到这个参考,参考将始终是一个月,因此所有开始日期将是一个月的第一个。结束日期将是一个月的最后一天,而FYI的大部分时间实际上将在当前日期之后,因为我们希望最后的期间范围包括今天的日期

所以我们需要一个可以传入的函数(我已经包含了示例值):

上述问题的答案如下,因为它符合以下范围:

01 JAN 2012 - 31 MAR 2012
01 APR 2012 - 31 JUN 2012
01 JUL 2012 - 30 SEP 2012
01 OCT 2012 - 31 DEC 2012

returns startDate = 01 JAN 2012
returns endDate = 31 DEC 2012
这是正确的,因为我们的周期开始于7月份,我们将今天的日期包括在最终范围内

显然,它还需要有利于与前几年的重叠。因此,另一个例子可能是:

currentDate = 10 FEB 2012
dateRangeInMonths = 6 (Half Year)
periodRangeInMonths = 2 (Bimonthly)
periodRangeReferenceStartMonth = 1 (Jan)
答复:

01 SEP 2011 - 31 OCT 2011
01 NOV 2011 - 31 DEC 2011
01 JAN 2012 - 29 FEB 2012

returns startDate = 01 SEP 2011
returns endDate = 29 FEB 2012
另外,如果它有任何帮助的话,这是一个c#位的代码,它做我想要的,但远不是优雅的,并且依赖于时间循环等等。所以你可能想忽略它哈哈

if (this.PeriodRangeInMonths > 1)
{
    this.StartDate = new DateTime(DateTime.Now.Year, this.PeriodRangeReferenceStartMonth, 1).AddMonths(0 - this.DateRangeInMonths);
    var temp = DateTime.Now.AddMonths(0 - this.DateRangeInMonths).AddMonths(this.PeriodRangeInMonths);
    while (this.StartDate.AddMonths(this.PeriodRangeInMonths) < temp)
        this.StartDate = this.StartDate.AddMonths(this.PeriodRangeInMonths);
}
else this.StartDate = new DateTime(DateTime.Now.AddMonths(1).Year, DateTime.Now.AddMonths(1).Month, 1).AddMonths(0 - this.DateRangeInMonths);
this.EndDate = this.StartDate.AddMonths(this.DateRangeInMonths);
if(this.PeriodRangeInMonths>1)
{
this.StartDate=new DateTime(DateTime.Now.Year,this.periodRangeReferencesStartMonth,1).AddMonths(0-this.DateRangeInMonths);
var temp=DateTime.Now.AddMonths(0-this.DateRangeInMonths).AddMonths(this.PeriodRangeInMonths);
while(this.StartDate.AddMonths(this.PeriodRangeInMonths)

我也愿意使用任何第三方jquery库,这些库可能会对数学或日期函数等有所帮助。

我想我已经掌握了数学知识:

这里有一个javascript解决方案,但适应另一种语言应该不会太难

function getDateRange(refDate, monthRange, periodMonths, startMonth) {
    var datePeriodOffset = Math.floor((refDate.getMonth() - startMonth)/periodMonths);
    var endMonth = startMonth + datePeriodOffset*periodMonths - 1 + periodMonths;   
    var endDate = new Date(refDate.getFullYear(), endMonth+1, 0);  // the 0 sets it to the last day of the previous month (endMonth)
    var startDate = new Date(endDate.getFullYear(), endDate.getMonth() - monthRange + 1, 1);

    return {
        start : startDate,
        end : endDate
    };
}

第一个答案不应该是2012年7月到2013年6月吗?不,参考月仅用于决定季度/双月期何时应在2012年6月拆分。返回的实际日期范围将始终具有上一季度的当前日期。因此,它总是在过去而不是未来工作并获得一个日期范围。这是一个很难解释的问题,但是我已经检查了我的例子,并且非常确定我的例子是正确的。第二个例子的开始日期应该是2011年9月吗?另外,你希望当前日期是在最后一个季度,还是最后一个期间?啊,是的,那一个是错误的,我现在已经编辑过了。当前日期总是在最后一个“periodRangeInMonths”期间结束。这可能是两个月、四个月、六个月,取决于传入的值。哦,看起来很有趣,只是突然走出办公室吃午饭,但我回来后会看一看,如果它完成了工作,我会接受:)谢谢你的时间!!嗯,这可能显示了几个月的错误结束日期。我刚刚意识到7月和8月有31天的连续时间,所以结束日期的逻辑有点不正确。做一些快速的研究,我想我已经找到了一个解决方案。我已经能够使用我找到的方法来减少大量的代码,以获得月的最后一天,以及一些其他重构。
function getDateRange(refDate, monthRange, periodMonths, startMonth) {
    var datePeriodOffset = Math.floor((refDate.getMonth() - startMonth)/periodMonths);
    var endMonth = startMonth + datePeriodOffset*periodMonths - 1 + periodMonths;   
    var endDate = new Date(refDate.getFullYear(), endMonth+1, 0);  // the 0 sets it to the last day of the previous month (endMonth)
    var startDate = new Date(endDate.getFullYear(), endDate.getMonth() - monthRange + 1, 1);

    return {
        start : startDate,
        end : endDate
    };
}