【问题标题】:Checking between date ranges javascript检查日期范围javascript
【发布时间】:2016-12-08 13:20:30
【问题描述】:

我目前正在开发一个系统,该系统具有基于日期范围的规则,

用户可以提交表单,我需要检查日期输入是否适合 3 个日期范围中的 1 个。基本上 2 个日期需要在以下 3 个规则中的 1 个内,

01/01 - 30/04 01/05 - 30/09 01/10 - 31/12,

我需要确定开始日期的月份和结束日期的月份,如果结束日期超出它的范围,请记录它。

所以基本上,如果用户提交 01/01/2017 作为开始日期和 10/02/2017 作为结束日期,这将是一个有效的输入,但如果用户输入 01/01/2017 作为开始日期日期,并将 01/06/2017 作为结束日期,因为该日期跨越多个日期范围,所以该日期无效。

是否可以用 javascript 检查这种事情?我经历了各种场景,但数组中的范围和检查数组值,但我一直让自己一团糟。

【问题讨论】:

  • 你已经添加了 momentjs 标志,所以看看他们的文档,它让一切变得简单!只需在您的开始日期和结束日期中创建两个时刻(例如var startMoment = moment(start_date)),然后您可以在刚刚创建的那一刻通过调用get('month') 来获取他们的月份。
  • 由于您的日期范围跨越一年,请考虑编写一个以日期为输入的函数,并根据日期所在的范围返回 0、1 或 2。然后您的任务就来了检查开始日期和结束日期的函数是否相同(有时您可能还会检查开始
  • 看起来您还需要检查两个用户日期是否相同。

标签: javascript date momentjs


【解决方案1】:

您可以简单地使用 getTime() 检查日期是否在范围内

JSBin

const isDateInRage = (startDate, endDate) => (dateToCheck) => {
  return dateToCheck >= startDate && dateToCheck <= endDate
}

const isInRangeOne = isDateInRage('2016-01-01', '2016-04-30')

console.log('inRange', isInRangeOne('2016-01-02'))
console.log('outtOfRange', isInRangeOne('2016-07-02'))

【讨论】:

  • 请注意,`new Date('2016-01-01') 会将日​​期视为 UTC,因此对于格林威治以西的用户来说,它似乎是 2015-12-31。此外,比较运算符会将日期转换为数字,因此不需要 getTime
  • 是的,但是由于我们只是比较具有相同字符串格式的日期,所以这不是问题。对于更复杂的逻辑,我首先推荐 moment.js。
  • 根据问题,看起来 > 应该是 >=
  • 应用了反馈
【解决方案2】:

试试这个

// parse string 'XX/XX/XXXX' to create date object
function parseDate(str) {
    var mdy = str.split('/');
    return new Date(mdy[2], mdy[0]-1, mdy[1]);
}

function daysBetween(date1, date2) {
    return Math.round((parseDate(date1)-parseDate(date2)) / (1000*60*60*24));
}

if(daysBetween('01/01/2017', '01/06/2017') > 1) {
    // Your code here
}

【讨论】:

  • 虽然这是一个很好的方法,但您应该解释您的代码如何解决 OP 的问题。此外,OP 只想知道特定日期是否在其他日期对的范围内,而不是两个日期之间的天数。
【解决方案3】:

考虑一个函数来测试每个范围的开始日期和结束日期,并在适合其中一个时返回 true。您需要正确解析字符串,并使用开始或结束日期的年份并将其应用于范围。

下面的函数使用开始日期,如果开始和结束在某个范围内,则返回 true,否则返回 false。如果提供的开始日期或结束日期无效,则会引发错误。

// Parse date in yyyy-mm-dd format as local date
function parseYMD(s) {
  var b = s.split(/\D/);
  var d = new Date(b[0], --b[1], b[2]);
  return d && d.getMonth() == b[1]? d : new Date(NaN);
}

// Check start and end date are within one of the valid ranges
var checkInRange = (function () {
  // Bespoke parser
  function parsePart(p, y) {
    p = p.split(/\D/);
    return new Date(y, p[1]-1, p[0]);
  }
  // Valid ranges as d/m, year is taken from start date
  var validRanges = ['01/01 - 30/04','01/05 - 30/09','01/10 - 31/12'];
    
  return function (startDate, endDate) {
    var dStart = parseYMD(startDate);
    var dEnd   = parseYMD(endDate);
    // Throw error if input dates aren't valid
    if (isNaN(dStart) || isNaN(dEnd)) {
      throw new Error('start or end date is invalid')
    }
    var year = dStart.getFullYear();
    // Return true if range is within valid ranges
    return validRanges.some(function(range) {
      var r = range.split(' - ').map(function(s){return parsePart(s, year)});
      return dStart >= r[0] && dEnd <= r[1];
    });
  }
})(); 

// Some tests
[['2016-01-01','2016-04-30'],['2016-03-30','2016-04-30'],['2017-04-30','2017-05-01']].
  forEach(function(dates) {
    console.log('Start and end: ' + dates[0] + ' - ' + dates[1] +
                '\nValid range?: ' + checkInRange(dates[0],dates[1]));
  });

不要使用 Date 构造函数(或 Date.parse)来解析字符串。它们的行为很大程度上取决于实现。 ISO 8601 格式的日期将被解析为 UTC,在这种情况下这是可以的,只要所有的字符串都被相同地解析,但是如果它们不是,用户将

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    相关资源
    最近更新 更多