Java 8中使用ISO639-2编码"gsw"构造Locale无效问题咨询
你遇到的问题核心在于Joda Time的本地化资源体系和Java标准库的Locale支持并不完全对齐——即使Java的Locale类支持ISO639-2/3的alpha-3编码(比如gsw),Joda Time本身可能没有为这类语言提供对应的本地化格式数据,最终导致格式化回退到英文。
为什么会回退到英文?
Java的Locale类确实支持alpha-3编码,但Joda Time的DateTimeFormatter依赖的是自身内置的本地化资源包(而非直接复用Java的本地化数据)。很多仅存在alpha-3编码的语言(比如gsw瑞士德语)并没有被Joda Time纳入官方支持范围——你可以检查Joda Time的jar包,里面大概率找不到org/joda/time/format/messages_gsw.properties这类对应gsw的本地化配置文件,所以格式化时会自动回退到默认的英文资源。
可行的解决方案
1. 自定义Joda Time的本地化资源
如果必须使用Joda Time,你可以手动创建gsw对应的本地化配置文件,然后注册到Joda的Locale体系中:
- 新建
messages_gsw.properties文件,添加日期时间格式的键值对,比如:datetime.full=EEEE, d. MMMM yyyy HH:mm:ss zzzz datetime.long=EEEE, d. MMMM yyyy HH:mm:ss z datetime.medium=dd.MM.yyyy HH:mm:ss datetime.short=dd.MM.yy HH:mm - 通过
LocaleProvider注册自定义资源:
之后再使用// 自定义LocaleProvider,加载gsw资源 LocaleProvider provider = new AbstractLocaleProvider() { @Override public ResourceBundle getResourceBundle(Locale locale) { if (locale.getLanguage().equals("gsw")) { return ResourceBundle.getBundle("messages_gsw", locale); } return super.getResourceBundle(locale); } }; // 设置全局LocaleProvider DateTimeFormatterBuilder.setLocaleProvider(provider);new Locale("gsw")创建Locale,格式化就会读取你自定义的配置。
2. 切换到Java 8+的java.time API(推荐)
Joda Time已经进入维护状态,官方推荐迁移到Java 8引入的java.time(JSR-310)API。这套API对ISO639-3编码的Locale支持更完善,直接利用Java标准库的本地化数据,gsw这类alpha-3编码的Locale可以正常生效:
import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Locale; // 示例代码 ZonedDateTime zdt = ZonedDateTime.now(); Locale gswLocale = new Locale("gsw"); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE, d. MMMM yyyy HH:mm:ss zzzz", gswLocale); String formatted = zdt.format(formatter);
3. 替代使用相近的alpha-2 Locale
如果暂时无法迁移或自定义资源,可以尝试使用和gsw相近的alpha-2编码Locale,比如瑞士德语区常用的de_CH(德语-瑞士),虽然不是严格的gsw,但格式化结果更符合瑞士德语的使用习惯:
Locale locale = new Locale("de", "CH"); DateTimeFormatter dtf = DateTimeFormat.fullDateTime().withLocale(locale);
内容的提问来源于stack exchange,提问作者Katakana

