【问题标题】:JS Check if multiple dates are within rangeJS 检查多个日期是否在范围内
【发布时间】:2018-07-02 12:16:34
【问题描述】:

我有以下代码,其中我有一个到达日期和离开日期,并编辑它们的格式,以及一个禁用日期:

var aankomstDatum = "19-05-2018";
var parts = aankomstDatum.split('-');
aankomstDatumDate = new Date(parts[2],parts[1]-1,parts[0]);

vertrekDatum = "02-06-2018";
var parts2 = vertrekDatum.split('-');
vertrekDatumDate = new Date(parts2[2],parts2[1]-1,parts2[0]);

var aankomstDatumDateCheck = (aankomstDatumDate.getMonth() + 1) + '/' + aankomstDatumDate.getDate() + '/' +  aankomstDatumDate.getFullYear();
//alert(aankomstDatumDateCheck);

var vertrekDatumDateCheck = (vertrekDatumDate.getMonth() + 1) + '/' + vertrekDatumDate.getDate() + '/' +  vertrekDatumDate.getFullYear();
//alert(vertrekDatumDateCheck);

var disabledDates = "26-05-2018";
var partsdisabled = disabledDates.split('-');
var disableddatesDatumDate = new Date(partsdisabled[2], partsdisabled[1]-1, partsdisabled[0]); //alert(disableddatesDatumDate);

var disableddatesDatumDateCheck = (disableddatesDatumDate.getMonth() + 1) + '/' + disableddatesDatumDate.getDate() + '/' +  disableddatesDatumDate.getFullYear();
//alert(disableddatesDatumDateCheck);

if(dateCheck(aankomstDatumDateCheck,vertrekDatumDateCheck,disableddatesDatumDateCheck)) {
    console.log("Not available");
} else {
    console.log("Available");
}

function dateCheck() {
    return true;
}

基本上,如果禁用日期介于到达日期和离开日期之间,则 if-else 触发,否则触发 else。

此代码有效(万岁!),但我还没有。因为我计划将多个日期设置为 var disabledDates ,这就是我被卡住的地方。那么,如何编辑检查多个禁用日期的代码呢?

【问题讨论】:

  • 你能提供一个可行的例子吗?例如声明 aankomstDatumDate 并给它一个日期。如果您插入代码示例并将代码粘贴到 JavaScript 框(左下角),您将获得运行代码的运行脚本按钮。我还认为您的代码可以大大简化,当您有一个工作示例时,我很乐意这样做。
  • 好的,我从您发布的代码中删除了错误。到达日期是否应该在出发日期之前,即您不希望人们在假期/工作旅行期间包含禁用日期?这些日期是一个很好的测试用例:{ arrival: 25-05-2018, disabled: 26-05-2018, departure: 27-05-2018 }
  • 嗨,我在这里做了一个工作示例:jsfiddle.net/x3gys7wa 禁用日期最好在此测试的到达日期和出发日期之间,例如这意味着其他人在此期间已经预订了。如果您需要更多信息,我会尽力提供帮助!
  • 还用您的编辑编辑了问题 + 我如何在当前代码中获得到达和离开日期。

标签: javascript arrays date for-loop date-range


【解决方案1】:

这是您的代码的简化版本,可以按您的要求工作。我认为在测试时最好使用construct Date objects using ISO8601 格式化文本,即"2018-05-19"(它在UTC 中创建日期)。另请参阅答案末尾的提示。

点击代码下方的Run code snippet按钮查看控制台输出(比使用alert好多了):

var start = new Date("2018-05-19");
var end = new Date("2018-06-02");

var bookings = [
    new Date("2018-05-26"),
    new Date("2018-05-28")
];

if (validPeriod(start, end, bookings)) {
    console.log("no bookings found");
} else {
    console.log("found at least one booking");
}

function validPeriod(start, end, bookings) {
    var valid = true;

    for (var i = 0; i < bookings.length; i++) {
        var date = bookings[i];
        if (start <= date && date <= end) {
            valid = false;
            break;
        }
    }

    return valid;
}

提示

我强烈建议您使用Moment.js 处理日期。以后会省去你的麻烦。

如果您不选择 Moment.js,请记住,根据您创建日期的方式将取决于使用哪个时区,以及根据您计算机的时区显示哪个日期,一种简单的方法是使用新的 Date(year, month, day, hours, minutes, seconds) 构造函数:

// for a browser/computer in timezone GMT+0200 (Paris)

