为何en_AU本地化下日期月份缩写带点?(Java Tomcat环境)
问题:澳大利亚Locale下SimpleDateFormat输出月份缩写带圆点的原因
环境
- Java 1.8
- Apache Tomcat 8.5.55
服务器端日期格式化代码
Locale locale = Locale.getDefault(); String lang = locale.getDisplayLanguage(); String country = locale.getDisplayCountry(); System.out.println(lang); System.out.println(country); LocalDate localDate1 = LocalDate.of(2023, 4, 10); ZoneId zone = ZoneId.systemDefault(); Instant atStartOfDay = localDate1.atStartOfDay(zone).toInstant(); String format = Constants.Format.user_dmy_df.get().format(Date.from(atStartOfDay)); System.out.println(format);
常量类说明
public class Constants{ public static class Format{ public static final ThreadLocal<DateFormat> user_dmy_df = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("dd-MMM-yyyy"); } }; } }
输出结果
English Australia 10-Apr.-2023
疑问
为何月份缩写后带有圆点?这不符合澳大利亚的日期格式规范,且本地单元测试(同样为en_AU环境)时无此圆点。
原因分析与解决办法
Locale未显式指定的隐性差异
当前SimpleDateFormat创建时未指定Locale,默认依赖JVM的全局Locale设置。虽然服务器输出显示默认Locale是en_AU,但Tomcat运行时可能存在Locale资源绑定问题——比如JVM底层语言环境配置未完全同步,导致日期格式回退使用了en_US的规则(en_US的月份缩写带圆点,而en_AU标准格式不带)。本地与服务器的JDK资源差异
本地JDK和服务器JDK的Locale数据可能不一致:不同厂商(Oracle/OpenJDK)的JDK对en_AU的日期格式定义存在细微差别,或者服务器JDK未完整加载en_AU的Locale资源,导致格式规则偏离预期。具体解决措施
- 显式指定Locale创建SimpleDateFormat:强制绑定en_AU的格式规则,避免依赖全局Locale的不确定性
return new SimpleDateFormat("dd-MMM-yyyy", new Locale("en", "AU")); - 固化Tomcat的JVM启动参数:确保JVM启动时明确使用en_AU Locale,避免环境变量干扰
-Duser.language=en -Duser.country=AU - 替换为Java 8+的DateTimeFormatter:
SimpleDateFormat线程不安全且Locale支持存在历史问题,改用线程安全的新API更稳定
对应格式化代码可简化为:public static final ThreadLocal<DateTimeFormatter> user_dmy_df = ThreadLocal.withInitial( () -> DateTimeFormatter.ofPattern("dd-MMM-yyyy", new Locale("en", "AU")) );String format = localDate1.format(Constants.Format.user_dmy_df.get());
- 显式指定Locale创建SimpleDateFormat:强制绑定en_AU的格式规则,避免依赖全局Locale的不确定性
内容的提问来源于stack exchange,提问作者Black
相关产品推荐
相关产品推荐

