通过 javascript 比较页面上的多个日期字段

Compare multiple date fields on a page through javascript

如何有效地比较页面上给定日期的动态日期数?

考虑以下代码:

<div id="dateFields">
    <input type="date" id="date1"/>
    <input type="date" id="date2"/>
    <input type="date" id="date3"/>
    <input type="date" id="date4"/>
    <input type="date" id="date5"/>
</div>
<div id="masterDate">
    <input type="date" id="comparator"/>
</div>
<button onClick="compareDate()">Compare Now</button>

考虑 div 和 id="dateFields 中的日期是随机数。现在说5。 div 和 id="comparator 中的日期是我们需要比较所有日期的日期。

现在,例如,如果比较日期设置为 "March, 2015" 并且 dateFields 中的所有值都由用户动态设置(比如 "Feb, 2002"、"Dec, 2010"、"Aug, 2016"、"Jul, 2019" 和 "Nov, 2015")。我应该在函数 compareDate() 中编写最有效和通用的代码是什么,以便输出带来所有大于比较器的日期。

编辑: 这是我的 javascript 函数。但是,我认为这不是有效的方法。即使这对动态值数量也不利。

function compareDate() {
    var v1 = document.getElementById("date1").value;
    var v2 = document.getElementById("date2").value;
    var v3 = document.getElementById("date3").value;
    var v4 = document.getElementById("date4").value;
    var v5 = document.getElementById("date5").value;
    var v6 = document.getElementById("comparator").value;
    var v7 = [ v1, v2, v3, v4, v5 ];
    var result = "";

    for (i = 0; i < v7.length; i++) {
        console.log(solidify(v7[i]));

        if (solidify(v6) < solidify(v7[i])) {
            result += v7[i];
        }
    }

    document.getElementById("result").innerHTML = result;
}

function solidify(date) {
    var tempResult = '';

    for (i = 0; i < date.length; i++) {
        if (date.charAt(i) == '-') {
            continue;
        }
        else {
            tempResult += date.charAt(i);
        }
    }

    return tempResult;
}

编辑 2: 举例说明要求。

不需要任何文本框,它可能只是一组 <td><p> 或者可能只是一个包含日期数量的 <div>,这可能会有所不同从最少 2 个日期到最多 50 个日期(比方说)。

我只是在寻找逻辑,因此尝试使用文本框。

举一个实时示例,考虑一个城市管理系统,它跟踪该城市每月发生的死亡人数。现在,一个职员想知道当月15日之后死亡的公民的详细信息,他将如何获得数据?

function compareDate() {
  var dateFields = document.getElementById('dateFields').getElementsByTagName('input');
  var comparatorDate = new Date(document.getElementById('comparator').value);
  var rslt = [];
  for (var i = 0; i < dateFields.length; i++) {
    if (new Date(dateFields[i].value) > comparatorDate) rslt.push(dateFields[i].value);
  }
  return rslt;
}

这已在 chrome

中测试

您可以通过以下方式进行:

 <script>
            function compareDate() {
                var v1 = document.getElementById("date1").value;
                var v2 = document.getElementById("date2").value;
                var v3 = document.getElementById("date3").value;
                var v4 = document.getElementById("date4").value;
                var v5 = document.getElementById("date5").value;
                var v6 = document.getElementById("comparator").value;
                var v7 = [ v1, v2, v3, v4, v5 ];
                var finalResult = "";
                for (k = 0; k < v7.length; k++) {
                    if (solidify(v6) < solidify(v7[k])) {
                        finalResult += v7[k];
                        finalResult += " and ";

                    }

                }
                document.getElementById("result").innerHTML = finalResult;
            }
            function solidify(date) {
                var result = '';
                for (i = 0; i < date.length; i++) {
                    if (date.charAt(i) == '-') {
                        continue;
                    } else {
                        result += date.charAt(i);

                    }

                }
                return result;
            }
        </script>

下面的代码可以满足您的要求,但您仍然需要确定一些要求,才能真正做到 "generic"(请参阅下面的代码):

HTML

<div id="dateFields">
    <input type="date" id="date1"/>
    <input type="date" id="date2"/>
    <input type="date" id="date3"/>
    <input type="date" id="date4"/>
    <input type="date" id="date5"/>
</div>

<div id="masterDate">
    <input type="date" id="comparator"/>
</div>

<div id="results">
    Results: <span id="resultDates"></span>
</div>

<button onClick="compareDate()">Compare Now</button>

JavaScript

