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


83

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

SimpleDateFormatコンストラクターにロケールを追加すると、月の部分は問題なく機能しますが、残りはどうでしょうか。

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


1
FYI、といった面倒な古い日付時刻クラスjava.util.Datejava.util.Calendarjava.text.SimpleDateFormat今のレガシーに取って代わられ、java.timeのJavaの8&9のJavaを参照してくださいに組み込まれたクラスのチュートリアルOracleで
バジルバーク2018年

回答:


87

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


1
おかげで、これは問題なく動作します。私は自分のニーズに最も適したDateFormat.LONGを選びました。ところで、ノルウェーのロケールとDateFormat.MEDIUMはがらくた(!)
fiskeben 2009年

そうです、ノルウェー人にとって奇妙なMEDIUMパターンは私には決して起こりませんでした。他のほとんどのロケールとは対照的に、平日もFULL形式で欠落しています。
jarnbjo 2009年

2
FYI、面倒なクラスjava.util.DateSimpleDateFormatなりましたjava.timeクラスに取って代わら遺産、です。
バジルバーク2016

89

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

29

スタイル+ロケールを使用します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

1
DateFormat.LONGDateFormat.DEFAULTスタイルを忘れないでください!
JDJ 2014年

6
コードの出力の追加はもっと完全だったでしょう
sam

1
スタイルとロケールを指定する正しいアイデア。しかし、使用されるクラスは現在時代遅れです。以下のような面倒な古い日付時刻クラスjava.util.Datejava.util.Calendarjava.text.SimpleDateFormat今のレガシーに取って代わられ、java.timeのJavaの8&9のJavaを参照してくださいに組み込まれたクラスのチュートリアルOracleで
バジルバーク

15

tl; dr

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

の厄介なクラスjava.util.DateSimpleDateFormatは現在レガシーであり、java.timeクラスに取って代わられています。

LocalDate

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

日付を決定するには、タイムゾーンが重要です。いつでも、日付はゾーンごとに世界中で異なります。たとえば、パリの真夜中から数分後のフランスは、モントリオールケベックではまだ「昨日」であるのに新しい日です。

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

DateTimeFormatter

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

DateTimeFormatterクラスが自動的にできるローカライズ

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

  • 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クラスは、文字列の解析/生成にデフォルトでISO8601形式を使用します。

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. 

フォーマットを熟読する

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

ANはEnumSet実装されSet、非常に低いメモリ使用量と速い実行速度収集の両方に最適化され、Enumオブジェクトを。したがって、ループするEnumSet.allOf( FormatStyle.class )4つのFormatStyle列挙型オブジェクトすべてのコレクションを提供します。詳細は、列挙型に関する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フレームワークは、Java8以降に組み込まれています。これらのクラスは面倒古い取って代わるレガシーのような日付時刻クラスをjava.util.DateCalendar、& SimpleDateFormat

ジョダタイムプロジェクトは、今でメンテナンスモードへの移行をアドバイスjava.timeのクラス。

詳細については、Oracleチュートリアルを参照してください。そして、StackOverflowで多くの例と説明を検索してください。仕様はJSR310です。

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

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

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

ThreeTen-エクストラプロジェクトでは、追加のクラスでjava.timeを拡張します。このプロジェクトは、java.timeに将来追加される可能性のある試験場です。あなたはここにいくつかの有用なクラスのような見つけることがIntervalYearWeekYearQuarter、および多くを


8

日付文字列のローカリゼーション:

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

2013年5月9月のようになります


4

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

日付と時刻を返すには:

import java.text.DateFormat;    
import java.util.Date;

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

1969年12月31日19:00:02

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

DateFormat.getDateInstance() 

1969年12月31日


1

特定の日付のJava8スタイル

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

これが誰かを助けることを願っています。ロケールインスタンスを受け入れ、ロケール固有の日付形式/パターンを返す以下のコードを見つけてください。

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

Java8

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

ofPatternロケール引数とともに使用すると、希望する言語で月の名前が表示されますが、質問で要求された異なる形式では表示されません。大文字YYYYを使用すると、コーナーケースで不正確で非常に驚くべき結果が得られます。Java8を使用することをお勧めします。
Ole VV
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.