鉴于您有一系列日期范围
var arr = [
{
"from": 'unix 1st of august',
"until": 'unix 5th of august'
},
{
"from": 'unix 15th of august',
"until": 'unix 20th of august'
},
{
"from": 'unix 25th of august',
"until": 'unix 31th of august'
}
];
找到漏洞的最简单方法是什么?在时间范围内?在这种情况下,直到第15和第20,直到第25日失踪。
function findDateRangeHoles() {
let chunks = [];
arr.forEach(range => {
// ??
chunks.push({from: '?', until: '?'});
});
// Return value example, array of object, each holding a missing date range chunk
[
{
from: 'unix 5th of august',
until: 'unix 15th of august'
},
{
from: 'unix 20th of august',
until: 'unix 25th of august'
}
]
return chunks;
}
let missingChunks = findDateRangeHoles(1st of August, 31 of August); // Array of objects
想知道如果有什么东西适合它吗?
答案 0 :(得分:2)
以下是一个示例,但在将来,您应该发布真实的尝试,您发布的内容并未显示您已尝试过。
对它们进行排序,并将范围a的结尾与范围b的开头进行比较,作为数字。执行此操作后,将您创建的from和until转换为日期范围
// Assuming they are sorted
var ranges = [{
from: 946702800, // +new Date(2000, 0, 1) / 1000
until: 949381200 // +new Date(2000, 1, 1)
},{
from: 954565200,
until: 957153600
},{
from: 962424000,
until: 965102400
}];
var holes = [];
for (var i=1; i < ranges.length; i++) {
var beginningOfHole = ranges[i-1].until;
var endOfHole = ranges[i].from;
if (beginningOfHole < endOfHole) {
holes.push({from: beginningOfHole + 1, until: endOfHole - 1});
}
}
console.log('holes in ranges', holes.map(hole => ({
from: new Date(hole.from * 1000), // Convert unix timestamp into JS timestamp
until: new Date(hole.until * 1000)
})));
答案 1 :(得分:1)
以下是ES6中的另一个示例,希望您能够了解为什么拥有一些测试数据并了解预期结果非常重要,并始终显示您尝试过的内容。
输出与人类可读范围不符,您需要考虑并调整您的期望或调整代码以符合您的期望,我会将此练习留给您。
// Unix time is in seconds since the Epoch, Javascript is milliseconds
// Date input UTC
// Month is zero indexed 0-11
// Time is 00:00:00.000
function getUnixTime(year, month, day) {
return Date.UTC(year, month, day) / 1000;
}
// Your example data for 2016
// You state that your data is sorted by `from`
const ranges = [{
from: getUnixTime(2016, 7, 1),
until: getUnixTime(2016, 7, 5)
}, {
from: getUnixTime(2016, 7, 15),
until: getUnixTime(2016, 7, 20)
}, {
from: getUnixTime(2016, 7, 25),
until: getUnixTime(2016, 7, 31)
}];
// Calculate `holes`
let previousRange;
const holes = [];
for (let range of ranges) {
if (previousRange && previousRange.until < range.from) {
// Add and substract 1 second to get `hole` and store
holes.push({
from: previousRange.until + 1,
until: range.from - 1
});
}
previousRange = range;
}
console.log('holes object: ', holes);
// Convert `holes` into human readable UTC string
function unixTimeToJavascriptUTC(seconds) {
return new Date(seconds * 1000).toUTCString();
}
for (let hole of holes) {
const from = unixTimeToJavascriptUTC(hole.from);
const until = unixTimeToJavascriptUTC(hole.until);
console.log(`From: ${from}, Until: ${until}`);
}
答案 2 :(得分:1)
所以,花了好几个小时之后..(对不起家伙,如果不存在范围,给定的答案没有给出一个块,所以不得不继续尝试)。
但无论如何,这是我最终使用的。
function getGapsFromRangesArray(from, until, ranges) {
let chunks = [],
i = 0, len = ranges.length, range;
let _from = from;
// If there are no ranges cached, create one big chunk for entire range.
if (!len) {
chunks.push({from: from, until: until});
} else {
for (; i < len; i++) {
range = ranges[i];
// Cache is complete or from is higher then until, we can stop looping
if (range.from >= until || (range.from <= from && range.until >= until)) {
_from = until;
break;
}
// Range hasn't gotten to from date yet, so continue
if (range.until < from)
continue;
// This range is lower then the current _from time, so we can go ahead to its until time
if (range.from <= _from) {
_from = range.until;
}
// This range is higher then the current _from time, so we are missing a piece
else {
console.log('missing piece', new Date(_from), new Date(range.from));
chunks.push({
from: _from,
until: range.from
});
_from = range.until;
}
}
// Final piece (if required)
if (_from < until) {
chunks.push({
from: _from,
until: until
});
}
}
return chunks
}
要使用的数据var
var testData = [
{
"from": 1470002400000, // 1st of August
"until": 1470780000000 // 10th of August
},
{
"from": 1471212000000, // 15th of August
"until": 1471644000000 // 20th of August
},
{
"from": 1472076000000, // 25th of August
"until": 1472594400000 // 31t of August
}]
然后你可以打电话
getGapsFromRangesArray(1470002400000, 1472594400000, testData);
// missing piece 2016-08-09T22:00:00.000Z 2016-08-14T22:00:00.000Z
// missing piece 2016-08-19T22:00:00.000Z 2016-08-24T22:00:00.000Z
时区确实被搞砸了(就像@George Jempty也提到的那样)如果包括或不包括开始/结束日期,我必须考虑..无论如何它都有效。
特别感谢@ Xotic750和@Juan Mendes对我的耐心和思考。
P.S。如果有人因为和我一样需要这个(延迟加载缓存系统)。这里有一个函数dat可以在加载新数据时将范围列表中的日期粘合在一起。这样,您可以按时间保持加载数据的有效记录。您只需要在缺少的日期范围内加载块,在正确的位置添加from / until到范围列表,或者每次添加范围时重新排序范围列表..
function glueMapDates(list) {
let prevUntil = null,
i = 0, len = list.length,
date;
for (; i < len; i++) {
date = list[i];
// From date matches, glue 2 dates together
if (date.from === prevUntil) {
// Set previous until to current until
list[i-1].until = date.until;
// Remove current date from the list
list.splice(i, 1);
// Set the loop back 1 counter
i--;
len--;
}
prevUntil = date.until;
}
fs.writeFileSync(PATH_MAP_FILE, JSON.stringify(map, null, 2));
}