【问题标题】:Javascript - same Date with multiple offset comparison [duplicate]Javascript - 具有多个偏移比较的相同日期[重复]
【发布时间】:2019-08-10 18:31:09
【问题描述】:

在比较多个日期时需要了解日期的工作原理

console.log(new Date('2019-10-10T05:00:00.000+0000') >= new Date('2019-10-10T10:30:00.000+0530')) // true
console.log(new Date('2019-10-10T05:00:00.000+0000') <= new Date('2019-10-10T10:30:00.000+0530')) // true
console.log(new Date('2019-10-10T05:00:00.000+0000') == new Date('2019-10-10T10:30:00.000+0530')) // false
console.log(+new Date('2019-10-10T05:00:00.000+0000') == +new Date('2019-10-10T10:30:00.000+0530')) // true

为什么前两个语句返回 true 和第三个 false。请求解释/链接,请。

【问题讨论】:

  • 您提供的 ISO 字符串不是有效的日期字符串。
  • @WillAlexander 这些有什么问题?对我来说,它们看起来像是有效的 ISO 字符串,而 ISO 字符串是 JavaScript 具有明确行为的唯一字符串格式。使用任何非 ISO 字符串格式都是由实现定义的,这是个坏主意。
  • 尝试用它们创建一个新的 Date 对象,然后调用任何方法,它都会失败。 en.wikipedia.org/wiki/ISO_8601 — 至于这些都不起作用的原因,这是因为您本质上是在比较引用,而不是对象的内部数据。你不能像那样测试深度平等。
  • @WillAlexander——维基百科不是参考资料。 OP 字符串 有效的 ISO 8601,但它们不是有效的 ECMA-262 格式,而这正是它们所需要的。 ECMA-262 要求偏移量的小时和分钟之间有一个冒号(在 ISO 8601 中,冒号是可选的,分钟也是如此)。
  • new Date('2019-10-10T05:00:00.000+0000') 可能会产生无效的日期,因为偏移量的小时和分钟之间的冒号丢失(如ECMA-262 所要求的那样)。解析任何不符合 ECMA-262 要求的完全格式取决于实现,因此您可能会得到一个有效的日期,也可能不是。对于 OP 格式,Safari 生成无效的日期。

标签: javascript node.js date new-operator console.log


【解决方案1】:

在第三次比较中:

console.log(new Date('2019-10-10T05:00:00.000+0000') == new Date('2019-10-10T10:30:00.000+0530')) // false

您只是在比较两个不是同一个对象的对象,因此返回 false。 MDN 解释:

对于严格或抽象比较而言,两个不同的对象永远不会相等。

第四次比较:

console.log(+new Date('2019-10-10T05:00:00.000+0000') == +new Date('2019-10-10T10:30:00.000+0530')) // true

通过使用+ 符号强制转换为数字。

第一次和第二次比较

console.log(new Date('2019-10-10T05:00:00.000+0000') >= new Date('2019-10-10T10:30:00.000+0530')) // true
console.log(new Date('2019-10-10T05:00:00.000+0000') <= new Date('2019-10-10T10:30:00.000+0530')) // true

MDN 解释了&lt; &lt;= &gt; &gt;= 关系运算符的行为:

在进行比较之前,这些运算符中的每一个都会在每个操作数上调用 valueOf() 函数。

所以它在date 对象上调用valueOf() 函数,返回timestamps 这是数字,因此评估为true

【讨论】:

  • 部分正确。在某些浏览器中,所有的比较都会是假的,因为所有的字符串都会被解析为无效的日期,从而导致使用 NaN 进行比较。
【解决方案2】:

我认为这是因为当您比较 Date 对象时,您实际上是在比较对象,如果比较相等,则结果总是 false(假设对象不相同)。 '==' 检查对象引用是否相同,而不是属性。因此在你的第三种情况下结果为假。

但是,当您在前面添加 + 时,日期将被强制转换为数字(如果是日期,则为从纪元开始的毫秒数),您可以通过在日期对象上使用 getTime() 方法获得相同的结果。

【讨论】:

    【解决方案3】:

    MDN Date page 在页面顶部包含此内容:

    var date1 = new Date('December 17, 1995 03:24:00');
    var date2 = new Date('1995-12-17T03:24:00');
    
    console.log(date1 === date2);
    // expected output: false;
    

    *编辑:已经指出,根据语言环境和 JavaScript 实现,MDN 示例中的这两个日期实际上可能相同。但是,使用以下方法获得了相同的结果:

    var date1 = new Date('1995-12-17T03:24:00');
    var date2 = new Date('1995-12-17T03:24:00');
    
    console.log(date1 === date2);
    // expected output: false;
    

    相等运算符不返回 true 的原因是因为 Date 对象是……嗯……对象。 JavaScript 相等只有在字面上是同一个对象时才返回 true。

    JavaScript 认为两个具有相同属性的对象不相等(想象一下,要对对象中的每个属性进行递归分析,算法会变得多么复杂!)

    var a = {test:1};
    var b = a;
    var c = {test:1};
    console.log(a===b) // true
    console.log(a===c) // false
    

    This StackOverflow answer 解释了如何使用getTime 测试日期相等性:

    var same = d1.getTime() === d2.getTime();
    

    这样你是在比较数字(纪元)而不是对象。

    【讨论】:

    • 第一个例子很糟糕(尽管来自 MDN),因为第一个字符串的解析依赖于实现,所以+date1 === +date2 也可能出于完全不同的原因返回 false。
    猜你喜欢
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 2011-08-03
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多