2

I have an array with keys: timestamp and price. The timestamps are hourly and I am also using date-fns library to compare if timestamps belong to the same day - if they do, I am trying to sum all price points of that day. However, I am finding some discrepancies as I do so:

Array is spaced out into 3 separate days for clarity purposes:

{
  "prices": [
    [1671818476949, 16854.460790677775],
    [1671822082820, 16845.20394128685],
    [1671825684227, 16857.05646176291],
    [1671829225308, 16829.569665685623],
    [1671832882885, 16825.560754591264],
    [1671836452315, 16802.19013067553],
    [1671840055897, 16791.45543916491],
    [1671843601067, 16828.5039057286],
    [1671847235412, 16818.886333963925],
    [1671850908752, 16828.80915767001],
    [1671854492281, 16849.1353436805],
    [1671858107673, 16844.63646922823],
    [1671861614876, 16826.94422938057],

    [1671865308427, 16830.32100715682],
    [1671868880378, 16859.602706687205],
    [1671872427084, 16838.84722581856],
    [1671876070308, 16843.698114347266],
    [1671879705628, 16833.179777617614],
    [1671883320221, 16826.127986844378],
    [1671886841429, 16835.60904589224],
    [1671890403652, 16826.52735073518],
    [1671894003774, 16840.053047104313],
    [1671897642888, 16844.75966886341],
    [1671901289954, 16846.46639955969],
    [1671904904119, 16846.743046196585],
    [1671908487819, 16849.228682191264],
    [1671912082408, 16853.84096165539],
    [1671915617341, 16848.57056951711],
    [1671919248222, 16838.55847898353],
    [1671922845055, 16847.802247651052],
    [1671926406952, 16848.649159225337],
    [1671930105411, 16849.932721831166],
    [1671933659969, 16848.512350420737],
    [1671937267311, 16836.58057734161],
    [1671940900097, 16842.511784308153],
    [1671944512405, 16837.250031512558],
    [1671948089796, 16835.01977126436],

    [1671951658960, 16837.930437518276],
    [1671955200553, 16831.66911474702],
    [1671958801135, 16841.3948238686],
    [1671962500002, 16839.084643107144],
    [1671966068189, 16834.494972743123],
    [1671969625433, 16833.460321328374],
    [1671973226717, 16832.79193114006],
    [1671976864726, 16814.494641690155],
    [1671980509077, 16781.822451943077],
    [1671984031113, 16821.199913544602],
    [1671987680236, 16820.32217610258],
    [1671991240419, 16807.414662482362],
    [1671994911250, 16794.108452870256],
    [1671998512051, 16769.85904421313],
    [1672002110939, 16772.940684988003],
    [1672005625248, 16820.196694166687],
    [1672009311744, 16813.158456662797],
    [1672012841914, 16842.72026144195],
    [1672016506486, 16843.359409890574],
    [1672020041689, 16852.772718398166],
    [1672023659844, 16883.023913256362],
    [1672027284022, 16895.732317171107],
    [1672030862669, 16882.371697632705],

    [1672034480606, 16862.501900560783],
    [1672038111850, 16853.824750006406],
    [1672041654416, 16845.9569876033],
    [1672045227499, 16843.843448135598],
    [1672048916306, 16848.912074255015],
    [1672052466904, 16859.749930767142],
    [1672056072318, 16865.679924348886],
    [1672059600720, 16862.520948313442],
    [1672063223636, 16840.16651774838],
    [1672066882254, 16836.402019038687],
    [1672070414455, 16818.749629565693],
    [1672074026355, 16841.011497434578],
    [1672077687367, 16841.16468121544],
    [1672081285285, 16823.19653988069],
    [1672084914724, 16846.539413040075],
    [1672088451149, 16844.521298565145],
    [1672092105680, 16839.48881574047],
    [1672095707553, 16843.692990272582],
    [1672099308191, 16895.753539841488],
    [1672102868807, 16869.94367902591],
    [1672106436652, 16869.681983132617],
    [1672110025423, 16889.298174537],
    [1672113676425, 16869.264589868446],
    [1672117308026, 16890.08282608721],
    [1672120880596, 16875.43904573174],

    [1672124490175, 16876.94990058372],
    [1672128063768, 16869.15484593176],
    [1672131709243, 16861.249964108203],
    [1672135267379, 16886.480841768516],
    [1672138903770, 16865.316599966118],
    [1672142409979, 16835.8325998708],
    [1672146052583, 16808.706816185026],
    [1672149645559, 16825.2039722797],
    [1672153287438, 16777.896913134075],
    [1672156909469, 16795.71982274382],
    [1672160506962, 16778.505439723354]
  ]
}

I have tried the following:

let sumPrice = 0;
let priceArr = [];
for (let i = 0; i < coinHistory.prices?.length; i++) {
  const coin = coinHistory.prices[i];
  const currentDate = coin[0];
  const currentPrice = coin[1];
  if (i === 0) {
    sumPrice = currentPrice;
  }

  if (i >= 1) {
    const prevDate = coinHistory.prices[i - 1][0];
    const prevPrice = coinHistory.prices[i - 1][1];
    const stillSameDay = isSameDay(currentDate,prevDate);

      if (stillSameDay) {
         sumPrice += currentPrice;
      } else{
        priceArr.push({timeStampDate: prevDate 
        ,totalDailySum: sumPrice});
        sumPrice = currentPrice;
      }
  }
}

The result I get:

[
{timeStampDate: 1671861614876, totalDailySum: 218802.4126234967},
{timeStampDate: 1671948089796, totalDailySum: 404208.3927127256}, 
{timeStampDate: 1672034480606, totalDailySum: 403928.82564146793}, 
{timeStampDate: 1672120880596, totalDailySum: 404514.88530415593}
]

As you can see, results does not include the timeStamp from 1672124490175 onwards, which is the 27th of the month and is different than 1672120880596 which is the 26th of the month.

Expected input:

[
{timeStampDate: 1671861614876, totalDailySum: TOTAL_PRICES_FOR_ALL_MATHING_TIMESTAMPS},
{timeStampDate: 1671948089796, totalDailySum: TOTAL_PRICES_FOR_ALL_MATHING_TIMESTAMPS}, 
{timeStampDate: 1672034480606, totalDailySum: TOTAL_PRICES_FOR_ALL_MATHING_TIMESTAMPS}, 
{timeStampDate: 1672120880596, totalDailySum: TOTAL_PRICES_FOR_ALL_MATHING_TIMESTAMPS},
{timeStampDate: 1672160506962, totalDailySum: TOTAL_PRICES_FOR_ALL_MATHING_TIMESTAMPS}
]
4
  • isSameDay is a function that takes 2 dates in any format and returns true or false. Commented Dec 27, 2022 at 17:41
  • 1
    Can you also post what is the exact output you want from the code with your given input. That would be better. Commented Dec 27, 2022 at 17:46
  • @james , updated with more details Commented Dec 27, 2022 at 17:53
  • 1
    Can't get this. You are telling that 1672120880596 is 26th of the month and from what I see it by converting it with epochconverter.com it's showing 27th. Commented Dec 27, 2022 at 18:05

2 Answers 2

1

Your code is fine. You just forgot a little detail: you only store a value in the result array, if you encounter a new date. After the last day though, no new date can be encountered and the data of the last day is never stored in the array.

To fix that you could for example simply add a special case where you push the data of the last day onto the array:

if (i + 1 === coinHistory.prices.length) {
  priceArr.push({
    timeStampDate: currentDate,
    totalDailySum: sumPrice
  });
}

Here is the complete working code I used to test it:

function isSameDay(d1, d2) {
  d1 = new Date(d1)
  d2 = new Date(d2)
  return d1.getFullYear() === d2.getFullYear() &&
    d1.getMonth() === d2.getMonth() &&
    d1.getDate() === d2.getDate();
}


let sumPrice = 0;
let priceArr = [];
for (let i = 0; i < coinHistory.prices.length; i++) {
  const coin = coinHistory.prices[i];
  const currentDate = coin[0];
  const currentPrice = coin[1];
  if (i !== 0) {
    const prevDate = coinHistory.prices[i - 1][0];
    const prevPrice = coinHistory.prices[i - 1][1];

    if (!isSameDay(currentDate, prevDate)) {
      priceArr.push({
        timeStampDate: prevDate,
        totalDailySum: sumPrice
      });
      sumPrice = 0; // reset
    }
  }
  sumPrice += currentPrice;

    // save the last day
  if (i + 1 === coinHistory.prices.length) {
    priceArr.push({
      timeStampDate: currentDate,
      totalDailySum: sumPrice
    });
  }
}


console.log(priceArr)
<script>
  window.coinHistory = {
    prices: [
      [1671818476949, 16854.460790677775],
      [1671822082820, 16845.20394128685],
      [1671825684227, 16857.05646176291],
      [1671829225308, 16829.569665685623],
      [1671832882885, 16825.560754591264],
      [1671836452315, 16802.19013067553],
      [1671840055897, 16791.45543916491],
      [1671843601067, 16828.5039057286],
      [1671847235412, 16818.886333963925],
      [1671850908752, 16828.80915767001],
      [1671854492281, 16849.1353436805],
      [1671858107673, 16844.63646922823],
      [1671861614876, 16826.94422938057],

      [1671865308427, 16830.32100715682],
      [1671868880378, 16859.602706687205],
      [1671872427084, 16838.84722581856],
      [1671876070308, 16843.698114347266],
      [1671879705628, 16833.179777617614],
      [1671883320221, 16826.127986844378],
      [1671886841429, 16835.60904589224],
      [1671890403652, 16826.52735073518],
      [1671894003774, 16840.053047104313],
      [1671897642888, 16844.75966886341],
      [1671901289954, 16846.46639955969],
      [1671904904119, 16846.743046196585],
      [1671908487819, 16849.228682191264],
      [1671912082408, 16853.84096165539],
      [1671915617341, 16848.57056951711],
      [1671919248222, 16838.55847898353],
      [1671922845055, 16847.802247651052],
      [1671926406952, 16848.649159225337],
      [1671930105411, 16849.932721831166],
      [1671933659969, 16848.512350420737],
      [1671937267311, 16836.58057734161],
      [1671940900097, 16842.511784308153],
      [1671944512405, 16837.250031512558],
      [1671948089796, 16835.01977126436],

      [1671951658960, 16837.930437518276],
      [1671955200553, 16831.66911474702],
      [1671958801135, 16841.3948238686],
      [1671962500002, 16839.084643107144],
      [1671966068189, 16834.494972743123],
      [1671969625433, 16833.460321328374],
      [1671973226717, 16832.79193114006],
      [1671976864726, 16814.494641690155],
      [1671980509077, 16781.822451943077],
      [1671984031113, 16821.199913544602],
      [1671987680236, 16820.32217610258],
      [1671991240419, 16807.414662482362],
      [1671994911250, 16794.108452870256],
      [1671998512051, 16769.85904421313],
      [1672002110939, 16772.940684988003],
      [1672005625248, 16820.196694166687],
      [1672009311744, 16813.158456662797],
      [1672012841914, 16842.72026144195],
      [1672016506486, 16843.359409890574],
      [1672020041689, 16852.772718398166],
      [1672023659844, 16883.023913256362],
      [1672027284022, 16895.732317171107],
      [1672030862669, 16882.371697632705],

      [1672034480606, 16862.501900560783],
      [1672038111850, 16853.824750006406],
      [1672041654416, 16845.9569876033],
      [1672045227499, 16843.843448135598],
      [1672048916306, 16848.912074255015],
      [1672052466904, 16859.749930767142],
      [1672056072318, 16865.679924348886],
      [1672059600720, 16862.520948313442],
      [1672063223636, 16840.16651774838],
      [1672066882254, 16836.402019038687],
      [1672070414455, 16818.749629565693],
      [1672074026355, 16841.011497434578],
      [1672077687367, 16841.16468121544],
      [1672081285285, 16823.19653988069],
      [1672084914724, 16846.539413040075],
      [1672088451149, 16844.521298565145],
      [1672092105680, 16839.48881574047],
      [1672095707553, 16843.692990272582],
      [1672099308191, 16895.753539841488],
      [1672102868807, 16869.94367902591],
      [1672106436652, 16869.681983132617],
      [1672110025423, 16889.298174537],
      [1672113676425, 16869.264589868446],
      [1672117308026, 16890.08282608721],
      [1672120880596, 16875.43904573174],

      [1672124490175, 16876.94990058372],
      [1672128063768, 16869.15484593176],
      [1672131709243, 16861.249964108203],
      [1672135267379, 16886.480841768516],
      [1672138903770, 16865.316599966118],
      [1672142409979, 16835.8325998708],
      [1672146052583, 16808.706816185026],
      [1672149645559, 16825.2039722797],
      [1672153287438, 16777.896913134075],
      [1672156909469, 16795.71982274382],
      [1672160506962, 16778.505439723354]
    ]
  }

</script>

https://jsfiddle.net/timlg07/0Ldnt6ko/

Sign up to request clarification or add additional context in comments.

Comments

1

This is a multiple step problem.

  1. Group the array of tuple values by date (See Array.prototype.group() - JavaScript | MDN)

    This is actually more involved than it might seem. A calendar "date" is a period between midnight (inclusive) and midnight (exclusive) according to a given time zone. You didn't specify if you want to use Universal Coordinated Time or some arbitrary time zone (e.g. the time zone of the local device), but that decision will potentially alter the results in a substantial way.

  2. After grouping the tuples by date, each date's array must be iterated to total the sum, and then the result pushed into a new array like the one you described for the desired output

Below is a code snippet demonstrating how to perform the above steps using some functional patterns. The date-related functions accept a boolean argument that will allow you to use the local time zone.

function group (array, selector) {
  const result = {};
  for (const element of array) {
    const key = selector(element);
    (result[key] ??= []).push(element);
  }
  return result;
}

function pad (num) {
  return String(num).padStart(2, '0');
}

function getDateKey (timestamp, useLocalTimeZone) {
  const date = new Date(timestamp);
  const year = useLocalTimeZone ? date.getFullYear() : date.getUTCFullYear();
  const month = (useLocalTimeZone ? date.getMonth() : date.getUTCMonth()) + 1;
  const dayOfMonth = useLocalTimeZone ? date.getDate() : date.getUTCDate();
  return `${year}-${pad(month)}-${pad(dayOfMonth)}`;
}

function groupAndSum (coinHistory, useLocalTimeZone) {
  const groupedByDate = group(
    coinHistory.prices,
    ([timestamp]) => getDateKey(timestamp, useLocalTimeZone),
  );

  const result = [];

  for (const [calendarDate, tuples] of Object.entries(groupedByDate)) {
    let totalDailySum = 0;
    for (const [,price] of tuples) totalDailySum += price;
    result.push({calendarDate, totalDailySum});
  }

  return result;
}

const coinHistory = {"prices":[[1671818476949,16854.460790677775],[1671822082820,16845.20394128685],[1671825684227,16857.05646176291],[1671829225308,16829.569665685623],[1671832882885,16825.560754591264],[1671836452315,16802.19013067553],[1671840055897,16791.45543916491],[1671843601067,16828.5039057286],[1671847235412,16818.886333963925],[1671850908752,16828.80915767001],[1671854492281,16849.1353436805],[1671858107673,16844.63646922823],[1671861614876,16826.94422938057],[1671865308427,16830.32100715682],[1671868880378,16859.602706687205],[1671872427084,16838.84722581856],[1671876070308,16843.698114347266],[1671879705628,16833.179777617614],[1671883320221,16826.127986844378],[1671886841429,16835.60904589224],[1671890403652,16826.52735073518],[1671894003774,16840.053047104313],[1671897642888,16844.75966886341],[1671901289954,16846.46639955969],[1671904904119,16846.743046196585],[1671908487819,16849.228682191264],[1671912082408,16853.84096165539],[1671915617341,16848.57056951711],[1671919248222,16838.55847898353],[1671922845055,16847.802247651052],[1671926406952,16848.649159225337],[1671930105411,16849.932721831166],[1671933659969,16848.512350420737],[1671937267311,16836.58057734161],[1671940900097,16842.511784308153],[1671944512405,16837.250031512558],[1671948089796,16835.01977126436],[1671951658960,16837.930437518276],[1671955200553,16831.66911474702],[1671958801135,16841.3948238686],[1671962500002,16839.084643107144],[1671966068189,16834.494972743123],[1671969625433,16833.460321328374],[1671973226717,16832.79193114006],[1671976864726,16814.494641690155],[1671980509077,16781.822451943077],[1671984031113,16821.199913544602],[1671987680236,16820.32217610258],[1671991240419,16807.414662482362],[1671994911250,16794.108452870256],[1671998512051,16769.85904421313],[1672002110939,16772.940684988003],[1672005625248,16820.196694166687],[1672009311744,16813.158456662797],[1672012841914,16842.72026144195],[1672016506486,16843.359409890574],[1672020041689,16852.772718398166],[1672023659844,16883.023913256362],[1672027284022,16895.732317171107],[1672030862669,16882.371697632705],[1672034480606,16862.501900560783],[1672038111850,16853.824750006406],[1672041654416,16845.9569876033],[1672045227499,16843.843448135598],[1672048916306,16848.912074255015],[1672052466904,16859.749930767142],[1672056072318,16865.679924348886],[1672059600720,16862.520948313442],[1672063223636,16840.16651774838],[1672066882254,16836.402019038687],[1672070414455,16818.749629565693],[1672074026355,16841.011497434578],[1672077687367,16841.16468121544],[1672081285285,16823.19653988069],[1672084914724,16846.539413040075],[1672088451149,16844.521298565145],[1672092105680,16839.48881574047],[1672095707553,16843.692990272582],[1672099308191,16895.753539841488],[1672102868807,16869.94367902591],[1672106436652,16869.681983132617],[1672110025423,16889.298174537],[1672113676425,16869.264589868446],[1672117308026,16890.08282608721],[1672120880596,16875.43904573174],[1672124490175,16876.94990058372],[1672128063768,16869.15484593176],[1672131709243,16861.249964108203],[1672135267379,16886.480841768516],[1672138903770,16865.316599966118],[1672142409979,16835.8325998708],[1672146052583,16808.706816185026],[1672149645559,16825.2039722797],[1672153287438,16777.896913134075],[1672156909469,16795.71982274382],[1672160506962,16778.505439723354]]};

const outputUtc = groupAndSum(coinHistory);
console.log('UTC:', outputUtc);

const outputLocal = groupAndSum(coinHistory, true);
console.log('Local:', outputLocal);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.