You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Multiplatform项目中kotlin.js.Date相等校验不生效如何解决?

问题根因

你的推测完全正确,kotlin.js.Date 本质是对JS原生Date对象的封装,原生JS Date的==是引用比较,Kotlin也没有为该类默认重载equals方法,所以两个时间戳相同但实例不同的Date对象会被判定为不相等,而JVM的java.util.Date和Native的NSDate都重写了按时间比较的equals方法,因此校验通过。


可选解决方案(按侵入性从低到高排序)

方案1:仅自定义测试断言(零侵入,优先推荐)

如果仅在单元测试场景需要做Date相等校验,完全不需要修改生产代码,只需在测试模块新增跨平台的Date断言工具即可:

  1. 在commonTest源集声明expect方法:
expect fun assertDateEquals(expected: Date, actual: Date, message: String? = null)
  1. 各平台实现:
  • JVM/Native的actual实现直接调用原有assertEquals即可:
actual fun assertDateEquals(expected: Date, actual: Date, message: String?) {
    assertEquals(expected, actual, message)
}
  • JS的actual实现按时间戳比较:
actual fun assertDateEquals(expected: Date, actual: Date, message: String?) {
    assertEquals(expected.getTime(), actual.getTime(), message)
}

后续所有Date比较的测试用例统一调用assertDateEquals即可,完全不需要改动现有生产API。


方案2:JS侧重载Date的equals运算符(低侵入)

如果生产代码中也有大量Kotlin侧的Date相等判断逻辑,不想改动现有Date的声明,可以直接在JS源集新增运算符重载:

// JS源集下添加
operator fun kotlin.js.Date.equals(other: Any?): Boolean {
    if (this === other) return true
    if (other !is kotlin.js.Date) return false
    return this.getTime() == other.getTime()
}

// 同步重写hashCode避免Hash集合类使用时出现异常
fun kotlin.js.Date.hashCode(): Int {
    return getTime().toInt()
}

该方案不需要改动现有公共API,仅需添加两个扩展方法,缺点是如果Date对象会被传递到原生JS代码中,JS侧的相等判断还是会走引用比较,仅Kotlin侧的==调用会生效。


方案3:Value Class包装公共Date类(长期最优)

如果你的项目后续还需要对Date做跨平台的统一操作(比如日期计算、格式化等),推荐用内联值类包装时间戳实现公共Date:

// common源集
@JvmInline
expect value class Date(val timestampMs: Long)

各平台的actual实现可以保留与平台原生Date的互转方法,原有业务代码中使用公共Date的地方不需要修改,对外API完全兼容:

  • 自动获得全平台统一的equals、hashCode、toString实现,不需要手动重写
  • 无额外性能开销,值类会在编译时被解包为原生Long
  • 后续可以统一在common层扩展日期操作方法,不用各平台重复实现

内容的提问来源于stack exchange,提问作者Daan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 20:15:03