web-dev-qa-db-ja.com

SimpleDateFormatおよびロケールベースのフォーマット文字列

指定されたロケールに基づいてさまざまな方法でJavaの日付をフォーマットしようとしています。たとえば、英語のユーザーには「2009年11月1日」(「MMM d、yyyy」でフォーマット)、ノルウェーのユーザーには「1. nov。2009」(「d。MMM。yyyy」)が表示されます。

SimpleDateFormatコンストラクターにロケールを追加すれば月の部分は問題なく動作しますが、残りはどうでしょうか?

ロケールとペアになっている書式文字列をSimpleDateFormatに追加できることを望んでいましたが、これを行う方法が見つかりません。可能ですか、それともコードにロケールをチェックさせ、対応するフォーマット文字列を追加させる必要がありますか?

72
fiskeben

SimpleDateFormatを使用して独自のパターンを作成する代わりに、 DateFormat.getDateInstance(int style、Locale locale) を使用します。

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

style + localeを使用します: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
27
JuanZe

tl; dr

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

厄介なJava.util.DateおよびSimpleDateFormatのクラスは、Java.timeクラスに取って代わられたレガシーです。

LocalDate

LocalDate クラスは、時刻とタイムゾーンのない日付のみの値を表します。

タイムゾーンは、日付を決定する際に重要です。どのような場合でも、日付はゾーンごとに世界中で異なります。たとえば、 Paris France の真夜中から数分後は新しい日であり、 MontréalQuébec の「昨日」のままです。

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

DateTimeFormatter

DateTimeFormatter を使用して、日付部分または時間部分のみを表す文字列を生成します。

DateTimeFormatter クラスは、自動的に localize できます。

ローカライズするには、次を指定します。

  • FormatStyle は、文字列の長さまたは短縮名を決定します。
  • Locale は、(a)曜日の名前、月の名前などの翻訳のための人間の言語、および(b)略語、大文字、句読点などの問題を決定する文化的規範を決定します。

例:

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

他の方向に進むと、ローカライズされた文字列を解析できます。

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

ロケールとタイムゾーンは完全に直交する問題であることに注意してください。モントリオールの瞬間を日本語で、またはニュージーランドのオークランドの瞬間をヒンディー語で提示することができます。

別の例:6 junio 2012(スペイン語)を2012-06-06(標準 ISO 8601 形式)に変更します。 Java.timeクラスは、文字列の解析/生成にデフォルトでISO 8601形式を使用します。

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. 

熟読フォーマット

以下は、複数のロケールで複数の形式の結果を自動的にローカライズするためのコードの例です。

EnumSetSet の実装であり、 Enum オブジェクトを収集する際の低メモリ使用量と高速実行速度の両方に対して高度に最適化されています。したがって、EnumSet.allOf( FormatStyle.class )は、ループする FormatStyle enumオブジェクトの4つすべてのコレクションを提供します。詳細については、 列挙型に関するOracleチュートリアル を参照してください。

LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 );

List < Locale > locales = new ArrayList <>( 3 );
locales.add( Locale.CANADA_FRENCH );
locales.add( new Locale( "no" , "NO" ) );
locales.add( Locale.US );

// Or use all locales (almost 800 of them, for about 120K text results).
// Locale[] locales = Locale.getAvailableLocales(); // All known locales. Almost 800 of them.

for ( Locale locale : locales )
{
    System.out.println( "------|  LOCALE: " + locale + " — " + locale.getDisplayName() + "  |----------------------------------" + System.lineSeparator() );

    for ( FormatStyle style : EnumSet.allOf( FormatStyle.class ) )
    {
        DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( style ).withLocale( locale );
        String output = ld.format( f );
        System.out.println( output );
    }
    System.out.println( "" );
}
System.out.println( "« fin »" + System.lineSeparator() );

出力。

------|  LOCALE: fr_CA — French (Canada)  |----------------------------------

mardi 23 janvier 2018
23 janvier 2018
23 janv. 2018
18-01-23

------|  LOCALE: no_NO — Norwegian (Norway)  |----------------------------------

tirsdag 23. januar 2018
23. januar 2018
23. jan. 2018
23.01.2018

------|  LOCALE: en_US — English (United States)  |----------------------------------

Tuesday, January 23, 2018
January 23, 2018
Jan 23, 2018
1/23/18

« fin »

Java.timeについて

Java.time フレームワークは、Java 8以降に組み込まれています。これらのクラスは、 Java.util.DateCalendar 、& SimpleDateFormat などの厄介な古い legacy date-timeクラスに取って代わります。

Joda-Time プロジェクトは、現在 メンテナンスモード であり、 Java.time クラスへの移行を推奨しています。

詳細については、 Oracle Tutorial を参照してください。また、Stack Overflowで多くの例と説明を検索してください。指定は JSR 31 です。

Java.timeオブジェクトをデータベースと直接交換できます。 JDBC 4.2 以降に準拠する JDBCドライバー を使用します。文字列もJava.sql.*クラスも必要ありません。

Java.timeクラスはどこで入手できますか?

  • Java SE 8Java SE 9 、およびそれ以降
    • ビルトイン。
    • 実装がバンドルされた標準Java AP​​Iの一部。
    • Java 9は、いくつかのマイナーな機能と修正を追加します。
  • Java SE 6 および Java SE 7
    • Java.time機能の多くは、 ThreeTen-Backport のJava 6および7にバックポートされています。
  • Android
    • Androidの後のバージョンは、Java.timeクラスの実装をバンドルします。
    • 以前のAndroidの場合、 ThreeTenABP プロジェクトはThreeTen-Backport(上記)に適合します。 ThreeTenABPの使用方法… を参照してください。

ThreeTen-Extra プロジェクトは、追加のクラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性のある証明の場です。 IntervalYearWeekYearQuarter 、および more などの便利なクラスがあります。

13
Basil Bourque

日付文字列のローカライズ:

Redsonicの投稿に基づく:

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のようになります

8
Yaro

これにより、ユーザーの現在のロケールに従って日付が表示されます。

日付と時刻を返すには:

import Java.text.DateFormat;    
import Java.util.Date;

Date date = new Date();
DateFormat df = DateFormat.getDateTimeInstance();
String myDate = df.format(date);

1969年12月31日7:00:02 PM

日付のみを返すには、次を使用します。

DateFormat.getDateInstance() 

1969年12月31日

2
live-love
String text = new SimpleDateFormat("E, MMM d, yyyy").format(date);
0
Hadid Graphics

特定の日付の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)));
0
Mircea Stanciu