我如何获得本地化的date模式string?

使用DateFormat的实例格式化和parsingJava Date(或Calendar)类是非常容易的,也就是说,我可以将当​​前date格式化为如下所示的短本地化date:

DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault()); String today = formatter.format(new Date()); 

我的问题是:我需要获得这个本地化的模式string(即像"MM/dd/yy" )。 这应该是一个微不足道的任务,但我找不到提供者…

对于SimpleDateFormat ,您可以调用toLocalizedPattern()

编辑:

对于Java 8用户:

Java 8 Date Time API与Joda-time类似。 为了获得一个本地化的模式,我们可以使用DateTimeFormatter类

DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);

请注意,当您在LocalDate上调用toString()时,将以ISO-8601格式获取date

请注意,Java 8中的Date Time API受Joda Time的启发,大多数解决scheme都可以基于与时间有关的问题。

对于那些仍然使用Java 7和更旧的版本:

你可以使用这样的东西:

 DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault()); String pattern = ((SimpleDateFormat)formatter).toPattern(); String localPattern = ((SimpleDateFormat)formatter).toLocalizedPattern(); 

由于从getDateInstance()返回的DateFormatSimpleDateFormat实例。 这两个方法实际上也应该在DateFormat中,因为这样做不那么黑客,但他们现在不是。

可能很奇怪,我正在回答我自己的问题,但我相信,我可以在图片上添加一些东西。

ICU的实施

显然,Java 8给了你很多,但也有其他的东西: ICU4J 。 这实际上是CalendarDateFormatSimpleDateFormat等Java原始实现的来源。
因此,ICU的SimpleDateFormat也包含像toPattern()toLocalizedPattern()这样的方法应该不会令人惊讶。 你可以在这里看到他们的行动:

 DateFormat fmt = DateFormat.getPatternInstance( DateFormat.YEAR_MONTH, Locale.forLanguageTag("pl-PL")); if (fmt instanceof SimpleDateFormat) { SimpleDateFormat sfmt = (SimpleDateFormat) fmt; String pattern = sfmt.toPattern(); String localizedPattern = sfmt.toLocalizedPattern(); System.out.println(pattern); System.out.println(localizedPattern); } 

ICU增强

这并不是什么新鲜事,但我真正想指出的是:

 DateFormat.getPatternInstance(String pattern, Locale locale); 

这是一个可以返回一大堆特定于语言环境的模式的方法,比如:

  • ABBR_QUARTER
  • 25美分硬币
  • YEAR_ABBR_QUARTER
  • YEAR_QUARTER
  • YEAR_ABBR_MONTH
  • YEAR_MONTH
  • YEAR_NUM_MONTH
  • YEAR_ABBR_MONTH_DAY
  • YEAR_NUM_MONTH_DAY
  • 年月日
  • YEAR_ABBR_MONTH_WEEKDAY_DAY
  • YEAR_MONTH_WEEKDAY_DAY
  • YEAR_NUM_MONTH_WEEKDAY_DAY
  • ABBR_MONTH
  • NUM_MONTH
  • ABBR_STANDALONE_MONTH
  • STANDALONE_MONTH
  • ABBR_MONTH_DAY
  • 月日
  • NUM_MONTH_DAY
  • ABBR_MONTH_WEEKDAY_DAY
  • MONTH_WEEKDAY_DAY
  • NUM_MONTH_WEEKDAY_DAY
  • ABBR_WEEKDAY
  • WEEKDAY
  • 小时
  • HOUR24
  • HOUR_MINUTE
  • HOUR_MINUTE_SECOND
  • HOUR24_MINUTE
  • HOUR24_MINUTE_SECOND
  • HOUR_TZ
  • HOUR_GENERIC_TZ
  • HOUR_MINUTE_TZ
  • HOUR_MINUTE_GENERIC_TZ
  • 分钟
  • MINUTE_SECOND
  • 第二
  • ABBR_UTC_TZ
  • ABBR_SPECIFIC_TZ
  • SPECIFIC_TZ
  • ABBR_GENERIC_TZ
  • GENERIC_TZ
  • LOCATION_TZ

当然,还有不less。 它们的好处是这些模式实际上是string(就像在java.lang.String ),也就是说,如果使用英文模式"MM/d" ,则会返回特定于语言环境的模式。 在某些angular落案例中,这可能是有用的。 通常你只会使用DateFormat实例,而不会关心模式本身。

特定于语言环境的模式与本地化模式

问题的意图是获得本地化,而不是特定于地区的模式。 有什么不同?

从理论上讲, toPattern()会给你locale特定的模式(取决于你用来实例化(Simple)DateFormat Locale )。 也就是说,无论你放置什么目标语言/国家,你都会得到由yMdhHM等符号组成的模式。

另一方面, toLocalizedPattern() 应该返回本地化的模式,这是适合最终用户阅读和理解的东西。 例如,德语中(默认)date模式将是:

  • toPattern():dd.MM.yyyy
  • toLocalizedPattern():tt.MM.jjjj(day = Tag,month = Monat,year = Jahr)

