求助:将Android Calendar API的getTimeInMillis毫秒值转可读时间
首先咱们得搞清楚你为啥会得到2038-01-18 22:14:07这个错误结果:
你提到的示例值2147483647是32位有符号整数的最大值,而你用FROM_UNIXTIME(uploadTime)时,相当于把毫秒值直接当成了秒值处理——2147483647秒正好是32位Unix时间戳的上限,也就是经典的「2038年问题」触发点,这就是错误的根源。
再结合Android的getTimeInMillis()方法:它返回的是从1970-01-01 UTC开始计算的毫秒数,本质是64位长整型,但如果你的数据库字段用的是32位INT类型,超过2^31-1的毫秒值会被截断或溢出,这也会导致转换异常。
接下来给你几个可行的解决方案:
1. 先修复字段类型(关键前提)
如果你的uploadTime字段是INT类型,赶紧改成BIGINT——只有64位整数才能完整存储Android返回的毫秒时间值,从根源避免溢出截断问题。
2. 正确的SQL转换语句
基础UTC时间转换
如果不需要处理时区偏移,直接将毫秒转秒后调用FROM_UNIXTIME即可,注意要确保字段是BIGINT类型避免精度丢失:
FROM_UNIXTIME(uploadTime / 1000) AS uploadTime
验证示例值:2147483647毫秒转成秒是2147483.647,对应的UTC时间是1970-01-25 03:14:03.647,你可以用这个来核对结果是否正确。
带时区偏移的转换
结合你已有的代码逻辑,我们可以直接用毫秒来计算时区偏移,避免先除以1000导致的整数精度问题:
DATE_ADD('1970-01-01 00:00:00', INTERVAL (uploadTime - (timeZoneOffset * 60 * 1000)) MILLISECOND) AS uploadTime
这里把时区偏移的分钟数转成毫秒,直接和原始毫秒值计算,再用DATE_ADD的MILLISECOND单位来转换,结果会更准确。
3. 排查已有错误的原因
你之前用FROM_UNIXTIME(uploadTime/1000)得到错误结果,大概率是因为uploadTime字段是INT类型,当值是2147483647时,整数除法2147483647/1000会截断小数部分得到2147483;如果字段已经发生溢出,实际存储的值可能并不是真实的毫秒数,这时候优先要修复字段类型和对应数据。
内容的提问来源于stack exchange,提问作者azunyan

