簡體   English   中英

如何獲取本地化的日期模式字符串?

[英]How do I get localized date pattern string?

使用DateFormat實例格式化和解析Java Date(或Calendar)類非常容易,即我可以將當​​前日期格式化為短本地化日期,如下所示:

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

我的問題是:我需要獲取此本地化的模式字符串(即類似"MM/dd/yy" )。 這應該是一件微不足道的任務,但我只是找不到提供者...

對於SimpleDateFormat ,您調用toLocalizedPattern()

編輯:

對於Java 8用戶:

Java 8日期時間API與Joda-time類似。 為了獲得本地化的模式,我們可以使用類DateTimeFormatter

DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);

請注意,當您在LocalDate上調用toString()時,您將獲得ISO-8601格式的日期

請注意,Java 8中的Date Time API受Joda Time的啟發,大多數解決方案都可以基於與時間有關的問題。

對於仍在使用Java 7和更早版本的用戶:

您可以使用如下形式:

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

由於從getDateInstance()返回的DateFormatSimpleDateFormat實例。 這兩個方法實際上也應該在DateFormat中,這樣可以減少hacky的麻煩,但目前還不是。

我正在回答自己的問題可能很奇怪,但是我相信,我可以在圖片中添加一些內容。

ICU實施

顯然,Java 8為您提供了很多東西,但還有其他東西: ICU4J 實際上,這是Java原始實現的源,例如CalendarDateFormatSimpleDateFormat ,僅舉幾例。
因此,ICU的SimpleDateFormat還包含諸如toPattern()toLocalizedPattern()類的方法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
  • 平日
  • 小時
  • 小時24
  • 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

當然,有很多。 它們的優點在於,這些模式實際上是字符串(如java.lang.String ),也就是說,如果您使用英語模式"MM/d" ,則將獲得特定於語言環境的模式。 在某些極端情況下,它可能很有用。 通常,您只使用DateFormat實例,而不關心模式本身。

特定於語言環境的模式與本地化模式

問題的意圖是要本地化,而不是特定於語言環境的模式。 有什么不同?

從理論上講, toPattern()將為您提供特定於Locale環境的模式(取決於您用來實例化(Simple)DateFormat Locale )。 也就是說,無論您使用哪種目標語言/國家/地區,都將獲得由yMdhHM等符號組成的模式。

另一方面, toLocalizedPattern() 應該返回本地化的模式,這適合最終用戶閱讀和理解。 例如,德語中間(默認)日期格式為:

  • toPattern():dd.MM.yyyy
  • toLocalizedPattern():tt.MM.jjjj(天=標簽,月= Monat,年= Jahr)

該問題的意圖是:“如何找到可以用作日期/時間格式提示的本地化模式”。 也就是說,假設我們有一個日期字段,用戶可以使用特定於語言環境的模式進行填寫,但是我想以本地化形式顯示格式提示。

可悲的是,到目前為止,還沒有好的解決方案。 我在本文前面提到的ICU部分起作用。 這是因為,ICU使用的數據來自CLDR ,但不幸的是部分翻譯/部分正確。 以我母親的舌頭為例,在撰寫本文時,沒有正確翻譯出圖案或其局部形式。 每次我糾正它們時,我都會被其他人投票,這些人不必住在波蘭,也不用講波蘭語...

這個故事的寓意:不要完全依靠CLDR。 您仍然需要聘請本地審核員/語言審核員。

您可以在Java 8中使用DateTimeFormatterBuilder 。下面的示例返回本地化的僅日期模式,例如"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開箱即用地提供了一些有用的功能,用於處理日期和時間並對其進行格式化/解析,包括處理語言環境。 這是一個簡短的介紹。

基本模式

在最簡單的格式/解析日期格式中,您可以將以下代碼與String模式一起使用:

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

然后,標准是將其與date對象直接用於格式化:

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

然后使用工廠模式來解析日期:

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

模式本身具有大量選項,將涵蓋大多數用例,可以在此處的javadoc位置找到完整的摘要。

語言環境

包含區域設置非常簡單,對於默認區域設置,您可以使用以下選項,然后將這些選項應用於上面演示的format / parse選項:

DateTimeFormatter.ofLocalizedDate(dateStyle);

上面的'dateStyle'是一個FormatStyle選項Enum,用於表示使用DateTimeFormatter時本地化Date的完整,長,中和短版本。 使用FormatStyle,您還可以使用以下選項:

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

最后一個選項允許您為日期和時間指定不同的FormatStyle 如果您不使用默認的Locale,則可以使用.withLocale選項調整每個Localized方法的返回值,例如

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

另外,ofPattern也有一個重載版本以指定語言環境

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

我需要更多!

DateTimeFormatter將滿足大多數用例,但是它基於DateTimeFormatterBuilder構建,它為構建器的用戶提供了廣泛的選擇范圍。 使用DateTimeFormatter開頭,如果需要這些擴展的格式設置功能,可使用構建器。

請在下面的代碼中找到,該代碼接受語言環境實例並返回特定於語言環境的數據格式/模式。

 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;
}

因為這只是您要查找的語言環境信息 ,所以我認為您需要做的是找到JVM(OpenJDK或Harmony)實際上用作整個Locale事物輸入的文件,並弄清楚如何解析它。 或者只是在網絡上使用其他來源(肯定在某處有一個列表)。 這樣可以節省那些可憐的翻譯員。

您可以嘗試類似:

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());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM