|
const t0 = new Date, t1 = new Date; |
|
|
|
export function timeInterval(floori, offseti, count, field) { |
|
|
|
function interval(date) { |
|
return floori(date = arguments.length === 0 ? new Date : new Date(+date)), date; |
|
} |
|
|
|
interval.floor = (date) => { |
|
return floori(date = new Date(+date)), date; |
|
}; |
|
|
|
interval.ceil = (date) => { |
|
return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date; |
|
}; |
|
|
|
interval.round = (date) => { |
|
const d0 = interval(date), d1 = interval.ceil(date); |
|
return date - d0 < d1 - date ? d0 : d1; |
|
}; |
|
|
|
interval.offset = (date, step) => { |
|
return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date; |
|
}; |
|
|
|
interval.range = (start, stop, step) => { |
|
const range = []; |
|
start = interval.ceil(start); |
|
step = step == null ? 1 : Math.floor(step); |
|
if (!(start < stop) || !(step > 0)) return range; |
|
let previous; |
|
do range.push(previous = new Date(+start)), offseti(start, step), floori(start); |
|
while (previous < start && start < stop); |
|
return range; |
|
}; |
|
|
|
interval.filter = (test) => { |
|
return timeInterval((date) => { |
|
if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1); |
|
}, (date, step) => { |
|
if (date >= date) { |
|
if (step < 0) while (++step <= 0) { |
|
while (offseti(date, -1), !test(date)) {} |
|
} else while (--step >= 0) { |
|
while (offseti(date, +1), !test(date)) {} |
|
} |
|
} |
|
}); |
|
}; |
|
|
|
if (count) { |
|
interval.count = (start, end) => { |
|
t0.setTime(+start), t1.setTime(+end); |
|
floori(t0), floori(t1); |
|
return Math.floor(count(t0, t1)); |
|
}; |
|
|
|
interval.every = (step) => { |
|
step = Math.floor(step); |
|
return !isFinite(step) || !(step > 0) ? null |
|
: !(step > 1) ? interval |
|
: interval.filter(field |
|
? (d) => field(d) % step === 0 |
|
: (d) => interval.count(0, d) % step === 0); |
|
}; |
|
} |
|
|
|
return interval; |
|
} |
|
|