简体   繁体   English

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

[英]Javascript Get Sequential Dates in Array cross week and month

I have an array with the following values (example): 我有一个包含以下值的数组(示例):

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

Where the index is a date time. 索引是日期时间。 The date time will always be at 12:00:00 on a date. 日期时间始终为12:00:00。

In this example, the first 3 dates are consecutive cross weekend (weekend is holiday so count as leave), then another group of 3 dates cross weekend and month. 在这个例子中,前3个日期是连续的交叉周末(周末是假期所以算作休假),然后另外一组3个日期跨越周末和月份。

Now, what I am trying to do is find sequential dates (cross week and month) and put them into an array as follows: 现在,我要做的是查找连续日期(跨周和月)并将它们放入数组中,如下所示:

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

I have tried the following code to get the sequential dates but this cannot cross week and month, how to modify the code to get above result? 我已经尝试了以下代码来获取顺序日期,但这不能跨越一周和一个月,如何修改代码以获得上述结果? Any help would be much appreciated! 任何帮助将非常感激!

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;
});

Manipulation of timestamps is a pain. 操纵时间戳是一种痛苦。 JavaScript has a built-in Date type, as you know, and I would suggest you use it. 如你所知,JavaScript有一个内置的Date类型,我建议你使用它。 Date#getUTCDay returns the day of the week as an integer (for reference, 4 is Friday, or the day before a weekend), while Date#setUTCDate and Date#getUTCDate together allow you to adjust the date in day increments (and have it overflow/underflow to the next/previous month). Date#getUTCDay以整数Date#getUTCDay返回星期几(作为参考, 4表示星期五,或周末前一天),而Date#setUTCDateDate#getUTCDate一起允许您以天为单位调整日期(并具有它)溢出/下溢到下一个/上个月)。 Thus, to determine whether a timestamp b follows "sequentially" (excluding weekends) after a , you can use: 因此,为了确定一个时戳是否b遵循“顺序”(不包括周末)后a时,可以使用:

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

Grouping is just an exercise after that; 分组只是一种练习; the code above contains all of the real logic behind this solution. 上面的代码包含此解决方案背后的所有实际逻辑。


Example Snippet 示例代码段

 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)) 

This requires help from a function to test if two dates are in the same week. 这需要函数的帮助来测试两个日期是否在同一周。 The following goes over the set of time values provided in an array and puts the first value into an array within the array. 以下内容遍历数组中提供的时间值集合,并将第一个值放入数组中的数组中。 For each subsequent value, it tests if it's in the same week as the first value in each array within the outer array. 对于每个后续值,它测试它是否与外部数组中每个数组中的第一个值在同一周。

If it's in the same week as the first value in any existing array, it's pushed into that array. 如果它与任何现有数组中的第一个值处于同一周,则将其推入该数组。 Otherwise, it's put in a new array and pushed into the outer array. 否则,它将放入一个新数组并推入外部数组。

There may be a neater way to implement the algorithm, but I'll leave that for others. 可能有一种更简洁的方法来实现该算法,但我会将其留给其他人。

Due to time zone differences, they are adjusted to the host time zone based on the original time values representing noon in the source time zone. 由于时区差异,它们会根据源时区中午的原始时间值调整到主机时区。

 // 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'); }); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM