从数组 obj/property js 中找到最近的日期

find closest date from array obj/property js

我正在尝试从数组中获取距现在最近的日期,并将其与事件相关的对象属性(如事件)一起用于倒数计时器。

我已经设法做到这一点,通过在网上四处寻找,但我的代码只从数组中提取最后一个条目,而不是最近的日期。

如果有人能帮助或推动我朝着正确的方向前进,那就太好了。

<p id="demo"></p>
<p id="celebration"></p>

<script>
  // Get today's date and time
  var now = new Date().getTime();

  var data = [
    {
      date: "04/10/2021",
      event: "event 1",
    },
    {
      date: "08/15/2022",
      event: "event 2",
    },
    {
      date: "09/15/2021",
      event: "event 3",
    },
    {
      date: "01/12/2025",
      event: "event 4",
    },
  ];

  var closest = data.reduce((a, b) => (a.date - now < b.date - now ? a : b));

  console.log(closest.date);

  // Set the date we're counting down to
  var countDownDate = new Date(closest.date);

  // Update the count down every 1 second
  var x = setInterval(function () {
    var now = new Date().getTime();
    // Find the distance between now and the count down date
    var distance = countDownDate - now;

    // Time calculations for days, hours, minutes and seconds
    var days = Math.floor(distance / (1000 * 60 * 60 * 24));
    var hours = Math.floor(
      (distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
    );
    var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
    var seconds = Math.floor((distance % (1000 * 60)) / 1000);

    // Display the result in the element with id="demo"
    document.getElementById("demo").innerHTML =
      days + "d " + hours + "h " + minutes + "m " + seconds + "s ";

    document.getElementById("celebration").innerHTML = closest.event;
    // If the count down is finished, write some text
    if (distance < 0) {
      clearInterval(x);
      document.getElementById("demo").innerHTML = "EXPIRED";
      document.getElementById("celebration").innerHTML = "None";
    }
  }, 1000);
</script>

您要做的第一件事是确保您有一种方法可以将您的美国格式日期转换为 javascript Date 实例:

const usFormattedDate = "08/15/2022"

const parseUSDate = str => {
  const parts = str.split("/");
  return new Date(Date.UTC(
    parseInt(parts[2],10),
    parseInt(parts[0],10)-1,
    parseInt(parts[1],10)));
}

console.log(parseUSDate(usFormattedDate))

为什么不简单地使用 Date 构造函数或 Date.parse 方法?正如 docs 所说:

Note: Parsing of date strings with the Date constructor (and Date.parse(), which works the same way) is strongly discouraged due to browser differences and inconsistencies.

然后您可以使用此代码来解析您的 date 属性 - 但您可能只想对每个对象执行一次而不是每次比较两次

const parseUSDate = str => {
  const parts = str.split("/");
  return new Date(Date.UTC(
    parseInt(parts[2], 10),
    parseInt(parts[0], 10) - 1,
    parseInt(parts[1], 10)));
}

var now = new Date().getTime();

var data = [{
    date: "04/10/2021",
    event: "event 1",
  },
  {
    date: "08/15/2022",
    event: "event 2",
  },
  {
    date: "09/15/2021",
    event: "event 3",
  },
  {
    date: "01/12/2025",
    event: "event 4",
  },
];

var closest = data
  .map(x => ({ ...x, date: parseUSDate(x.date) })) // Convert date to an actual date
  .filter(x => x.date > now)                       // remove records in the past
  .reduce((a, b) => (a.date - now < b.date - now ? a : b));

console.log(closest);

请注意,以这种方式完成(转换 date 属性)就不需要这一行了:

var countDownDate = new Date(closest.date);

简直了

var countDownDate = closest.date;

你可以 sort 它并找到第一个未过期的元素

  const sorted = data.sort((a, b) => new Date(a.date) - new Date(b.date))
  const closest = sorted.find(o => new Date(o.date) - now > 0)

<p id="demo"></p>
<p id="celebration"></p>

<script>
  // Get today's date and time
  var now = new Date().getTime();

  var data = [{
      date: "04/10/2021",
      event: "event 1",
    },
    {
      date: "08/15/2022",
      event: "event 2",
    },
    {
      date: "09/15/2021",
      event: "event 3",
    },
    {
      date: "01/12/2025",
      event: "event 4",
    },
  ];

  // var closest = data.reduce( ( a, b ) => ( new Date(a.date) - now < new Date(b.date) - now ? a : b ) );
  const sorted = data.sort((a, b) => new Date(a.date) - new Date(b.date))
  const closest = sorted.find(o => new Date(o.date) - now > 0)

  // Set the date we're counting down to
  var countDownDate = new Date(closest.date);

  // Update the count down every 1 second
  var x = setInterval(function() {
    var now = new Date().getTime();
    // Find the distance between now and the count down date
    var distance = countDownDate - now;

    // Time calculations for days, hours, minutes and seconds
    var days = Math.floor(distance / (1000 * 60 * 60 * 24));
    var hours = Math.floor(
      (distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
    );
    var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
    var seconds = Math.floor((distance % (1000 * 60)) / 1000);

    // Display the result in the element with id="demo"
    document.getElementById("demo").innerHTML =
      days + "d " + hours + "h " + minutes + "m " + seconds + "s ";

    document.getElementById("celebration").innerHTML = closest.event;
    // If the count down is finished, write some text
    if (distance < 0) {
      clearInterval(x);
      document.getElementById("demo").innerHTML = "EXPIRED";
      document.getElementById("celebration").innerHTML = "None";
    }
  }, 1000);
</script>