使用touch命令设置三月最后一个周日凌晨2点时段时间戳时触发格式错误的问题咨询
这绝对不是touch的bug,而是夏令时(DST)时间切换导致的正常行为——你遇到的那些“无效时间”,本质上是系统时区里根本不存在的时间段!
问题根源
以Ubuntu默认的欧洲/中欧这类实行夏令时的时区为例,每年三月的最后一个周日,当地时间会从凌晨2点直接跳转到3点,用来开启夏令时。也就是说,当地时间的2:00:00到2:59:59这段时间是完全不存在的——系统的时间体系里没有这些时间点的合法映射,所以touch(以及所有依赖系统时间解析的工具,比如date命令)都会判定这些时间戳是无效的。
你测试的所有失败案例刚好都落在了这个被跳过的“幽灵时段”里:
- 2023年3月26日是该年三月最后一个周日,当地2点到3点被跳过
- 2016年3月27日同理,2点到3点不存在
- 而3点之后的时间已经是夏令时生效后的合法时间,第二天的2点也已经是夏令时后的正常时间,所以touch能正常处理
你可以自己用date命令验证,在你的Ubuntu系统上执行:
date -d "2023-03-26 02:00:00"
同样会得到“invalid date”的错误,因为这个时间在系统时区里根本不存在。
解决方案
如果是批量处理文件时遇到这类无效时间,你可以根据需求选择以下处理方式:
映射到有效时间点
把这些“不存在的2点时段”的时间戳,自动映射到切换前的1点时段,或者切换后的3点时段。比如:- 把
2023032602xx.xx改成2023032601xx.xx(切换前的标准时间) - 或者改成
2023032603xx.xx(切换后的夏令时时间)
- 把
使用UTC时区设置时间
UTC时区没有夏令时切换,所有时间点都是有效的。你可以强制touch用UTC时区解析时间:TZ=UTC touch -t 202303260200.00 myfile.txt这样设置后,文件的时间戳在UTC时区是2023-03-26 02:00,对应你当地时区的时间会是3:00(夏令时生效后),但能成功执行不会报错。
批量处理时自动调整
针对你的5000个文件,可以写一个简单脚本:先检查时间戳是否落在三月最后一个周日的2-3点时段,如果是就自动加1小时(调整到3点的时间),再执行touch操作。
额外验证
切换到UTC时区后再执行那些报错的touch命令,会发现完全可以正常运行:
TZ=UTC touch -t 202303260200.00 test.txt
这也能证明,问题的核心是时区的夏令时切换,而非touch命令的bug。
备注:内容来源于stack exchange,提问作者Schroeder

