Java Ant <Date>任务解析异常求助:新旧服务器环境排查
1. 确认服务器Locale差异
新旧服务器的JVM默认Locale可能不一致:Oracle JDK和OpenJDK在系统默认Locale的继承逻辑上有细微差别,比如旧服务器可能用en_US(AM/PM格式为AM/PM),新服务器可能用en_GB或其他区域(AM/PM格式为a.m./p.m.),这会导致<tstamp>生成的日期字符串格式和<date>任务预期的MM/dd/yyyy hh:mm a不匹配。
可以在两台服务器上执行以下命令查看JVM默认Locale:
java -XshowSettings:locale -version
2. 强制使用指定Locale
在<format>标签中显式指定locale属性,强制生成符合MM/dd/yyyy hh:mm a格式的日期字符串:
<format property="1_day_ago" pattern="MM/dd/yyyy hh:mm aa" offset="-10" unit="day" locale="en_US"/>
en_US Locale下,aa模式会生成不带点的AM/PM,正好匹配<date>任务要求的格式。
3. 验证生成的日期字符串
在Ant脚本中添加<echo>任务,输出${1_day_ago}的值,确认新服务器上生成的日期格式:
<echo message="1_day_ago value: ${1_day_ago}"/>
如果输出是10/21/2024 05:31 p.m.,说明Locale确实是问题根源;如果输出是10/21/2024 05:31 PM,则需要排查其他问题。
4. 统一Ant启动时的JVM Locale
如果不想修改Ant脚本,可以在启动Ant时指定JVM参数,强制全局使用en_US Locale:
ant -Duser.language=en -Duser.country=US [your-target]
这会让整个JVM进程的Locale统一,确保<tstamp>生成和<date>解析的格式一致。
5. 检查任务的格式匹配
如果上述方法无效,可以尝试修改<date>任务的pattern参数,匹配新服务器生成的带点格式:
<date datetime="${1_day_ago}" when="before" pattern="MM/dd/yyyy hh:mm a"/>
注意:这里的pattern要和<tstamp>生成的格式完全一致,比如如果生成的是p.m.,则pattern需要支持这种格式(部分Locale下a模式会匹配带点的AM/PM)。
内容的提问来源于stack exchange,提问作者user1391606

