web-dev-qa-db-ja.com

ローカライズされた日付パターン文字列を取得するにはどうすればよいですか?

DateFormat のインスタンスを使用してJava Date(またはCalendar)クラスをフォーマットおよび解析するのは非常に簡単です。

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

私の問題は、このローカライズされたパターン文字列(つまり、"MM/dd/yy")。これは簡単な作業になりますが、プロバイダーが見つかりませんでした...

44
Paweł Dyda

SimpleDateFormat の場合、 toLocalizedPattern() を呼び出します

編集:

Java 8ユーザーの場合:

Java 8 Date Time 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のインスタンスであるため。これら2つのメソッドは、実際にはDateFormatにも含まれている必要がありますが、これはハックを軽減するためですが、現在はそうではありません。

31
Zarremgregarrok

私自身の質問に答えているのは奇妙なことかもしれませんが、写真に何かを追加できると信じています。

ICUの実装

明らかに、Java 8は多くを与えますが、他にも何かあります: ICU4J 。これは実際にJavaのソースですいくつか例を挙げると、CalendarDateFormatSimpleDateFormatなどの元の実装。
したがって、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
  • 四半期
  • YEAR_ABBR_QUARTER
  • YEAR_QUARTER
  • YEAR_ABBR_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
  • 平日
  • 営業時間
  • 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

確かに、かなりあります。これらの良い点は、これらのパターンが実際には文字列であることです(_Java.lang.String_のように)。つまり、英語のパターン_"MM/d"_を使用すると、ロケール固有のパターンが返されます。いくつかの場合に役立つかもしれません。通常はDateFormatインスタンスを使用するだけで、パターン自体は気にしません。

ロケール固有のパターンとローカライズされたパターン

質問の意図は、ロケール固有のパターンではなく、ローカライズすることでした。違いは何ですか?

理論上、toPattern()はロケール固有のパターンを提供します(_(Simple)DateFormat_のインスタンス化に使用したLocaleに依存します)。つまり、どのターゲット言語/国を配置しても、yMdhなどの記号で構成されるパターンを取得できます。 、HMなど。

一方、toLocalizedPattern()shouldはローカライズされたパターンを返します。これは、エンドユーザーが読み、理解するのに適したものです。たとえば、ドイツの中間(デフォルト)日付パターンは次のようになります。

  • toPattern():dd.MM.yyyy
  • toLocalizedPattern():tt.MM.jjjj(日=タグ、月=モナト、​​年= Jahr)

質問の意図は、「日付/時刻形式が何であるかについてのヒントとして役立つローカライズされたパターンを見つける方法」でした。つまり、ユーザーがロケール固有のパターンを使用して入力できる日付フィールドがあるが、ローカライズされた形式で形式のヒントを表示したいとします。

悲しいことに、これまでのところ良い解決策はありません。 ICUこの投稿で前述したように、部分的に動作します。ICUが使用するデータは [〜#〜] cldr [〜#〜] 、これは残念ながら部分的に翻訳されています/部分的に正しいです母の舌の場合、執筆時点では、パターンもローカライズされたフォームも正しく翻訳されていません。ポーランドに住んでいる必要もポーランド語も話せない他の人々に献身された.

この話の教訓:CLDRに完全に依存しないでください。現地の監査人/言語レビューアが必要です。

20
Paweł Dyda

DateTimeFormatterBuilder in Java 8.を使用できます。次の例では、ローカライズされた日付のみのパターンを返します。例:"d.M.yyyy"

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

次のコードは、ロケールのパターンを提供します。

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

Java 8は、ロケールの処理を含む、日付と時刻の操作と書式設定/解析のために、すぐに使える便利な機能をいくつか提供します。ここに簡単な紹介があります。

基本パターン

日付をフォーマット/解析する最も簡単なケースでは、文字列パターンで次のコードを使用します。

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

標準では、書式設定のためにこれを日付オブジェクトで直接使用することです。

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

次に、ファクトリパターンを使用して日付を解析します。

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

パターン自体には、大部分のユースケースをカバーする多数のオプションがあり、完全な要約はjavadocの場所 here で見つけることができます。

ロケール

ロケールの組み込みは非常に簡単です。デフォルトロケールの場合、上記の形式/解析オプションに適用できる次のオプションがあります。

DateTimeFormatter.ofLocalizedDate(dateStyle);

上の「dateStyle」は、 FormatStyle オプションEnumであり、DateTimeFormatterを操作するときにローカライズされたDateのフル、ロング、ミディアム、ショートバージョンを表します。 FormatStyle を使用すると、次のオプションもあります。

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

最後のオプションでは、日付と時刻に異なる FormatStyle を指定できます。デフォルトのロケールで作業していない場合、ローカライズされた各メソッドの戻り値は、.withLocaleオプションを使用して調整できます。

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

または、ofPatternにはロケールを指定するためのオーバーロードバージョンがあります

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

もっと必要!

DateTimeFormatterは、ほとんどのユースケースに対応しますが、ビルダーのユーザーに広範なオプションを提供する DateTimeFormatterBuilder に基づいて構築されます。 DateTimeFormatterを使用して開始し、これらの広範なフォーマット機能が必要な場合は、ビルダーにフォールバックします。

4
Jim

以下のコードで、ロケールインスタンスを受け入れ、ロケール固有のデータ形式/パターンを返すコードを見つけてください。

 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;
}
2
Dinesh Lomte

それは単なるロケールであるためinformationあとは、JVM(OpenJDKまたはHarmony)がLocale事とそれを解析する方法を見つけます。または、単にWeb上の別のソースを使用します(リストはどこかにあります)。それはそれらの貧しい翻訳者を救います。

0
David Bullock