如何有效地找到时间戳数组中每个 day/week/month 的第一个时间戳?
How to efficiently find the first timestamp of each day/week/month in an array of timestamps?
我有一长串排序的时间戳(股票报价)。时间戳具有最小分辨率(例如,每个 TS 至少比前一个大 1 分钟),但白天可能存在间隙(尤其是在 pre/after 小时的会话中)并且没有周末和假期。
我想(有效地)找到开始新间隔(例如天、周或月 - 取决于时间范围)的时间戳以用于图表目的。
我当前的解决方案是遍历数组并根据每个时间戳创建日期,然后比较前一个和当前数组元素的 .getDay()。
let rangeSecs = data[data.length-1]- data[0];
let rangeDays = rangeSecs / 86400; //data has timestamps in seconds, not ms.
let spt=[]; //array of indexes of the "timestamps of interest"
const minInterval=data.slice(0,9).reduce((ac,x,i,ar)=>Math.min(ac,x-ar[i-1]))
let prevdate=new Date(data[0]*1000)
for(let i=1;i<data.length;i++){
const curDate=new Date(data[i]*1000)
if(rangeDays>70 && prevdate.getMonth()!=curDate.getMonth() ){ //monthly
spt.push(i)
}else if(rangeDays<=70 && rangeDays>14 && prevdate.getDay()>curDate.getDay() ){ //weekly
spt.push(i)
}else if(rangeDays<=14 && prevdate.getDay()!=curDate.getDay() ){ //daily
spt.push(i)
}
prevdate=curDate;
}
可以用,但是速度很慢。
有人知道如何加快速度吗?
我尝试跳过一些“安全”数量的时间戳,但因为我无法确定每天会有多少数据点(正常交易时间除外),优化不是 optimal/generic.
编辑:根据要求提供样本数据。它涵盖了约。一个月,最小时间戳间隔为 15 分钟。
[1625572800,1625573700,1625574600,1625576400,1625578200,1625579100,1625580000,1625580900,1625581800,1625582700,1625583600,1625584500,1625585400,1625586300,1625587200,1625588100,1625589000,1625589900,1625590800,1625591700,1625592600,1625593500,1625594400,1625595300,1625596200,1625597100,1625598000,1625598900,1625599800,1625600700,1625601600,1625602500,1625603400,1625604300,1625605200,1625606100,1625607000,1625607900,1625609700,1625613300,1625615100,1625656500,1625659200,1625660100,1625664600,1625665500,1625666400,1625667300,1625668200,1625669100,1625670000,1625670900,1625671800,1625672700,1625673600,1625674500,1625675400,1625676300,1625677200,1625678100,1625679000,1625679900,1625680800,1625681700,1625682600,1625683500,1625684400,1625685300,1625686200,1625687100,1625688000,1625690700,1625691600,1625693400,1625694300,1625695200,1625697900,1625700600,1625743800,1625745600,1625746500,1625747400,1625748300,1625749200,1625751000,1625751900,1625752800,1625753700,1625754600,1625755500,1625756400,1625757300,1625758200,1625759100,1625760000,1625760900,1625761800,1625762700,1625763600,1625764500,1625765400,1625766300,1625767200,1625768100,1625769000,1625769900,1625770800,1625771700,1625772600,1625773500,1625774400,1625784300,1625786100,1625787000,1625830200,1625832000,1625832900,1625834700,1625837400,1625838300,1625839200,1625840100,1625841000,1625841900,1625842800,1625843700,1625844600,1625845500,1625846400,1625847300,1625848200,1625849100,1625850000,1625850900,1625851800,1625852700,1625853600,1625854500,1625855400,1625856300,1625857200,1625858100,1625859000,1625859900,1625860800,1625862600,1625867100,1625871600,1626087600,1626091200,1626096600,1626097500,1626098400,1626099300,1626100200,1626101100,1626102000,1626102900,1626103800,1626104700,1626105600,1626106500,1626107400,1626108300,1626109200,1626110100,1626111000,1626111900,1626112800,1626113700,1626114600,1626115500,1626116400,1626117300,1626118200,1626119100,1626120000,1626123600,1626129900,1626178500,1626183000,1626183900,1626184800,1626185700,1626186600,1626187500,1626188400,1626189300,1626190200,1626191100,1626192000,1626192900,1626193800,1626194700,1626195600,1626196500,1626197400,1626198300,1626199200,1626200100,1626201000,1626201900,1626202800,1626203700,1626204600,1626205500,1626206400,1626213600,1626215400,1626262200,1626264000,1626267600,1626269400,1626270300,1626271200,1626272100,1626273000,1626273900,1626274800,1626275700,1626276600,1626277500,1626278400,1626279300,1626280200,1626281100,1626282000,1626282900,1626283800,1626284700,1626285600,1626286500,1626287400,1626288300,1626289200,1626290100,1626291000,1626291900,1626292800,1626293700,1626295500,1626300000,1626302700,1626306300,1626342300,1626346800,1626349500,1626350400,1626351300,1626352200,1626353100,1626355800,1626356700,1626357600,1626358500,1626359400,1626360300,1626361200,1626362100,1626363000,1626363900,1626364800,1626365700,1626366600,1626367500,1626368400,1626369300,1626370200,1626371100,1626372000,1626372900,1626373800,1626374700,1626375600,1626376500,1626377400,1626378300,1626379200,1626381000,1626381900,1626386400,1626390900,1626433200,1626438600,1626442200,1626443100,1626444000,1626444900,1626445800,1626446700,1626447600,1626448500,1626449400,1626450300,1626451200,1626452100,1626453000,1626453900,1626454800,1626455700,1626456600,1626457500,1626458400,1626459300,1626460200,1626461100,1626462000,1626462900,1626463800,1626464700,1626465600,1626466500,1626477300,1626692400,1626696000,1626696900,1626697800,1626698700,1626699600,1626701400,1626702300,1626703200,1626704100,1626705000,1626705900,1626706800,1626707700,1626708600,1626709500,1626710400,1626711300,1626712200,1626713100,1626714000,1626714900,1626715800,1626716700,1626717600,1626718500,1626719400,1626720300,1626721200,1626722100,1626723000,1626723900,1626724800,1626725700,1626727500,1626731100,1626735600,1626737400,1626778800,1626780600,1626783300,1626784200,1626785100,1626787800,1626788700,1626789600,1626790500,1626791400,1626792300,1626793200,1626794100,1626795000,1626795900,1626796800,1626797700,1626798600,1626799500,1626800400,1626801300,1626802200,1626803100,1626804000,1626804900,1626805800,1626806700,1626807600,1626808500,1626809400,1626810300,1626811200,1626869700,1626872400,1626874200,1626875100,1626876000,1626876900,1626877800,1626878700,1626879600,1626880500,1626881400,1626882300,1626883200,1626884100,1626885000,1626885900,1626886800,1626887700,1626888600,1626889500,1626890400,1626891300,1626892200,1626893100,1626894000,1626894900,1626895800,1626896700,1626897600,1626955200,1626957000,1626960600,1626961500,1626962400,1626963300,1626964200,1626965100,1626966000,1626966900,1626967800,1626968700,1626969600,1626970500,1626971400,1626972300,1626973200,1626974100,1626975000,1626975900,1626976800,1626977700,1626978600,1626979500,1626980400,1626981300,1626982200,1626983100,1626984000,1626992100,1627047000,1627047900,1627048800,1627049700,1627050600,1627051500,1627052400,1627053300,1627054200,1627055100,1627056000,1627056900,1627057800,1627058700,1627059600,1627060500,1627061400,1627062300,1627063200,1627064100,1627065000,1627065900,1627066800,1627067700,1627068600,1627069500,1627070400,1627074900,1627300800,1627306200,1627307100,1627308000,1627308900,1627309800,1627310700,1627311600,1627312500,1627313400,1627314300,1627315200,1627316100,1627317000,1627317900,1627318800,1627319700,1627320600,1627321500,1627322400,1627323300,1627324200,1627325100,1627326000,1627326900,1627327800,1627328700,1627329600,1627387200,1627388100,1627392600,1627393500,1627394400,1627395300,1627396200,1627397100,1627398000,1627398900,1627399800,1627400700,1627401600,1627402500,1627403400,1627404300,1627405200,1627406100,1627407000,1627407900,1627408800,1627409700,1627410600,1627411500,1627412400,1627413300,1627414200,1627415100,1627416000,1627479000,1627479900,1627480800,1627481700,1627482600,1627483500,1627484400,1627485300,1627486200,1627487100,1627488000,1627488900,1627489800,1627490700,1627491600,1627492500,1627493400,1627494300,1627495200,1627496100,1627497000,1627497900,1627498800,1627499700,1627500600,1627501500,1627502400,1627565400,1627566300,1627567200,1627568100,1627569000,1627569900,1627570800,1627571700,1627572600,1627573500,1627574400,1627575300,1627576200,1627577100,1627578000,1627578900,1627579800,1627580700,1627581600,1627582500,1627583400,1627584300,1627585200,1627586100,1627587000,1627587900,1627588800,1627599600,1627600500,1627646400,1627651800,1627652700,1627653600,1627654500,1627655400,1627656300,1627657200,1627658100,1627659000,1627659900,1627660800,1627661700,1627662600,1627663500,1627664400,1627665300,1627666200,1627667100,1627668000,1627668900,1627669800,1627670700,1627671600,1627672500,1627673400,1627674300,1627675200,1627676100]
无需将每个时间戳都转换为 Date
对象。相反,当您有一个有趣的日期时,计算出下一个有趣日期(当前日期加上一个月、一周或一天)的时间戳值,并跳过小于该值的后续时间戳。 (另请参阅对该问题的各种评论。)
我在下面的代码中做了一些假设,您可以根据需要进行调整——例如,如果间隔是一周,那么下一个最小时间戳应该总是从星期一开始,并且它应该总是从午夜开始(不分天、周或月)。
查看评论:
// Function to find the indexes of the interesting dates in the given data
function findIndexes(data) {
let rangeSecs = data[data.length-1] - data[0];
let rangeDays = rangeSecs / 86400; // data has timestamps in seconds, not ms.
let spt = []; // array of indexes of the "timestamps of interest"
// You didn't say what these were, so I'm just using the whole array
const scaleMin = 0;
const scaleMax = data.length - 1;
// Figure out what kind of interval we want: month, week, or day
const interval = rangeDays > 70 ? "month" : rangeDays <= 14 ? "day" : "week";
/*
console.log(`${displayString(data[0])} to ${displayString(data[data.length-1])}, rangeDays = ${rangeDays}, interval = ${interval}`);
*/
// First date is presumably always of interest (but you could remove this if not)
spt.push(scaleMin);
// Remember the last "interesting" date
let prevdate = new Date(data[0] * 1000);
// Find the timestamp value for the next interesting date
let minNext = getMinNext(interval, prevdate);
// Loop through the data
for (let i = scaleMin + 1; i <= scaleMax; ++i) {
const value = data[i];
// Is this value at or above the next minimum value?
if (value >= minNext) {
// Yes, it's "interesting" -- save it and get the next one
spt.push(i);
prevdate = new Date(value * 1000);
minNext = getMinNext(interval, prevdate);
}
}
return spt;
}
// Subroutine of `findIndexes`
function getMinNext(interval, prevdate) {
let nextTime;
if (interval === "month") {
// Find out when the next month starts by adding a month and clearing the hours,
// minutes, seconds, and milliseconds
nextTime = new Date(+prevdate);
nextTime.setMonth(nextTime.getMonth() + 1);
nextTime.setHours(0, 0, 0, 0);
} else {
// Find out when the next week or day starts
const intervalLength = interval === "day" ? 86400 : 7 * 86400;
nextTime = new Date(+prevdate + (intervalLength * 1000));
nextTime.setHours(0, 0, 0, 0);
if (interval === "week") {
// Going by weeks, scan backward to Monday (this only scans the first time,
// after that we add seven days so it's always Monday)
while (nextTime.getDay() !== 1) {
nextTime.setDate(nextTime.getDate() - 1);
}
}
}
const minNext = Math.floor(nextTime / 1000);
/*
console.log(`minNext for ${displayString(prevdate)} is ${displayString(minNext)}`);
*/
return minNext;
}
具有随机数据的实时示例:
// Function to find the indexes of the interesting dates in the given data
function findIndexes(data) {
let rangeSecs = data[data.length-1] - data[0];
let rangeDays = rangeSecs / 86400; // data has timestamps in seconds, not ms.
let spt = []; // array of indexes of the "timestamps of interest"
// You didn't say what these were, so I'm just using the whole array
const scaleMin = 0;
const scaleMax = data.length - 1;
// Figure out what kind of interval we want: month, week, or day
const interval = rangeDays > 70 ? "month" : rangeDays <= 14 ? "day" : "week";
/*
console.log(`${displayString(data[0])} to ${displayString(data[data.length-1])}, rangeDays = ${rangeDays}, interval = ${interval}`);
*/
// First date is presumably always of interest (but you could remove this if not)
spt.push(scaleMin);
// Remember the last "interesting" date
let prevdate = new Date(data[0] * 1000);
// Find the timestamp value for the next interesting date
let minNext = getMinNext(interval, prevdate);
// Loop through the data
for (let i = scaleMin + 1; i <= scaleMax; ++i) {
const value = data[i];
// Is this value at or above the next minimum value?
if (value >= minNext) {
// Yes, it's "interesting" -- save it and get the next one
spt.push(i);
prevdate = new Date(value * 1000);
minNext = getMinNext(interval, prevdate);
}
}
return spt;
}
// Subroutine of `findIndexes`
function getMinNext(interval, prevdate) {
let nextTime;
if (interval === "month") {
// Find out when the next month starts by going back to the 1st, adding a month and clearing the hours,
// minutes, seconds, and milliseconds
nextTime = new Date(+prevdate);
nextTime.setDate(1);
nextTime.setMonth(nextTime.getMonth() + 1);
nextTime.setHours(0, 0, 0, 0);
} else {
// Find out when the next week or day starts
const intervalLength = interval === "day" ? 86400 : 7 * 86400;
nextTime = new Date(+prevdate + (intervalLength * 1000));
nextTime.setHours(0, 0, 0, 0);
if (interval === "week") {
// Going by weeks, scan backward to Monday (this only scans the first time,
// after that we add seven days so it's always Monday)
while (nextTime.getDay() !== 1) {
nextTime.setDate(nextTime.getDate() - 1);
}
}
}
const minNext = Math.floor(nextTime / 1000);
/*
console.log(`minNext for ${displayString(prevdate)} is ${displayString(minNext)}`);
*/
return minNext;
}
// Examples:
let indexes;
console.log("Days:");
const daysData = getRandomData(3 * 60 * 60); // Up to 4 hour intervals
indexes = findIndexes(daysData);
console.log(indexes.map(index => new Date(daysData[index] * 1000).toLocaleString()));
console.log("Weeks:");
const weeksData = getRandomData(3 * 24 * 60 * 60); // Up to 3 day intervals
indexes = findIndexes(weeksData);
console.log(indexes.map(index => new Date(weeksData[index] * 1000).toLocaleString()));
console.log("Months:");
const monthsData = getRandomData(21 * 24 * 60 * 60); // Up to 3 week intervals
indexes = findIndexes(monthsData);
console.log(indexes.map(index => new Date(monthsData[index] * 1000).toLocaleString()));
console.log("Your sample data:");
const sampleData = getSampleData();
indexes = findIndexes(sampleData);
console.log(indexes.map(index => new Date(sampleData[index] * 1000).toLocaleString()));
// Make random data for us
function getRandomData(interval) {
let value = Math.floor(Date.now() / 1000);
const data = Array.from({length: 20}, () => {
const current = value;
value += Math.floor(Math.random() * interval);
return current;
});
/*
for (const value of data) {
console.log(new Date(value * 1000).toLocaleString());
}
*/
return data;
}
function displayString(value) {
if (typeof value === "number") {
value = new Date(value * 1000);
}
return value.toLocaleString();
}
function getSampleData() {
return [
1625572800,1625573700,1625574600,1625576400,1625578200,1625579100,1625580000,1625580900,
1625581800,1625582700,1625583600,1625584500,1625585400,1625586300,
1625587200,1625588100,1625589000,1625589900,1625590800,1625591700,
1625592600,1625593500,1625594400,1625595300,1625596200,1625597100,
1625598000,1625598900,1625599800,1625600700,1625601600,1625602500,
1625603400,1625604300,1625605200,1625606100,1625607000,1625607900,
1625609700,1625613300,1625615100,1625656500,1625659200,1625660100,
1625664600,1625665500,1625666400,1625667300,1625668200,1625669100,
1625670000,1625670900,1625671800,1625672700,1625673600,1625674500,
1625675400,1625676300,1625677200,1625678100,1625679000,1625679900,
1625680800,1625681700,1625682600,1625683500,1625684400,1625685300,
1625686200,1625687100,1625688000,1625690700,1625691600,1625693400,
1625694300,1625695200,1625697900,1625700600,1625743800,1625745600,
1625746500,1625747400,1625748300,1625749200,1625751000,1625751900,
1625752800,1625753700,1625754600,1625755500,1625756400,1625757300,
1625758200,1625759100,1625760000,1625760900,1625761800,1625762700,
1625763600,1625764500,1625765400,1625766300,1625767200,1625768100,
1625769000,1625769900,1625770800,1625771700,1625772600,1625773500,
1625774400,1625784300,1625786100,1625787000,1625830200,1625832000,
1625832900,1625834700,1625837400,1625838300,1625839200,1625840100,
1625841000,1625841900,1625842800,1625843700,1625844600,1625845500,
1625846400,1625847300,1625848200,1625849100,1625850000,1625850900,
1625851800,1625852700,1625853600,1625854500,1625855400,1625856300,
1625857200,1625858100,1625859000,1625859900,1625860800,1625862600,
1625867100,1625871600,1626087600,1626091200,1626096600,1626097500,
1626098400,1626099300,1626100200,1626101100,1626102000,1626102900,
1626103800,1626104700,1626105600,1626106500,1626107400,1626108300,
1626109200,1626110100,1626111000,1626111900,1626112800,1626113700,
1626114600,1626115500,1626116400,1626117300,1626118200,1626119100,
1626120000,1626123600,1626129900,1626178500,1626183000,1626183900,
1626184800,1626185700,1626186600,1626187500,1626188400,1626189300,
1626190200,1626191100,1626192000,1626192900,1626193800,1626194700,
1626195600,1626196500,1626197400,1626198300,1626199200,1626200100,
1626201000,1626201900,1626202800,1626203700,1626204600,1626205500,
1626206400,1626213600,1626215400,1626262200,1626264000,1626267600,
1626269400,1626270300,1626271200,1626272100,1626273000,1626273900,
1626274800,1626275700,1626276600,1626277500,1626278400,1626279300,
1626280200,1626281100,1626282000,1626282900,1626283800,1626284700,
1626285600,1626286500,1626287400,1626288300,1626289200,1626290100,
1626291000,1626291900,1626292800,1626293700,1626295500,1626300000,
1626302700,1626306300,1626342300,1626346800,1626349500,1626350400,
1626351300,1626352200,1626353100,1626355800,1626356700,1626357600,
1626358500,1626359400,1626360300,1626361200,1626362100,1626363000,
1626363900,1626364800,1626365700,1626366600,1626367500,1626368400,
1626369300,1626370200,1626371100,1626372000,1626372900,1626373800,
1626374700,1626375600,1626376500,1626377400,1626378300,1626379200,
1626381000,1626381900,1626386400,1626390900,1626433200,1626438600,
1626442200,1626443100,1626444000,1626444900,1626445800,1626446700,
1626447600,1626448500,1626449400,1626450300,1626451200,1626452100,
1626453000,1626453900,1626454800,1626455700,1626456600,1626457500,
1626458400,1626459300,1626460200,1626461100,1626462000,1626462900,
1626463800,1626464700,1626465600,1626466500,1626477300,1626692400,
1626696000,1626696900,1626697800,1626698700,1626699600,1626701400,
1626702300,1626703200,1626704100,1626705000,1626705900,1626706800,
1626707700,1626708600,1626709500,1626710400,1626711300,1626712200,
1626713100,1626714000,1626714900,1626715800,1626716700,1626717600,
1626718500,1626719400,1626720300,1626721200,1626722100,1626723000,
1626723900,1626724800,1626725700,1626727500,1626731100,1626735600,
1626737400,1626778800,1626780600,1626783300,1626784200,1626785100,
1626787800,1626788700,1626789600,1626790500,1626791400,1626792300,
1626793200,1626794100,1626795000,1626795900,1626796800,1626797700,
1626798600,1626799500,1626800400,1626801300,1626802200,1626803100,
1626804000,1626804900,1626805800,1626806700,1626807600,1626808500,
1626809400,1626810300,1626811200,1626869700,1626872400,1626874200,
1626875100,1626876000,1626876900,1626877800,1626878700,1626879600,
1626880500,1626881400,1626882300,1626883200,1626884100,1626885000,
1626885900,1626886800,1626887700,1626888600,1626889500,1626890400,
1626891300,1626892200,1626893100,1626894000,1626894900,1626895800,
1626896700,1626897600,1626955200,1626957000,1626960600,1626961500,
1626962400,1626963300,1626964200,1626965100,1626966000,1626966900,
1626967800,1626968700,1626969600,1626970500,1626971400,1626972300,
1626973200,1626974100,1626975000,1626975900,1626976800,1626977700,
1626978600,1626979500,1626980400,1626981300,1626982200,1626983100,
1626984000,1626992100,1627047000,1627047900,1627048800,1627049700,
1627050600,1627051500,1627052400,1627053300,1627054200,1627055100,
1627056000,1627056900,1627057800,1627058700,1627059600,1627060500,
1627061400,1627062300,1627063200,1627064100,1627065000,1627065900,
1627066800,1627067700,1627068600,1627069500,1627070400,1627074900,
1627300800,1627306200,1627307100,1627308000,1627308900,1627309800,
1627310700,1627311600,1627312500,1627313400,1627314300,1627315200,
1627316100,1627317000,1627317900,1627318800,1627319700,1627320600,
1627321500,1627322400,1627323300,1627324200,1627325100,1627326000,
1627326900,1627327800,1627328700,1627329600,1627387200,1627388100,
1627392600,1627393500,1627394400,1627395300,1627396200,1627397100,
1627398000,1627398900,1627399800,1627400700,1627401600,1627402500,
1627403400,1627404300,1627405200,1627406100,1627407000,1627407900,
1627408800,1627409700,1627410600,1627411500,1627412400,1627413300,
1627414200,1627415100,1627416000,1627479000,1627479900,1627480800,
1627481700,1627482600,1627483500,1627484400,1627485300,1627486200,
1627487100,1627488000,1627488900,1627489800,1627490700,1627491600,
1627492500,1627493400,1627494300,1627495200,1627496100,1627497000,
1627497900,1627498800,1627499700,1627500600,1627501500,1627502400,
1627565400,1627566300,1627567200,1627568100,1627569000,1627569900,
1627570800,1627571700,1627572600,1627573500,1627574400,1627575300,
1627576200,1627577100,1627578000,1627578900,1627579800,1627580700,
1627581600,1627582500,1627583400,1627584300,1627585200,1627586100,
1627587000,1627587900,1627588800,1627599600,1627600500,1627646400,
1627651800,1627652700,1627653600,1627654500,1627655400,1627656300,
1627657200,1627658100,1627659000,1627659900,1627660800,1627661700,
1627662600,1627663500,1627664400,1627665300,1627666200,1627667100,
1627668000,1627668900,1627669800,1627670700,1627671600,1627672500,
1627673400,1627674300,1627675200,1627676100
];
}
.as-console-wrapper {
max-height: 100% !important;
}
我有一长串排序的时间戳(股票报价)。时间戳具有最小分辨率(例如,每个 TS 至少比前一个大 1 分钟),但白天可能存在间隙(尤其是在 pre/after 小时的会话中)并且没有周末和假期。 我想(有效地)找到开始新间隔(例如天、周或月 - 取决于时间范围)的时间戳以用于图表目的。
我当前的解决方案是遍历数组并根据每个时间戳创建日期,然后比较前一个和当前数组元素的 .getDay()。
let rangeSecs = data[data.length-1]- data[0];
let rangeDays = rangeSecs / 86400; //data has timestamps in seconds, not ms.
let spt=[]; //array of indexes of the "timestamps of interest"
const minInterval=data.slice(0,9).reduce((ac,x,i,ar)=>Math.min(ac,x-ar[i-1]))
let prevdate=new Date(data[0]*1000)
for(let i=1;i<data.length;i++){
const curDate=new Date(data[i]*1000)
if(rangeDays>70 && prevdate.getMonth()!=curDate.getMonth() ){ //monthly
spt.push(i)
}else if(rangeDays<=70 && rangeDays>14 && prevdate.getDay()>curDate.getDay() ){ //weekly
spt.push(i)
}else if(rangeDays<=14 && prevdate.getDay()!=curDate.getDay() ){ //daily
spt.push(i)
}
prevdate=curDate;
}
可以用,但是速度很慢。 有人知道如何加快速度吗?
我尝试跳过一些“安全”数量的时间戳,但因为我无法确定每天会有多少数据点(正常交易时间除外),优化不是 optimal/generic.
编辑:根据要求提供样本数据。它涵盖了约。一个月,最小时间戳间隔为 15 分钟。
[1625572800,1625573700,1625574600,1625576400,1625578200,1625579100,1625580000,1625580900,1625581800,1625582700,1625583600,1625584500,1625585400,1625586300,1625587200,1625588100,1625589000,1625589900,1625590800,1625591700,1625592600,1625593500,1625594400,1625595300,1625596200,1625597100,1625598000,1625598900,1625599800,1625600700,1625601600,1625602500,1625603400,1625604300,1625605200,1625606100,1625607000,1625607900,1625609700,1625613300,1625615100,1625656500,1625659200,1625660100,1625664600,1625665500,1625666400,1625667300,1625668200,1625669100,1625670000,1625670900,1625671800,1625672700,1625673600,1625674500,1625675400,1625676300,1625677200,1625678100,1625679000,1625679900,1625680800,1625681700,1625682600,1625683500,1625684400,1625685300,1625686200,1625687100,1625688000,1625690700,1625691600,1625693400,1625694300,1625695200,1625697900,1625700600,1625743800,1625745600,1625746500,1625747400,1625748300,1625749200,1625751000,1625751900,1625752800,1625753700,1625754600,1625755500,1625756400,1625757300,1625758200,1625759100,1625760000,1625760900,1625761800,1625762700,1625763600,1625764500,1625765400,1625766300,1625767200,1625768100,1625769000,1625769900,1625770800,1625771700,1625772600,1625773500,1625774400,1625784300,1625786100,1625787000,1625830200,1625832000,1625832900,1625834700,1625837400,1625838300,1625839200,1625840100,1625841000,1625841900,1625842800,1625843700,1625844600,1625845500,1625846400,1625847300,1625848200,1625849100,1625850000,1625850900,1625851800,1625852700,1625853600,1625854500,1625855400,1625856300,1625857200,1625858100,1625859000,1625859900,1625860800,1625862600,1625867100,1625871600,1626087600,1626091200,1626096600,1626097500,1626098400,1626099300,1626100200,1626101100,1626102000,1626102900,1626103800,1626104700,1626105600,1626106500,1626107400,1626108300,1626109200,1626110100,1626111000,1626111900,1626112800,1626113700,1626114600,1626115500,1626116400,1626117300,1626118200,1626119100,1626120000,1626123600,1626129900,1626178500,1626183000,1626183900,1626184800,1626185700,1626186600,1626187500,1626188400,1626189300,1626190200,1626191100,1626192000,1626192900,1626193800,1626194700,1626195600,1626196500,1626197400,1626198300,1626199200,1626200100,1626201000,1626201900,1626202800,1626203700,1626204600,1626205500,1626206400,1626213600,1626215400,1626262200,1626264000,1626267600,1626269400,1626270300,1626271200,1626272100,1626273000,1626273900,1626274800,1626275700,1626276600,1626277500,1626278400,1626279300,1626280200,1626281100,1626282000,1626282900,1626283800,1626284700,1626285600,1626286500,1626287400,1626288300,1626289200,1626290100,1626291000,1626291900,1626292800,1626293700,1626295500,1626300000,1626302700,1626306300,1626342300,1626346800,1626349500,1626350400,1626351300,1626352200,1626353100,1626355800,1626356700,1626357600,1626358500,1626359400,1626360300,1626361200,1626362100,1626363000,1626363900,1626364800,1626365700,1626366600,1626367500,1626368400,1626369300,1626370200,1626371100,1626372000,1626372900,1626373800,1626374700,1626375600,1626376500,1626377400,1626378300,1626379200,1626381000,1626381900,1626386400,1626390900,1626433200,1626438600,1626442200,1626443100,1626444000,1626444900,1626445800,1626446700,1626447600,1626448500,1626449400,1626450300,1626451200,1626452100,1626453000,1626453900,1626454800,1626455700,1626456600,1626457500,1626458400,1626459300,1626460200,1626461100,1626462000,1626462900,1626463800,1626464700,1626465600,1626466500,1626477300,1626692400,1626696000,1626696900,1626697800,1626698700,1626699600,1626701400,1626702300,1626703200,1626704100,1626705000,1626705900,1626706800,1626707700,1626708600,1626709500,1626710400,1626711300,1626712200,1626713100,1626714000,1626714900,1626715800,1626716700,1626717600,1626718500,1626719400,1626720300,1626721200,1626722100,1626723000,1626723900,1626724800,1626725700,1626727500,1626731100,1626735600,1626737400,1626778800,1626780600,1626783300,1626784200,1626785100,1626787800,1626788700,1626789600,1626790500,1626791400,1626792300,1626793200,1626794100,1626795000,1626795900,1626796800,1626797700,1626798600,1626799500,1626800400,1626801300,1626802200,1626803100,1626804000,1626804900,1626805800,1626806700,1626807600,1626808500,1626809400,1626810300,1626811200,1626869700,1626872400,1626874200,1626875100,1626876000,1626876900,1626877800,1626878700,1626879600,1626880500,1626881400,1626882300,1626883200,1626884100,1626885000,1626885900,1626886800,1626887700,1626888600,1626889500,1626890400,1626891300,1626892200,1626893100,1626894000,1626894900,1626895800,1626896700,1626897600,1626955200,1626957000,1626960600,1626961500,1626962400,1626963300,1626964200,1626965100,1626966000,1626966900,1626967800,1626968700,1626969600,1626970500,1626971400,1626972300,1626973200,1626974100,1626975000,1626975900,1626976800,1626977700,1626978600,1626979500,1626980400,1626981300,1626982200,1626983100,1626984000,1626992100,1627047000,1627047900,1627048800,1627049700,1627050600,1627051500,1627052400,1627053300,1627054200,1627055100,1627056000,1627056900,1627057800,1627058700,1627059600,1627060500,1627061400,1627062300,1627063200,1627064100,1627065000,1627065900,1627066800,1627067700,1627068600,1627069500,1627070400,1627074900,1627300800,1627306200,1627307100,1627308000,1627308900,1627309800,1627310700,1627311600,1627312500,1627313400,1627314300,1627315200,1627316100,1627317000,1627317900,1627318800,1627319700,1627320600,1627321500,1627322400,1627323300,1627324200,1627325100,1627326000,1627326900,1627327800,1627328700,1627329600,1627387200,1627388100,1627392600,1627393500,1627394400,1627395300,1627396200,1627397100,1627398000,1627398900,1627399800,1627400700,1627401600,1627402500,1627403400,1627404300,1627405200,1627406100,1627407000,1627407900,1627408800,1627409700,1627410600,1627411500,1627412400,1627413300,1627414200,1627415100,1627416000,1627479000,1627479900,1627480800,1627481700,1627482600,1627483500,1627484400,1627485300,1627486200,1627487100,1627488000,1627488900,1627489800,1627490700,1627491600,1627492500,1627493400,1627494300,1627495200,1627496100,1627497000,1627497900,1627498800,1627499700,1627500600,1627501500,1627502400,1627565400,1627566300,1627567200,1627568100,1627569000,1627569900,1627570800,1627571700,1627572600,1627573500,1627574400,1627575300,1627576200,1627577100,1627578000,1627578900,1627579800,1627580700,1627581600,1627582500,1627583400,1627584300,1627585200,1627586100,1627587000,1627587900,1627588800,1627599600,1627600500,1627646400,1627651800,1627652700,1627653600,1627654500,1627655400,1627656300,1627657200,1627658100,1627659000,1627659900,1627660800,1627661700,1627662600,1627663500,1627664400,1627665300,1627666200,1627667100,1627668000,1627668900,1627669800,1627670700,1627671600,1627672500,1627673400,1627674300,1627675200,1627676100]
无需将每个时间戳都转换为 Date
对象。相反,当您有一个有趣的日期时,计算出下一个有趣日期(当前日期加上一个月、一周或一天)的时间戳值,并跳过小于该值的后续时间戳。 (另请参阅对该问题的各种评论。)
我在下面的代码中做了一些假设,您可以根据需要进行调整——例如,如果间隔是一周,那么下一个最小时间戳应该总是从星期一开始,并且它应该总是从午夜开始(不分天、周或月)。
查看评论:
// Function to find the indexes of the interesting dates in the given data
function findIndexes(data) {
let rangeSecs = data[data.length-1] - data[0];
let rangeDays = rangeSecs / 86400; // data has timestamps in seconds, not ms.
let spt = []; // array of indexes of the "timestamps of interest"
// You didn't say what these were, so I'm just using the whole array
const scaleMin = 0;
const scaleMax = data.length - 1;
// Figure out what kind of interval we want: month, week, or day
const interval = rangeDays > 70 ? "month" : rangeDays <= 14 ? "day" : "week";
/*
console.log(`${displayString(data[0])} to ${displayString(data[data.length-1])}, rangeDays = ${rangeDays}, interval = ${interval}`);
*/
// First date is presumably always of interest (but you could remove this if not)
spt.push(scaleMin);
// Remember the last "interesting" date
let prevdate = new Date(data[0] * 1000);
// Find the timestamp value for the next interesting date
let minNext = getMinNext(interval, prevdate);
// Loop through the data
for (let i = scaleMin + 1; i <= scaleMax; ++i) {
const value = data[i];
// Is this value at or above the next minimum value?
if (value >= minNext) {
// Yes, it's "interesting" -- save it and get the next one
spt.push(i);
prevdate = new Date(value * 1000);
minNext = getMinNext(interval, prevdate);
}
}
return spt;
}
// Subroutine of `findIndexes`
function getMinNext(interval, prevdate) {
let nextTime;
if (interval === "month") {
// Find out when the next month starts by adding a month and clearing the hours,
// minutes, seconds, and milliseconds
nextTime = new Date(+prevdate);
nextTime.setMonth(nextTime.getMonth() + 1);
nextTime.setHours(0, 0, 0, 0);
} else {
// Find out when the next week or day starts
const intervalLength = interval === "day" ? 86400 : 7 * 86400;
nextTime = new Date(+prevdate + (intervalLength * 1000));
nextTime.setHours(0, 0, 0, 0);
if (interval === "week") {
// Going by weeks, scan backward to Monday (this only scans the first time,
// after that we add seven days so it's always Monday)
while (nextTime.getDay() !== 1) {
nextTime.setDate(nextTime.getDate() - 1);
}
}
}
const minNext = Math.floor(nextTime / 1000);
/*
console.log(`minNext for ${displayString(prevdate)} is ${displayString(minNext)}`);
*/
return minNext;
}
具有随机数据的实时示例:
// Function to find the indexes of the interesting dates in the given data
function findIndexes(data) {
let rangeSecs = data[data.length-1] - data[0];
let rangeDays = rangeSecs / 86400; // data has timestamps in seconds, not ms.
let spt = []; // array of indexes of the "timestamps of interest"
// You didn't say what these were, so I'm just using the whole array
const scaleMin = 0;
const scaleMax = data.length - 1;
// Figure out what kind of interval we want: month, week, or day
const interval = rangeDays > 70 ? "month" : rangeDays <= 14 ? "day" : "week";
/*
console.log(`${displayString(data[0])} to ${displayString(data[data.length-1])}, rangeDays = ${rangeDays}, interval = ${interval}`);
*/
// First date is presumably always of interest (but you could remove this if not)
spt.push(scaleMin);
// Remember the last "interesting" date
let prevdate = new Date(data[0] * 1000);
// Find the timestamp value for the next interesting date
let minNext = getMinNext(interval, prevdate);
// Loop through the data
for (let i = scaleMin + 1; i <= scaleMax; ++i) {
const value = data[i];
// Is this value at or above the next minimum value?
if (value >= minNext) {
// Yes, it's "interesting" -- save it and get the next one
spt.push(i);
prevdate = new Date(value * 1000);
minNext = getMinNext(interval, prevdate);
}
}
return spt;
}
// Subroutine of `findIndexes`
function getMinNext(interval, prevdate) {
let nextTime;
if (interval === "month") {
// Find out when the next month starts by going back to the 1st, adding a month and clearing the hours,
// minutes, seconds, and milliseconds
nextTime = new Date(+prevdate);
nextTime.setDate(1);
nextTime.setMonth(nextTime.getMonth() + 1);
nextTime.setHours(0, 0, 0, 0);
} else {
// Find out when the next week or day starts
const intervalLength = interval === "day" ? 86400 : 7 * 86400;
nextTime = new Date(+prevdate + (intervalLength * 1000));
nextTime.setHours(0, 0, 0, 0);
if (interval === "week") {
// Going by weeks, scan backward to Monday (this only scans the first time,
// after that we add seven days so it's always Monday)
while (nextTime.getDay() !== 1) {
nextTime.setDate(nextTime.getDate() - 1);
}
}
}
const minNext = Math.floor(nextTime / 1000);
/*
console.log(`minNext for ${displayString(prevdate)} is ${displayString(minNext)}`);
*/
return minNext;
}
// Examples:
let indexes;
console.log("Days:");
const daysData = getRandomData(3 * 60 * 60); // Up to 4 hour intervals
indexes = findIndexes(daysData);
console.log(indexes.map(index => new Date(daysData[index] * 1000).toLocaleString()));
console.log("Weeks:");
const weeksData = getRandomData(3 * 24 * 60 * 60); // Up to 3 day intervals
indexes = findIndexes(weeksData);
console.log(indexes.map(index => new Date(weeksData[index] * 1000).toLocaleString()));
console.log("Months:");
const monthsData = getRandomData(21 * 24 * 60 * 60); // Up to 3 week intervals
indexes = findIndexes(monthsData);
console.log(indexes.map(index => new Date(monthsData[index] * 1000).toLocaleString()));
console.log("Your sample data:");
const sampleData = getSampleData();
indexes = findIndexes(sampleData);
console.log(indexes.map(index => new Date(sampleData[index] * 1000).toLocaleString()));
// Make random data for us
function getRandomData(interval) {
let value = Math.floor(Date.now() / 1000);
const data = Array.from({length: 20}, () => {
const current = value;
value += Math.floor(Math.random() * interval);
return current;
});
/*
for (const value of data) {
console.log(new Date(value * 1000).toLocaleString());
}
*/
return data;
}
function displayString(value) {
if (typeof value === "number") {
value = new Date(value * 1000);
}
return value.toLocaleString();
}
function getSampleData() {
return [
1625572800,1625573700,1625574600,1625576400,1625578200,1625579100,1625580000,1625580900,
1625581800,1625582700,1625583600,1625584500,1625585400,1625586300,
1625587200,1625588100,1625589000,1625589900,1625590800,1625591700,
1625592600,1625593500,1625594400,1625595300,1625596200,1625597100,
1625598000,1625598900,1625599800,1625600700,1625601600,1625602500,
1625603400,1625604300,1625605200,1625606100,1625607000,1625607900,
1625609700,1625613300,1625615100,1625656500,1625659200,1625660100,
1625664600,1625665500,1625666400,1625667300,1625668200,1625669100,
1625670000,1625670900,1625671800,1625672700,1625673600,1625674500,
1625675400,1625676300,1625677200,1625678100,1625679000,1625679900,
1625680800,1625681700,1625682600,1625683500,1625684400,1625685300,
1625686200,1625687100,1625688000,1625690700,1625691600,1625693400,
1625694300,1625695200,1625697900,1625700600,1625743800,1625745600,
1625746500,1625747400,1625748300,1625749200,1625751000,1625751900,
1625752800,1625753700,1625754600,1625755500,1625756400,1625757300,
1625758200,1625759100,1625760000,1625760900,1625761800,1625762700,
1625763600,1625764500,1625765400,1625766300,1625767200,1625768100,
1625769000,1625769900,1625770800,1625771700,1625772600,1625773500,
1625774400,1625784300,1625786100,1625787000,1625830200,1625832000,
1625832900,1625834700,1625837400,1625838300,1625839200,1625840100,
1625841000,1625841900,1625842800,1625843700,1625844600,1625845500,
1625846400,1625847300,1625848200,1625849100,1625850000,1625850900,
1625851800,1625852700,1625853600,1625854500,1625855400,1625856300,
1625857200,1625858100,1625859000,1625859900,1625860800,1625862600,
1625867100,1625871600,1626087600,1626091200,1626096600,1626097500,
1626098400,1626099300,1626100200,1626101100,1626102000,1626102900,
1626103800,1626104700,1626105600,1626106500,1626107400,1626108300,
1626109200,1626110100,1626111000,1626111900,1626112800,1626113700,
1626114600,1626115500,1626116400,1626117300,1626118200,1626119100,
1626120000,1626123600,1626129900,1626178500,1626183000,1626183900,
1626184800,1626185700,1626186600,1626187500,1626188400,1626189300,
1626190200,1626191100,1626192000,1626192900,1626193800,1626194700,
1626195600,1626196500,1626197400,1626198300,1626199200,1626200100,
1626201000,1626201900,1626202800,1626203700,1626204600,1626205500,
1626206400,1626213600,1626215400,1626262200,1626264000,1626267600,
1626269400,1626270300,1626271200,1626272100,1626273000,1626273900,
1626274800,1626275700,1626276600,1626277500,1626278400,1626279300,
1626280200,1626281100,1626282000,1626282900,1626283800,1626284700,
1626285600,1626286500,1626287400,1626288300,1626289200,1626290100,
1626291000,1626291900,1626292800,1626293700,1626295500,1626300000,
1626302700,1626306300,1626342300,1626346800,1626349500,1626350400,
1626351300,1626352200,1626353100,1626355800,1626356700,1626357600,
1626358500,1626359400,1626360300,1626361200,1626362100,1626363000,
1626363900,1626364800,1626365700,1626366600,1626367500,1626368400,
1626369300,1626370200,1626371100,1626372000,1626372900,1626373800,
1626374700,1626375600,1626376500,1626377400,1626378300,1626379200,
1626381000,1626381900,1626386400,1626390900,1626433200,1626438600,
1626442200,1626443100,1626444000,1626444900,1626445800,1626446700,
1626447600,1626448500,1626449400,1626450300,1626451200,1626452100,
1626453000,1626453900,1626454800,1626455700,1626456600,1626457500,
1626458400,1626459300,1626460200,1626461100,1626462000,1626462900,
1626463800,1626464700,1626465600,1626466500,1626477300,1626692400,
1626696000,1626696900,1626697800,1626698700,1626699600,1626701400,
1626702300,1626703200,1626704100,1626705000,1626705900,1626706800,
1626707700,1626708600,1626709500,1626710400,1626711300,1626712200,
1626713100,1626714000,1626714900,1626715800,1626716700,1626717600,
1626718500,1626719400,1626720300,1626721200,1626722100,1626723000,
1626723900,1626724800,1626725700,1626727500,1626731100,1626735600,
1626737400,1626778800,1626780600,1626783300,1626784200,1626785100,
1626787800,1626788700,1626789600,1626790500,1626791400,1626792300,
1626793200,1626794100,1626795000,1626795900,1626796800,1626797700,
1626798600,1626799500,1626800400,1626801300,1626802200,1626803100,
1626804000,1626804900,1626805800,1626806700,1626807600,1626808500,
1626809400,1626810300,1626811200,1626869700,1626872400,1626874200,
1626875100,1626876000,1626876900,1626877800,1626878700,1626879600,
1626880500,1626881400,1626882300,1626883200,1626884100,1626885000,
1626885900,1626886800,1626887700,1626888600,1626889500,1626890400,
1626891300,1626892200,1626893100,1626894000,1626894900,1626895800,
1626896700,1626897600,1626955200,1626957000,1626960600,1626961500,
1626962400,1626963300,1626964200,1626965100,1626966000,1626966900,
1626967800,1626968700,1626969600,1626970500,1626971400,1626972300,
1626973200,1626974100,1626975000,1626975900,1626976800,1626977700,
1626978600,1626979500,1626980400,1626981300,1626982200,1626983100,
1626984000,1626992100,1627047000,1627047900,1627048800,1627049700,
1627050600,1627051500,1627052400,1627053300,1627054200,1627055100,
1627056000,1627056900,1627057800,1627058700,1627059600,1627060500,
1627061400,1627062300,1627063200,1627064100,1627065000,1627065900,
1627066800,1627067700,1627068600,1627069500,1627070400,1627074900,
1627300800,1627306200,1627307100,1627308000,1627308900,1627309800,
1627310700,1627311600,1627312500,1627313400,1627314300,1627315200,
1627316100,1627317000,1627317900,1627318800,1627319700,1627320600,
1627321500,1627322400,1627323300,1627324200,1627325100,1627326000,
1627326900,1627327800,1627328700,1627329600,1627387200,1627388100,
1627392600,1627393500,1627394400,1627395300,1627396200,1627397100,
1627398000,1627398900,1627399800,1627400700,1627401600,1627402500,
1627403400,1627404300,1627405200,1627406100,1627407000,1627407900,
1627408800,1627409700,1627410600,1627411500,1627412400,1627413300,
1627414200,1627415100,1627416000,1627479000,1627479900,1627480800,
1627481700,1627482600,1627483500,1627484400,1627485300,1627486200,
1627487100,1627488000,1627488900,1627489800,1627490700,1627491600,
1627492500,1627493400,1627494300,1627495200,1627496100,1627497000,
1627497900,1627498800,1627499700,1627500600,1627501500,1627502400,
1627565400,1627566300,1627567200,1627568100,1627569000,1627569900,
1627570800,1627571700,1627572600,1627573500,1627574400,1627575300,
1627576200,1627577100,1627578000,1627578900,1627579800,1627580700,
1627581600,1627582500,1627583400,1627584300,1627585200,1627586100,
1627587000,1627587900,1627588800,1627599600,1627600500,1627646400,
1627651800,1627652700,1627653600,1627654500,1627655400,1627656300,
1627657200,1627658100,1627659000,1627659900,1627660800,1627661700,
1627662600,1627663500,1627664400,1627665300,1627666200,1627667100,
1627668000,1627668900,1627669800,1627670700,1627671600,1627672500,
1627673400,1627674300,1627675200,1627676100
];
}
.as-console-wrapper {
max-height: 100% !important;
}