将Java Date转换为Epoch毫秒值的正确方法咨询
首先明确核心事实:java.util.Date对象本身存储的就是UTC时区的Epoch毫秒值,它的getTime()方法可以直接返回你需要的结果,这是最直接、高效的方式。
你的两种实现方式对比
方式one是正确的:
代码里的time就是Date的getTime()返回值,Instant.ofEpochMilli(time).toEpochMilli()只是绕了一圈返回同一个值,结果1719565201000是正确的——对应原时间Fri Jun 28 10:00:01 GMT+01:00 2024转换为UTC后的2024-06-28T09:00:01Z的毫秒数。方式three是错误的:
你先将Date转成指定时区的LocalDateTime,再通过utcEpochSecs计算毫秒,这里的问题在于LocalDateTime是无时区信息的时间对象——它只表示“2024年6月28日10:00:01”这个时间点,但不知道这个时间属于哪个时区。当你把它直接当作UTC时间计算Epoch时,相当于把“10:00:01”当成了UTC时间,而非原时间的GMT+01时区,所以得到的1719568801000是错误的。
更合适的实现方案
方案1:直接调用Date的原生方法(最优)
typealias Dates = java.util.Date fun Dates.toEpochMillis(): Long { return this.getTime() }
这是最直接的方式,因为Date内部就是用Epoch毫秒存储时间的,不需要任何额外转换。
方案2:使用Java 8+时间API(更符合现代Java/Kotlin习惯)
如果你想结合新的时间API,也可以直接将Date转成Instant,再获取毫秒:
typealias Dates = java.util.Date fun Dates.toEpochMillis(): Long { return this.toInstant().toEpochMilli() }
这个方式和你的one逻辑一致,但更简洁,因为Java 8+的Date已经提供了toInstant()方法,可以直接转换为表示UTC时间的Instant对象。
为什么不需要传入ZoneId?
因为Date本身是UTC时间戳,和时区无关——不管你传入哪个时区,Date对应的Epoch毫秒值都是固定的。只有当你需要将Date转换为某个时区的本地时间时,才需要ZoneId,但转换Epoch毫秒不需要。
内容的提问来源于stack exchange,提问作者BRDroid