<script>
    function compareDate() {
        var aDates = document.getElementById("dateFields").getElementsByTagName("input");
        var sCompareDate = document.getElementById("comparator").value;
        var dCompareDate = formatDate(sCompareDate);
        var result = "";

        for (i = 0; i < aDates.length; i++) {
            var sCurrDate = aDates[i].value;

            if (dCompareDate < formatDate(sCurrDate)) {
                if (result.length > 0) {
                    result += ", ";
                }

                result += sCurrDate;
            }
        }

        if (result === "") {
            result = "No dates less than " + sCompareDate;
        }

        document.getElementById("resultDates").innerHTML = result;
    }

    function formatDate(sDate) {
        var regMonthYear = /[a-z]{3}, \d{4}/i;

        if (regMonthYear.test(sDate)) {
            sDate = sDate.replace(",", " 1,");
        }

        return new Date(sDate);
    }
</script>

还有待解决的事情:

  1. 您必须比较 Date 个对象,而不是字符串。

要完成您想要做的事情,您必须使用 JavaScript Date 个对象。即使您使用 <input> 和 "date" 的 type 属性,它的值仍然是一个字符串。如果你比较它,就像问 "orange" 是否小于 "house" 一样。 . . JavaScript 会给你一个答案,但它与你要找的东西没有任何关系。

JavaScript Date 对象内置了比较功能,可以满足您的需求。

2 您需要为您的日期输入制定某种标准,并确保您有代码来执行它们。

虽然 Date 对象在创建新实例时接受的输入非常灵活,但它确实有其局限性。您可以查看这两个链接以获取有关创建日期的有效字符串格式的更多信息:

ISO 日期格式 - https://msdn.microsoft.com/en-us/library/ie/ff743760%28v=vs.94%29.aspx#ISO

其他日期解析规则 - https://msdn.microsoft.com/en-us/library/ie/ff743760%28v=vs.94%29.aspx#OtherDateFormats

一旦您确定了最适合您的需求的格式,您真的应该设置一个您想要使用的通用格式(或一组格式),并在您的输入中强制使用该格式验证规则。如果不这样做,您将不得不添加大量逻辑来验证所有不同的可能性,以便您知道在尝试创建对象时将获得一个有效的 Date 对象。

3 您需要为您的结果提出某种标准输出。

理想情况下,如果您想创建一个真正的 "generic" 日期比较函数来满足您的要求,您希望它只专注于比较而不是其他。像这样:

function compareDate(aDateGroup, dComparisonDate)
    var aGreaterThanDates = [];

    for (i = 0; i < aDateGroup.length; i++) {
        if (dCompareDate < aDateGroup[i]) {
            aGreaterThanDates.push(aDateGroup[i]);
        }
    }

    return aGreaterThanDates;
}

。 . .其中 aDateGroupDate 个对象的数组,dCompareDate 也是一个 Date 对象。

该函数将接收日期,比较它们,然后传回通过测试的日期。然后您可以循环遍历返回的数组并根据需要处理这些日期。

这还允许您从任何来源传递日期(即,像您在第二个步骤中提到的 <td><p><div> 元素的集合更新),只要首先将它们转换为正确的 Date 对象。

  1. 判断是否需要灵活比较。

上面的 "ideal code" 实际上甚至可以 "more ideal" 通过在比较函数中添加一些灵活性,通过添加一些参数来指示要进行哪种比较:

function compareDate(aDateGroup, dComparisonDate, sCompareDirection, bIncludeComparisonDate)
    var aPassedDates = [];

    for (i = 0; i < aDateGroup.length; i++) {
        if (sCompareDirection === "before") {
            if (bIncludeComparisonDate) {
                if (dCompareDate >= aDateGroup[i]) {
                    aPassedDates.push(aDateGroup[i]);
                }
            }
            else {
                if (dCompareDate > aDateGroup[i]) {
                    aPassedDates.push(aDateGroup[i]);
                }
            }
        }
        else if (sCompareDirection === "after") {
            if (bIncludeComparisonDate) {
                if (dCompareDate <= aDateGroup[i]) {
                    aPassedDates.push(aDateGroup[i]);
                }
            }
            else {
                if (dCompareDate < aDateGroup[i]) {
                    aPassedDates.push(aDateGroup[i]);
                }
            }
        }
        else {
            if (dCompareDate == aDateGroup[i]) {
                aPassedDates.push(aDateGroup[i]);
            }
        }
    }

    return aPassedDates;
}

sCompareDirection 参数可以让您确定比较的方向。 "before" 将检查小于比较日期的值,"after" 将检查大于比较日期的值,任何其他值(或无值)将检查日期是否相等。

bIncludeComparisonDate 参数允许您将比较日期作为匹配的一部分。 true 的值会将 "greater than" 与 "greater than or equal to" 进行比较,将 "less than" 与 "less than or equal to" 进行比较。

结论

日期比较实际上是一个相当普遍的过程,但也是一个需要大量思考才能变得灵活和万无一失的过程。如果您不及早发现其中的一些问题,那么当您尝试重用您构建的内容时,您会在与您最初设置的内容不完全匹配的情况下自取其辱。 :)