首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >决定下一次付款续期日期

决定下一次付款续期日期
EN

Code Review用户
提问于 2014-10-08 09:39:25
回答 2查看 536关注 0票数 2

我不是一个很好的JavaScript,当然不是日期操纵,但我黑了下面的脚本,目的是确定下一个付款更新日期基础上的开始日期和付款期限。脚本完成了它应该做的事情。脚本是数据转换的一部分,数据转换中的每一行都会运行该转换(戊a)。它有110万行,因此性能非常重要。Who有提高性能的想法(目前我的i5上只有18行/秒)。

代码语言:javascript
复制
var renewaldate = new Date(START_DATE.getTime());
var renewalday = START_DATE.getDate();
var renewalmonth = START_DATE.getMonth();
var renewalyear = START_DATE.getYear();
var paymentterm= 12 / PAYMENTS_PER_YEAR;
var today = new Date();

while (renewaldate - today < 0) {
    renewalmonth = renewalmonth + paymentterm;
    if (renewalmonth > 12) {
        renewalmonth = renewalmonth - 12;
        renewalyear++;
    }
    renewaldate.setFullYear(renewalyear, renewalmonth, renewalday);
}
EN

回答 2

Code Review用户

发布于 2014-10-08 14:00:27

一个有趣的问题..。

我假设PAYMENTS_PER_YEAR的值只能是以下内容:

代码语言:javascript
复制
var paymentFrequencies = [ 1 , 2 , 3 , 4 , 6 , 12 ];

如果是这样的话,那么renewalyear只能是今天的一年或明天的一年。

我会创建一个缓存,预先计算每个月和每个支付频率下一个付款月份是什么,以及是否会跳过一年。

然后,你可以简单地使用一个查询来确定下一个付款月份是什么时候,没有比这更快的方法了。

我目前正在考虑建设这一点,这是绝对可能的,但比预期稍难;)

这就是我所拥有的,我对它进行了一些测试,校长应该很清楚:

代码语言:javascript
复制
function createCache( monthsOffset ){
  var cache = {},
      paymentFrequencies = [ 1 , 2 , 3 , 4 , 6 , 12 ],
      todaysMonth = (new Date ()).getMonth() + monthsOffset,
      renewalYear, renewalMonth, targetMonth, frequency, monthsShort, nextYear, term;
  for( var month = 0 ; month < 12 ; month++ ){
    cache[month] = {};
    for( var i = 0 ; i < paymentFrequencies.length ; i++ ){
      frequency = paymentFrequencies[i];
      term = 12 / frequency;
      targetMonth = todaysMonth < month ? todaysMonth + 12 : todaysMonth;
      monthsShort = ( targetMonth - month ) % term;
      cache[month][frequency] = todaysMonth + (monthsShort ? term - monthsShort : 0);
      
    }
  }
  return cache;
}

var stillThisMonth = createCache( 0 ),
    nextMonth = createCache(1);

function determineRenewalDate( startDate , paymentsPerYear  ){

    var today = new Date(),
        todaysYear =  today.getFullYear();
        startMonth =  startDate.getMonth();
  /*Compare the days, if we renew say monthly, and we start on the 15th, 
    but today is the 20, then we need to renew for next month, if we are the
    the 8th then you can stick to this month */    
  var todaysDayOfTheMonth = today.getDate(),
      startDayOfTheMonth = startDate.getDate();
  //One more cool thing, `setFullYear` and `new Date` will roll over the year if you set the month too high
  if( todaysDayOfTheMonth > startDayOfTheMonth  ){
     return new Date( todaysYear, nextMonth[startMonth][paymentsPerYear], startDayOfTheMonth );
  } else {
     return new Date( todaysYear, stillThisMonth[startMonth][paymentsPerYear], startDayOfTheMonth );
  }    
}


document.write(  determineRenewalDate( new Date(2010 , 1 , 1 ) , 12 ) + '<br>' );
document.write(  determineRenewalDate( new Date(2010 , 1 , 2 ) , 2 ) + '<br>' );
票数 3
EN

Code Review用户

发布于 2014-10-08 10:35:37

第一个问题是:二月怎么样?

代码语言:javascript
复制
> var a = new Date()
undefined
> a.setFullYear(2014, 2, 30)
1396175283793
> a
Sun Mar 30 2014 18:28:03 GMT+0800 (CST)

同样,如果最后一次付款是在5月31日,而每年支付的金额是12次,那会发生什么呢?

第二,每秒18行是否意味着每秒18次转换?你确定瓶颈是这个转变吗?还是很久以前就开始约会了?

优化的一种方法是:您可以简单地将更新年设置为今年,因为每年的付款数量可以被12整除。

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/65070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档