如何以本地化敏感方式显示星期、月份和日期(不含年份)
解决方案:本地化显示星期、月份和日期(不含年份)
针对你需要在不同Locale下显示星期、月份、日期但不含年份的需求,其实可以借助Java的java.time API,结合本地化的模式处理,不用为每个Locale硬编码格式。下面是两种可靠的实现方式:
方法一:基于本地化模式移除年份部分
这种思路是先获取对应Locale的标准日期模式(比如MEDIUM格式),再通过正则移除其中的年份相关部分,保留原有本地化的星期、月、日顺序。
import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.FormatStyle; import java.util.Locale; public class LocalizedDateFormatter { public String formatWeekdayMonthDay(ZonedDateTime input) { Locale currentLocale = Locale.getDefault(); // 获取当前Locale下MEDIUM级别的日期模式(带年份) String fullPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern( FormatStyle.MEDIUM, null, IsoChronology.INSTANCE, currentLocale); // 移除年份相关片段:匹配 ", yyyy"、" yyyy" 或 "yy" 等变体,然后清理多余空格/逗号 String noYearPattern = fullPattern.replaceAll(",?\\s*[yY]+", "").trim(); // 构建适配当前Locale的格式化器 DateTimeFormatter formatter = DateTimeFormatter.ofPattern(noYearPattern, currentLocale); return input.format(formatter); } }
为什么这个方法有效?
- 对于
en_US,标准MEDIUM日期模式是"EEE, MMM d, yyyy",移除年份后变成"EEE, MMM d",输出就是"Thursday, May 10"; - 对于
en_GB,标准MEDIUM日期模式是"EEE, d MMM yyyy",移除年份后变成"EEE, d MMM",输出就是"Thursday, 10 May"; - 其他Locale(比如fr_FR)会自动适配对应的格式,不需要额外修改代码。
方法二:手动组装本地化日期元素(更灵活)
如果你需要更精细控制星期、月份的显示样式(比如用全称还是缩写),可以直接用DateTimeFormatterBuilder组装本地化的日期字段:
import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.FormatStyle; import java.time.format.TextStyle; import java.time.temporal.ChronoField; import java.util.Locale; public class LocalizedDateFormatter { public String formatWeekdayMonthDay(ZonedDateTime input) { Locale currentLocale = Locale.getDefault(); DateTimeFormatter formatter = new DateTimeFormatterBuilder() // 添加星期的本地化文本(这里用FULL全称,也可以改成SHORT缩写) .appendText(ChronoField.DAY_OF_WEEK, TextStyle.FULL) .appendLiteral(", ") // 添加本地化的月日组合(复用方法一的逻辑获取无年份的模式) .appendPattern(getMonthDayPattern(currentLocale)) .toFormatter(currentLocale); return input.format(formatter); } private String getMonthDayPattern(Locale locale) { String fullPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern( FormatStyle.MEDIUM, null, IsoChronology.INSTANCE, locale); return fullPattern.replaceAll(",?\\s*[yY]+", "").trim(); } }
可选调整
如果想直接指定月份和日期的样式,也可以替换appendPattern部分为:
// 比如用SHORT缩写显示月份,直接添加日期值 .appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT) .appendLiteral(" ") .appendValue(ChronoField.DAY_OF_MONTH)
不过这种方式要注意:不同Locale的月日顺序可能不同(比如en_US是月在前,en_GB是日在前),所以还是推荐复用本地化模式的方法更稳妥。
注意事项
- 正则
",?\\s*[yY]+"可以匹配大多数Locale的年份格式(包括4位yyyy、2位yy),同时处理年份前的逗号和空格; - 如果遇到特殊Locale的年份格式(比如带前缀的),可以根据实际情况调整正则,但大部分场景下这个正则足够覆盖;
- 始终使用
Locale.getDefault()或者指定目标Locale,确保格式适配用户的区域设置。
内容的提问来源于stack exchange,提问作者Farrukh Najmi
相关产品推荐
相关产品推荐

