Java设置1970年前文件时间异常问题求助
问题分析与解决方案
核心结论:这不是Java Bug,而是文件系统时间精度限制与API校验/时区逻辑差异导致的问题
1. file.setLastModified()抛出Negative time异常的原因
java.io.File.setLastModified(long time)接收毫秒级时间戳,但部分旧文件系统(或特定OS配置)不支持存储1970-01-01 UTC之前的负时间戳,Java会将底层系统的不支持错误包装为IllegalArgumentException抛出。而废弃的Date.parse()因历史实现逻辑,未做严格的合法性校验,反而能绕过这一限制。
2. Calendar生成时间戳导致时间重置的原因
Calendar默认生成的时间戳包含毫秒级精度,但多数Unix类文件系统(如ext3/ext4)的文件修改时间(mtime)默认仅支持秒级精度。当传入带毫秒的负时间戳时,底层文件系统无法正确解析毫秒部分,导致时间被错误截断或重置到epoch起点(1970-01-01)。Nemo显示“unknown date”是因为它无法识别被破坏的时间戳格式。
至于每次生成的时间戳略有差异,是因为Calendar若未明确设置MILLISECOND字段,会默认取当前系统的毫秒值,因此每次调用的时间戳毫秒部分不同。
3. 取整到秒级能成功的原因
将时间戳向下取整到秒级(即timestamp / 1000 * 1000)后,传入的是纯秒级的负时间戳,文件系统可以正确识别并存储,因此能成功设置1970年前的日期。
推荐解决方案
统一使用java.nio.file.Files.setLastModifiedTime(),但生成时间戳时必须强制清除毫秒部分,确保传入秒级精度的时间戳:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("CET")); cal.set(1960, Calendar.OCTOBER, 12, 0, 0, 0); cal.set(Calendar.MILLISECOND, 0); // 明确设置毫秒为0,避免随机值 long timestamp = cal.getTimeInMillis(); Files.setLastModifiedTime(Paths.get("/your/file/path"), FileTime.fromMillis(timestamp));
注意:避免依赖已废弃的Date.parse(),其行为未定义且可能在新版本Java中被移除。
内容的提问来源于stack exchange,提问作者CoSoCo
相关产品推荐
相关产品推荐