// create a local date
new Date(2018, 5-1, 18).toString() // "Fri May 18 2018 00:00:00 GMT+0200 (CEST)"
new Date(2018, 5-1, 18).toISOString() // "2018-05-17T22:00:00.000Z"

// create a UTC date
new Date(Date.UTC(2018, 5-1, 18)).toString() // "Fri May 18 2018 02:00:00 GMT+0200 (CEST)"
new Date(Date.UTC(2018, 5-1, 18)).toISOString() // "2018-05-18T00:00:00.000Z"

// for a browser/computer in timezone GMT-0400 (New York)

// create a local date
new Date(2018, 5-1, 18).toString() // "Fri May 18 2018 00:00:00 GMT-0400 (EDT)"
new Date(2018, 5-1, 18).toISOString() // "2018-05-18T04:00:00.000Z"

// create a UTC date
new Date(Date.UTC(2018, 5-1, 18)).toString() // "Thu May 17 2018 20:00:00 GMT-0400 (EDT)"
new Date(Date.UTC(2018, 5-1, 18)).toISOString() // "2018-05-18T00:00:00.000Z"

但请注意您是否为 Date 构造函数使用字符串,因为它在内部使用 Date.parse(dateString),有时它被解释为本地日期,有时被解释为 UTC:

// for a browser/computer in timezone GMT-0400 (New York)
new Date("08-19-2018"); // Sun Aug 19 2018 00:00:00 GMT-0400 (EDT) <-- local
new Date("08/19/2018"); // Sun Aug 19 2018 00:00:00 GMT-0400 (EDT) <-- local
new Date("2018-05-19"); // Fri May 18 2018 20:00:00 GMT-0400 (EDT) <-- UTC
new Date("2018/05/19"); // Sat May 19 2018 00:00:00 GMT-0400 (EDT) <-- local

【讨论】:

  • 非常感谢!对于这个项目,我无法使用 JS 库(客户端,嗯?),所以这就是为什么这个项目如此困难。你帮了我很多!
  • @KevinVerhoeven 接受我的回答,我会更乐意提供帮助 ;o)
  • "测试时最好使用 ISO8601 格式的文本构造 Date 对象"——不一定。内置解析器会将“2018-05-19”解析为 UTC,而用户可能希望将其解析为本地(即按照 ISO 8601)。
  • @RobG 这就是为什么我在带有 ISO8601 的 Date 构造函数参数上发送了一个指向 MDN 的链接,以及为什么我提到 Moment.js 如果使用不当,JavaScript 中的日期可能会出现问题。
  • @RobG 我将额外提及他的示例使用本地时区,而我的答案使用 UTC。
【解决方案2】:

添加到@djdavemark 的答案,

您还可以使用 JavaScript 在 build some 函数中检查是否有任何日期在给定范围内。

正如@RobG 提到的,对于某些浏览器,这些日期字符串可能会给出错误的结果,因此为了安全起见,您可以以Date constructor 接受的方式显式格式化。

来自@CMS 的回答Question: Why does Date.parse give incorrect results?

function parseDate(input) {
  var parts = input.split('-');
  // new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
  return new Date(parts[2], parts[1]-1, parts[0]); // Note: months are 0-based
}  

var startData = parseDate("19-05-2018")
var endDate = parseDate("25-05-2018")

var dateSet = [
"20-05-2018",
"21-05-2018",
"22-05-2018"
];

var dateSet2 = [
"26-05-2018",
];

function inBetween(element, index, array) {
  return parseDate(element) >= startData && parseDate(element) <= endDate;
}

console.log(dateSet.some(inBetween))

console.log(dateSet2.some(inBetween))

这看起来更优雅。

更多关于数组some方法MDN Docs的信息

【讨论】:

  • MDN 不是“官方文档”,它是一个由 Mozilla 托管的公共 wiki,任何人都可以参与其中。唯一的“官方”文档是语言标准ECMA-262。也不建议使用内置解析器,在许多浏览器(例如 Chrome)中 new Date("19-05-2018") 将返回无效的日期。见Why does Date.parse give incorrect results?
  • 感谢@RobG 的反馈,我已经相应地更新了答案。
  • 您应该将您的代码发布为可运行的 sn-p,这将表明它无法正常工作。您将数组中的值作为字符串传递,然后与 Date 对象进行比较。两者都将被强制输入 Number,并且“20-05-2018”的计算结果为 NaN。 NaN 永远不会 false(请参阅 Abstract Relational Comparison algorithm)。
  • 感谢您也添加此见解!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-26
  • 2016-01-25
相关资源
最近更新 更多