问题的意图是:“如何find可以作为date/时间格式的暗示的本地化模式”。 也就是说,我们有一个date字段,用户可以填写使用特定于语言环境的模式,但是我想以本地化的forms显示格式提示。

可悲的是,到目前为止没有好的解决办法。 我之前在这篇文章中提到的ICU部分工作。 这是因为,ICU使用的数据来自CLDR ,不幸的是部分翻译/部分正确。 如果是我母亲的话,在写作的时候,既没有模式,也没有他们的本地化forms被正确翻译。 每次我纠正他们,我都会被其他人没有必要住在波兰,也不会说波兰语。

这个故事的寓意:不完全依靠CLDR。 你仍然需要有当地的审计师/语言评论员。

您可以在Java 8中使用DateTimeFormatterBuilder 。以下示例仅返回本地化date模式,例如"dMyyyy"

 String datePattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern( FormatStyle.SHORT, null, IsoChronology.INSTANCE, Locale.GERMANY); // or whatever Locale 

以下代码将为您提供区域设置的模式:

 final String pattern1 = ((SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, locale)).toPattern(); System.out.println(pattern1); 

Java 8提供了一些有用的function,用于处理和格式化/分析date和时间,包括处理区域设置。 这里是一个简要的介绍。

基本模式

在最简单的情况下格式化/parsing一个date,你可以使用下面的代码和一个String模式:

 DateTimeFormatter.ofPattern("MM/dd/yyyy") 

这个标准然后将这个与date对象直接用于格式化:

 return LocalDate.now().format(DateTimeFormatter.ofPattern("MM/dd/yyyy")); 

然后使用工厂模式parsingdate:

 return LocalDate.parse(dateString, DateTimeFormatter.ofPattern("MM/dd/yyyy")); 

该模式本身有大量的选项,将涵盖大部分的用例,可以在这里的javadoc位置find完整的概要。

语言环境

包含语言环境相当简单,对于默认语言环境,您可以将以下选项应用于上面显示的格式/parsing选项:

 DateTimeFormatter.ofLocalizedDate(dateStyle); 

上面的'dateStyle'是一个FormatStyle选项枚举,用于表示使用DateTimeFormatter处理本地化date的完整,长期,中期和短期版本。 使用FormatStyle你也有以下select:

 DateTimeFormatter.ofLocalizedTime(timeStyle); DateTimeFormatter.ofLocalizedDateTime(dateTimeStyle); DateTimeFormatter.ofLocalizedDateTime(dateTimeStyle, timeStyle); 

最后一个选项允许您为date和时间指定一个不同的FormatStyle 。 如果您没有使用默认的Locale,则可以使用.withLocale选项来调整每个Localized方法的返回值,例如

 DateTimeFormatter.ofLocalizedTime(timeStyle).withLocale(Locale.ENGLISH); 

或者,ofPattern也有一个重载的版本来指定语言环境

 DateTimeFormatter.ofPattern("MM/dd/yyyy",Locale.ENGLISH); 

我需要更多!

DateTimeFormatter将满足大部分的用例,但它是build立在为构build器的用户提供大量选项的DateTimeFormatterBuilder上构build的。 使用DateTimeFormatter开始,如果您需要这些广泛的格式化function回落到生成器。

因为它只是你所追求的语言环境信息 ,所以我认为你需要做的是findJVM(OpenJDK或Harmony)实际使用的文件作为整个Locale的input,并找出如何parsing它。 或者只是在网上使用另一个来源(当然有一个列表)。 这将节省那些可怜的翻译。

请在下面的代码中find接受语言环境实例的代码,并返回特定于语言环境的数据格式/模式。

  public static String getLocaleDatePattern(Locale locale) { // Validating if Locale instance is null if (locale == null || locale.getLanguage() == null) { return "MM/dd/yyyy"; } // Fetching the locale specific date pattern String localeDatePattern = ((SimpleDateFormat) DateFormat.getDateInstance( DateFormat.SHORT, locale)).toPattern(); // Validating if locale type is having language code for Chinese and country // code for (Hong Kong) with Date Format as - yy'?'M'?'d'?' if (locale.toString().equalsIgnoreCase("zh_hk")) { // Expected application Date Format for Chinese (Hong Kong) locale type return "yyyy'MM'dd"; } // Replacing all d|m|y OR Gy with dd|MM|yyyy as per the locale date pattern localeDatePattern = localeDatePattern.replaceAll("d{1,2}", "dd").replaceAll( "M{1,2}", "MM").replaceAll("y{1,4}|Gy", "yyyy"); // Replacing all blank spaces in the locale date pattern localeDatePattern = localeDatePattern.replace(" ", ""); // Validating the date pattern length to remove any extract characters if (localeDatePattern.length() > 10) { // Keeping the standard length as expected by the application localeDatePattern = localeDatePattern.substring(0, 10); } return localeDatePattern; } 

你可以尝试像这样:

 LocalDate fromCustomPattern = LocalDate.parse("20.01.2014", DateTimeFormatter.ofPattern("MM/dd/yy")) 

林不知道你想要什么,但…

SimpleDateFormat示例:

 SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yy"); Date date = sdf.parse("12/31/10"); String str = sdf.format(new Date());