Javascript获取阵列中的连续日期交叉周和月

时间:2017-03-09 04:32:48

标签: javascript arrays date

我有一个包含以下值的数组(示例):

[
  1491408000000,
  1491494400000,
  1491753600000,
  1493222400000,
  1493308800000,
  1493568000000
]

索引是日期时间。日期时间始终为12:00:00。

在此示例中,前3个日期是连续的交叉周末(周末是假期,因此算作休假),然后另外一组3个日期跨越周末和月份。

现在,我要做的是查找连续日期(跨周和月)并将它们放入数组中,如下所示:

[
  1491408000000,
  1491494400000,
  1491753600000
],
[
  1493222400000,
  1493308800000,
  1493568000000
]

我已经尝试了以下代码来获取顺序日期,但这不能跨越一周和一个月,如何修改代码以获得上述结果?任何帮助将不胜感激!

var timeValue = new Date(dateReview).getTime(); 
valueCon.push(timeValue);                                           

var k = 0;   
sortedValue[k] = [];

valueCon.sort( function ( a, b ){
    return +a > +b ? 1 : +a == +b ? 0: -1;
})
.forEach( function( v , i ){
    var a = v,b = valueCon[i+1]||0;

    sortedValue[k].push( +a );

    if ( (+b - +a) > 86400000) {                                
        sortedValue[++k] = []
    }
    return 1;
});                     

sortedValue.sort( function ( a,b ){
    return a.length > b.length ? -1: 1;
});

2 个答案:

答案 0 :(得分:0)

操纵时间戳是一种痛苦。如你所知,JavaScript有一个内置的Date类型,我建议你使用它。 Date#getUTCDay以整数形式返回星期几(供参考,4是星期五,或周末前一天),而Date#setUTCDateDate#getUTCDate一起允许您以天为单位调整日期(并使其溢出/下溢到下一个/上个月)。因此,确定时间戳b是否遵循"顺序" a之后(周末除外),您可以使用:

function sequential (a, b) {
  a = new Date(a)
  return a.setUTCDate(a.getUTCDate() + (a.getUTCDay() === 4 ? 3 : 1)) === b
}

分组只是一种练习;上面的代码包含了这个解决方案背后的所有真实逻辑。

<小时/>

示例代码段

&#13;
&#13;
var dates = [
  1491408000000,
  1491494400000,
  1491753600000,
  1493222400000,
  1493308800000,
  1493568000000
]

function sequential (a, b) {
  a = new Date(a)
  return a.setUTCDate(a.getUTCDate() + (a.getUTCDay() === 4 ? 3 : 1)) === b
}

function groupSequential(dates) {
  if (dates.length < 2) return [dates.slice()]
  dates.sort(function(a, b) { return a - b })
  
  var result = [], group
  for (var i = 0; i < dates.length; i++) {
    sequential(dates[i - 1], dates[i]) || result.push(group = [])
    group.push(dates[i])
  }
  return result
}

console.log(groupSequential(dates))
&#13;
&#13;
&#13;

答案 1 :(得分:0)

这需要函数的帮助来测试两个日期是否在同一周。以下内容遍历数组中提供的时间值集合,并将第一个值放入数组中的数组中。对于每个后续值,它测试它是否与外部数组中每个数组中的第一个值在同一周。

如果它与任何现有数组中的第一个值在同一周,则会将其推入该数组。否则,它将放入一个新数组并推入外部数组。

可能有一种更简洁的方法来实现该算法,但我会将其留给其他人。

由于时区差异,它们会根据源时区中午的原始时间值调整为主机时区。

// Given 2 dates, return true if they are in the same week (Mon to Sun).
// Otherwise, return false
function sameWeek(a, b){
  var e = new Date(+a);
  // Week starts at 00:00:00.000 on Monday on or before date
  var s = new Date(e.setDate(e.getDate() - ((e.getDay()||7) -1)));
  s.setHours(0,0,0,0);
  // Week ends at 23:59:59.999 the following Sunday 
  e.setDate(e.getDate() + 6);
  e.setHours(23,59,59,999);
  // Test b and return value
  return b >= s && b <= e;
}

// Given time value for UTC-0400, adjust to same date and time
// in local time zone and return a date
function adjust(n) {
  var d = new Date(n);
  d.setMinutes(d.getMinutes() - 240 + d.getTimezoneOffset());
  return d;
}

var result = [1491408000000,1491494400000,1491753600000,1493222400000,1493308800000,1493568000000
].reduce(function(acc, n) {
  var d = adjust(n);
  var used;
  if (acc.length != 0) {
    used = acc.some(function(arr) {
      if (sameWeek(adjust(arr[0]), d)) {
        arr.push(n);
        return true;
      }
    });
  }
  if (!used || acc.length == 0) {
    acc.push([n]);
  }
  return acc;
},[]);

// Result array
console.log(result);

// Printed as date strings adjusted to same host local time
result.forEach(arr => {
  arr.forEach(n => console.log(adjust(n).toString()))
  console.log('\n');
});