如何在 JavaScript 的 Date 对象数组中找到最早的日期?

How can i find the oldest date in an array of Date objects in JavaScript?

提问人:gggaute 提问时间:3/15/2023 最后编辑:derpirschergggaute 更新时间:3/15/2023 访问量:138

问:

我有一个对应于 Date 对象的字符串数组。喜欢这个:

const timestamps =  [
  '2023-03-15T10:47:38.878Z',
  '2023-03-15T10:46:51.375Z',
  '2023-03-15T10:46:39.645Z',
  '2023-03-15T10:47:19.072Z',
  '2023-03-15T10:46:20.395Z'
]

var convertedTimestamps = [];
for (var time in timestamps) {
  var timeAsDate = Date.parse(time);
  console.log(time, timeAsDate);
  convertedTimestamps.push(timeAsDate);
}
const min = Math.min(...convertedTimestamps);

它们是出于其他目的解析为字符串的 Date 对象 这可以是任何长度,这只是其中的一个实例。我想找到最早的时间戳。

在上面的示例中,这些是转换后的时间戳,最小值基于数字是正确的,但不是日期对象。最上面的一个是被删除的那个

946681200000
978303600000
980982000000
983401200000
986076000000
min: 946681200000
'2023-03-15T10:47:38.878Z'

这可能只是一个数学问题,但按照我的理解,像这样解析的字符串会返回一个 int,表示自 1970 年以来已经过去了多少时间等,所以最古老的应该最接近那个时间,不是吗?此最小值实际上是最新的时间戳。当我尝试最大值时,它也是不正确的。

JavaScript 数组 日期解析

评论

0赞 derpirscher 3/15/2023
这回答了你的问题吗?在 JavaScript 中循环(针对每个)数组
0赞 derpirscher 3/15/2023
我将您的脚本转换为可运行的示例。看看实际有哪些值,以及哪些值被解析为日期。使用循环而不是 .否则你的代码很好......timefor .. offor .. in

答:

0赞 41 72 6c 3/15/2023 #1

认为您可以通过调整您的案例中的循环来解决这个问题。循环应如下所示:

for (var i = 0; i < timestamps.length; i++) {
    var timeAsDate = Date.parse(timestamps[i]); # just adapted this to the loop
    ...
}

这应该适合您的情况,因为 before 循环遍历数组的键而不是元素本身,这会导致不正确的 Date 解析,因为它在这种情况下会尝试解析索引而不是时间戳。

评论

0赞 derpirscher 3/15/2023
虽然这个答案解决了问题,但你还应该说明为什么在这里使用循环是错误的......(或者只是将其作为副本关闭)for .. in
0赞 41 72 6c 3/15/2023
@derpirscher感谢您的提示!刚刚编辑了我的答案。
0赞 derpirscher 3/15/2023
但是你的解释是错误的。循环不会遍历数组的元素(如果是,OP 的代码会起作用),而是遍历对象的键,即 OP 的代码获取值,,,,这显然是错误的for .. intime"0""1""2""3""4"
0赞 41 72 6c 3/15/2023
误会了。索引的含义是,循环正在迭代对象属性,在数组的情况下,该属性将是索引(键)而不是元素。
0赞 0stone0 3/15/2023 #2

由于您正在处理 ISO 8601 时间戳,因此您可以将任何字符串与它进行比较

  1. 设置为 ,一个高值字符串lowesta
  2. 循环timestamps
  3. 如果电流较低,则覆盖
  4. 日志

const timestamps = [
  '2023-03-15T10:47:38.878Z',
  '2023-03-15T10:46:51.375Z',
  '2023-03-15T10:46:39.645Z',
  '2023-03-15T10:47:19.072Z',
  '2023-03-15T10:46:20.395Z'
];
let lowest = 'a';

for (let timestamp of timestamps) {
    if (lowest > timestamp) {
        lowest = timestamp;
    }
}

console.log('Lowest timestamp: ' + lowest)
// Lowest timestamp: 2023-03-15T10:46:20.395Z


感谢@Derpirscher对此发表评论


有用的读物:

评论

1赞 derpirscher 3/15/2023
实际上,使用 ISO 时间戳,无需解析。你可以通过字符串比较来比较它们。而且,使用类似 的值初始化 也会更有效,您不需要在每次迭代中检查。lowerNumber.MAX_SAFE_INTEGER0
1赞 derpirscher 3/15/2023
对不起,如果我的评论不清楚,但以您的使用,这段代码工作纯属巧合,因为......如果是呢?我的意思是,如果您按数值进行比较(即解析),请用 .如果作为字符串进行比较,只需使用或完全确定(如果您必须处理 9999 年)MAX_SAFE_INTEGER.ToString()MAX_SAFE_INTEGER900719925474099119007199254740991MAX_SAFE_INTEGERlet lower = '9'let lower = 'a'
0赞 boppy 3/15/2023 #3

如果所有日期都遵循上述格式,则对该数组进行字符串排序并获取第一个条目就足够了,因为字符串是从最长时间单位到最短时间单位“排序”的。

因此,要获取最早的条目:

const timestamps =  [
  '2023-03-15T10:47:38.878Z',
  '2023-03-15T10:46:51.375Z',
  '2023-03-15T10:46:39.645Z',
  '2023-03-15T10:47:19.072Z',
  '2023-03-15T10:46:20.395Z'
];
const lowest = timestamps.sort()[0];

评论

0赞 InSync 3/15/2023
致读者:请注意,的时间复杂度是 ,而简单循环的时间复杂度是 。.sortO(n log n)O(n)
0赞 derpirscher 3/15/2023
排序以查找最大值/最小值是将任务转换为 。可能与小型数据集无关,但仍然不是最佳实践......O(n)O(n logn)
0赞 boppy 3/15/2023
问题是,这是否会导致更长的运行时间,因为我认为可能比上述自我实现的排序更快(更好地优化)。而且肯定比将每个条目单独解析为 Date-object 要快.......sort
0赞 derpirscher 3/15/2023
无需“排序”。只需遍历集合一次,并记住当前最小的元素。这肯定比任何(即使内置和优化)排序算法都快......
0赞 rjax 3/15/2023 #4

为。。in 用于循环访问对象的属性,而不是数组。如果在循环中添加 console.log(time),您将看到 time 是一个字符串,表示数组的每个索引。如果更改为 for..你的代码将起作用。

const timestamps = [
  '2023-03-15T10:47:38.878Z',
  '2023-03-15T10:46:51.375Z',
  '2023-03-15T10:46:39.645Z',
  '2023-03-15T10:47:19.072Z',
  '2023-03-15T10:46:20.395Z'
]

for (var time in timestamps) {
  console.log(time);
}

for (var time of timestamps) {
  console.log(time);
}

此外,除非您需要转换时间戳来做其他事情,否则您可能只想在循环中获取最小值。

const timestamps = [
  '2023-03-15T10:47:38.878Z',
  '2023-03-15T10:46:51.375Z',
  '2023-03-15T10:46:39.645Z',
  '2023-03-15T10:47:19.072Z',
  '2023-03-15T10:46:20.395Z'
];

let dateTime;
let minDateTime = Date.parse(timestamps[0]);
for (var time of timestamps) {
  dateTime = Date.parse(time);
  if (dateTime < minDateTime)
    minDateTime = dateTime;
}

console.log((new Date(minDateTime)).toISOString());

评论

0赞 derpirscher 3/15/2023
你必须小心你的初始化,如果数组是空的,你的代码会抛出一个错误......let minDateTime = Date.parse(timestamps[0]);timestamps