【问题标题】:How can I calculate the number of "quarters" that have passed between 2 dates, where quarters are not simply a quarter of a year, but specific dates?如何计算两个日期之间经过的“季度”数,其中季度不仅仅是一年的四分之一,而是特定日期?
【发布时间】:2015-08-13 11:09:27
【问题描述】:

我正在尝试使用 Javascript 制作“租金欠款计算器”,其中一个理想的功能是可以选择计算每周、每月或每季度的租金。

如果按季度支付租金,则当日期超过某一天时,迟交的季度数会增加。这些季度日是每年 25/03、24/06、29/09/ 和 25/12。

当输入日期的月份大于季度日期的月份,但其日期小于季度的日期时,我的代码目前返回不正确的值。

即对于 2014 年 6 月 24 日的“第一次错过付款日期”和 2015 年 4 月 22 日的日期,这应该返回 4,而是返回 1。它应该返回 4,因为此时已经过去了 4 个季度日期( 24/06/2014、29/09/2014、25/12/2014 和 25/03/2015)。

这是我的代码:

function getNumberPeriods() {
        var years = (getNumberYears());
        var days = (getNumberDays());
        if ((getPeriodLength()) == "Weekly") {
            return ((days - (days % 7)) / 7);
        } else if ((getPeriodLength()) == "Monthly") {
            var months = ((((options.untilDate).getMonth()) + 1) - (((options.dueDate).getMonth()) + 1) + (12 * years));
            if (((options.untilDate).getDate()) < ((options.dueDate).getDate())) {
                months--;
            }
            return (months + 1);
        } else if ((getPeriodLength()) == "Quarterly") {
            if ((options.dueDate).getMonth() == 2) {
                if (((options.untilDate).getMonth() <= 5) && ((options.untilDate).getDate() < 24)) {
                    return (1+(years * 4));
                }
                else if (((options.untilDate).getMonth() <= 5) && ((options.untilDate).getDate() >= 24)) {
                    return (2+(years * 4));
                }
                else if (((options.untilDate).getMonth() <= 8) && ((options.untilDate).getDate() < 29)) {
                    return (2 + (years * 4));
                }
                else if (((options.untilDate).getMonth() <= 8) && ((options.untilDate).getDate() >= 29)) {
                    return (3 + (years * 4));
                }
                else if (((options.untilDate).getMonth() <= 11) && ((options.untilDate).getDate() < 25)) {
                    return (3 + (years * 4));
                }
                else if (((options.untilDate).getMonth() <= 11) && ((options.untilDate).getDate() >= 25)) {
                    return ((years * 4)+4);
                }
                else return (years * 4);
            }
            else if ((options.dueDate).getMonth() == 5) {
                if ((options.untilDate).getMonth() <= 2 && (options.untilDate).getDate() < 25) {
                    return (3 + (years * 4));
                }
                else if ((options.untilDate).getMonth() <= 2 && (options.untilDate).getDate() >= 25) {
                    return (4+(years * 4));
                }
                else if ((options.untilDate).getMonth() <= 8 && (options.untilDate).getDate() < 29) {
                    return ((years * 4)+1);
                }
                else if ((options.untilDate).getMonth() <= 8 && (options.untilDate).getDate() >= 29) {
                    return ((years * 4)+2);
                }
                else if ((options.untilDate).getMonth() <= 11 && (options.untilDate).getDate() < 25) {
                    return (2 + (years * 4));
                }
                else if ((options.untilDate).getMonth() <= 11 && (options.untilDate).getDate() >= 25) {
                    return (3 + (years * 4));
                }
                else return (years * 4);
            }
            else if ((options.dueDate).getMonth() == 8) {
                if ((options.untilDate).getMonth() <= 2 && (options.untilDate).getDate() < 25) {
                    return (2 + (years * 4));
                }
                if ((options.untilDate).getMonth() <= 2 && (options.untilDate).getDate() >= 25) {
                    return (3 + (years * 4));
                }
                else if ((options.untilDate).getMonth() <= 5 && (options.untilDate).getDate() < 24) {
                    return (3 + (years * 4));
                }
                else if ((options.untilDate).getMonth() <= 5 && (options.untilDate).getDate() >= 24) {
                    return (4+(years * 4));
                }
                else if ((options.untilDate).getMonth() <= 11 && (options.untilDate).getDate() < 25) {
                    return ((years * 4)+1);
                }
                else if ((options.untilDate).getMonth() <= 11 && (options.untilDate).getDate() >= 25) {
                    return ((years * 4)+2);
                }
                else return (years * 4);
            }
            else if ((options.dueDate).getMonth() == 11) {
                if ((options.untilDate).getMonth() <= 2 && (options.untilDate).getDate() < 25) {
                    return ((years * 4)+1);
                }
                else if ((options.untilDate).getMonth() <= 2 && (options.untilDate).getDate() >= 25) {
                    return ((years * 4)+2);
                }
                else if ((options.untilDate).getMonth() <= 5 && (options.untilDate).getDate() < 24) {
                    return (2 + (years * 4));
                }
                else if ((options.untilDate).getMonth() <= 5 && (options.untilDate).getDate() >= 24) {
                    return (3 + (years * 4));
                }
                else if ((options.untilDate).getMonth() <= 8 && (options.untilDate).getDate() < 29) {
                    return (3 + (years * 4));
                }
                else if ((options.untilDate).getMonth() <= 8 && (options.untilDate).getDate() >= 29) {
                    return ((years * 4)+4);
                }
                else return (years * 4);
            }
            else alert("not werkin");
        }
    }


    function getNumberDays() {
        return ((((options.untilDate)) - ((options.dueDate))) / (1000 * 60 * 60 * 24));
    }
    function getNumberYears() {
        var dueMonth = (options.dueDate).getMonth();
        var dueDay = (options.dueDate).getDate();
        var dueYear = (options.dueDate).getFullYear();
        var untilYear = (options.untilDate).getFullYear();
        var untilMonth = (options.untilDate).getMonth();
        var untilDay = (options.untilDate).getDate();
        var diffyears = untilYear - dueYear; 

        if (untilMonth < dueMonth - 1){
         diffyears--;
            }
        if (dueMonth - 1 == untilMonth && untilDay < dueDay){
        diffyears--;
            }
        return diffyears;

this 是我的 JS 小提琴的链接(我知道小提琴的其他部分无法正常工作,但我还没有接触到这些)。

任何帮助将不胜感激!

斑马线。

【问题讨论】:

  • 也就是说,你需要从(25/03, 24/06, 29/09/, 25/12 )集合中计算出给定时间段内的日期数,对吗?
  • 是的!没错

标签: javascript date if-statement logic calculator


【解决方案1】:

以下代码将传递的宿舍数计入passed

var quarters = [{'month':3, 'day':25}, {'month':6, 'day':24}, 
    {'month':9, 'day':29}, {'month':12, 'day':25}];

var year = options.dueDate.getFullYear();
var passed = 0; // this is the number of passed quarters
var quarterIndex = 0;
do {
    // month is 0 based
    var reference = new Date(
        year, 
        quarters[quarterIndex].month - 1, 
        quarters[quarterIndex].day);

    if( (reference >= options.dueDate) && (reference <= options.untilDate) ) {
        passed ++;
    }

    quarterIndex++;
    if(4 == quarterIndex) {
        quarterIndex = 0;
        year++;
    }
} while(reference < options.untilDate);

【讨论】:

    【解决方案2】:

    在您的代码中,您试图掩盖所有可能存在的情况。对于这个问题(以及大多数其他具有大量案例的问题),这不是一个很好的方法。相反,请尝试以不同的方式思考:您可以遍历季度日期,看看它们是否在dueDateuntilDate 之间的时间段内。但是,您缺少执行此操作的日期的 year 组件。我建议在开始时使用dueDate的年份构造Date对象,然后每次迭代增加年份,直到year变得大于untilDate的年份。

    这里是代码清单:

         } else if ((getPeriodLength()) == "Quarterly") {
            // We have an array of all the quarter dates
            var quarterDates = [
                {
                    'm': 3,
                    'd': 25
                },
                {
                    'm': 6,
                    'd': 24
                },
                {
                    'm': 9,
                    'd': 29
                },
                {
                    'm': 12,
                    'd': 25
                }];
            // The count of missed periods
            var count = 0;
            // Initial year value
            var year = options.dueDate.getFullYear();
            // Condition on when to stop
            while (year <= options.untilDate.getFullYear()) {
                for(var i in quarterDates) {
                    // Just a precaution, because foreach in js
                    // loops through all properties of the object
                    // and there might be functions and we want to
                    // skip them   
                    if (typeof(quarterDates[i]) != 'function') {
                        // Construct a Date object
                        // Note: months in js have numbers from 0 to 11
                        var qDate = new Date(year, quarterDates[i].m - 1, quarterDates[i].d);
                        // If the date is in the given period
                        if (qDate >= options.dueDate && qDate <= options.untilDate) {
                            // Increase the counter
                            count++;
                        }
                    }
                }
                // Increase the value
                year++;
            }
            return count;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 2019-02-11
      相关资源
      最近更新 更多