SimpleDateFormat和基于区域的格式string

我想基于给定的语言环境以不同的方式在Java中格式化date。 例如,我想让英文用户看到“2009年11月1日”(格式为“MMM d,yyyy”),挪威用户看到“2009年1月1日”(“d。MMM。yyyy”)。

如果我将该语言环境添加到SimpleDateFormat构造函数,那么月份部分工作正常,但其余部分呢?

我希望我可以添加与语言环境配对的格式string到SimpleDateFormat,但我找不到任何方式来做到这一点。 是否有可能或者我需要让我的代码检查语言环境,并添加相应的格式string?

使用DateFormat.getDateInstance(int style,Locale locale)而不是使用SimpleDateFormat创build自己的模式。

 SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE dd MMM yyyy", Locale.ENGLISH); String formatted = dateFormat.format(the_date_you_want_here); 

使用样式+语言环境DateFormat.getDateInstance(int style,Locale locale)

检查http://java.sun.com/j2se/1.5.0/docs/api/java/text/DateFormat.html

运行以下示例查看差异:

 import java.text.DateFormat; import java.util.Date; import java.util.Locale; public class DateFormatDemoSO { public static void main(String args[]) { int style = DateFormat.MEDIUM; //Also try with style = DateFormat.FULL and DateFormat.SHORT Date date = new Date(); DateFormat df; df = DateFormat.getDateInstance(style, Locale.UK); System.out.println("United Kingdom: " + df.format(date)); df = DateFormat.getDateInstance(style, Locale.US); System.out.println("USA: " + df.format(date)); df = DateFormat.getDateInstance(style, Locale.FRANCE); System.out.println("France: " + df.format(date)); df = DateFormat.getDateInstance(style, Locale.ITALY); System.out.println("Italy: " + df.format(date)); df = DateFormat.getDateInstance(style, Locale.JAPAN); System.out.println("Japan: " + df.format(date)); } } 

输出:

 United Kingdom: 25-Sep-2017 USA: Sep 25, 2017 France: 25 sept. 2017 Italy: 25-set-2017 Japan: 2017/09/25 

datestring的本地化:

根据redsonic的post:

 private String localizeDate(String inputdate, Locale locale) { Date date = new Date(); SimpleDateFormat dateFormatCN = new SimpleDateFormat("dd-MMM-yyyy", locale); SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy"); try { date = dateFormat.parse(inputdate); } catch (ParseException e) { log.warn("Input date was not correct. Can not localize it."); return inputdate; } return dateFormatCN.format(date); } String localizedDate = localizeDate("05-Sep-2013", new Locale("zh","CN")); 

将会像05-九月-2013

TL;博士

 LocalDate.now().format( DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM ) .withLocale( new Locale( "no" , "NO" ) ) ) 

java.util.DateSimpleDateFormat的麻烦类现在是遗留的,被java.time类取代。

LocalDate

LocalDate类代表没有时间和没有时区的只有date的值。

时区对确定date至关重要。 对于任何特定的时刻,date在全球各地按照地区而不同。 例如, 巴黎午夜过后的几分钟, 法国是一个新的一天,而在魁北克蒙特利尔仍然是“昨天”。

 ZoneId z = ZoneId.of( "America/Montreal" ); LocalDate today = LocalDate.now( z ); 

DateTimeFormatter

使用DateTimeFormatter生成仅表示date部分或时间部分的string。

DateTimeFormatter类可以自动本地化 。

要本地化,请指定:

  • FormatStyle来确定string应该多长或缩短多less。
  • (a)用于确定(a)用于翻译date名称,月份名称等的人类语言,以及(b)用于确定缩写,大写,标点等问题的文化准则。

例:

 Locale l = Locale.CANADA_FRENCH ; DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL ).withLocale( l ); String output = ld.format( f ); 

走另一个方向,你可以parsing一个本地化的string。

 LocalDate ld = LocalDate.parse( input , f ); 

请注意,语言环境和时区是完全正交的问题。 您可以用日语或奥克兰新西兰时刻以印度语呈现蒙特利尔时刻。

又如:将6 junio 2012 (西class牙文)改为2012-06-06 (标准ISO 8601格式)。 java.time类默认使用ISO 8601格式来parsing/生成string。

 String input = "6 junio 2012"; Locale l = new Locale ( "es" , "ES" ); DateTimeFormatter f = DateTimeFormatter.ofPattern ( "d MMMM uuuu" , l ); LocalDate ld = LocalDate.parse ( input , f ); String output = ld.toString(); // 2012-06-06. 

关于java.time

java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧的遗留date时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time项目现在处于维护模式 ,build议迁移到java.time。

要了解更多信息,请参阅Oracle教程 。 并search堆栈溢出了很多例子和解释。 规范是JSR 310 。

从何处获取java.time类?

  • Java SE 8SE 9及更高版本
    • 内置。
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小function和修复。
  • Java SE 6SE 7
    • 大部分的java.timefunction都被移植到了ThreeTen-Backport中的 Java 6&7中。
  • Android的
    • ThreeTenABP项目专门针对Android,采用了ThreeTen-Backport (上文提到)。
    • 请参阅如何使用…。

ThreeTen-Extra项目将java.time扩展到其他类。 这个项目是未来可能增加java.time的一个试验场。 你可能会在这里find一些有用的类,比如IntervalYearWeekYearQuarter 等等 。

 String text = new SimpleDateFormat("E, MMM d, yyyy").format(date); 

给定date的Java 8样式

 LocalDate today = LocalDate.of(1982, Month.AUGUST, 31); System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.ENGLISH))); System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.FRENCH))); System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.JAPANESE))); 

Java8

  import java.time.format.DateTimeFormatter; myDate.format(DateTimeFormatter.ofPattern("dd-MMM-YYYY",new Locale("ar")))