Javaで文字列をカレンダーオブジェクトに変換


174

私はJavaを初めて使用し、通常はPHPで動作します。

私はこの文字列を変換しようとしています:

2011年3月14日(月)16:02:37 GMT

次のように年と月を簡単に取得できるように、カレンダーオブジェクトに入れます。

String yearAndMonth = cal.get(Calendar.YEAR)+cal.get(Calendar.MONTH);

手動で解析するのは悪い考えでしょうか?部分文字列メソッドを使用していますか?

どんなアドバイスでも感謝します!


回答:


396
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
cal.setTime(sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done

注:Locale環境/要件に応じて設定


こちらもご覧ください


onlineconversion.com/unix_time.htm。これはオンラインのタイムスタンプコンバータです。Javaコードによって計算された値とこのオンラインコンバージョンは異なります。なぜ??あなたはこれを経験できますか?おかげで:)
Sachin J

6
これはタイムゾーン情報を失うことに注意してください。Calendarオブジェクトには、解析されたものではなく、システムのデフォルトのTimeZoneがあります。
クリスティアンヴラビー

これはもはやトップ/受け入れられた答えであってはなりません。Java 8はすでに4年以上使用されていないため、回答を更新して言及する必要がありますjava.time。このQ / Aはグーグルでかなり目立つようになります。
Scolytus、2018年

18

tl; dr

最新のアプローチでは、java.timeクラスを使用します。

YearMonth.from(
    ZonedDateTime.parse( 
        "Mon Mar 14 16:02:37 GMT 2011" , 
        DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" )
     )
).toString()

2011-03

従来の日時クラスを避ける

最新の方法は、java.timeクラスを使用する方法です。次のような古い日時クラスCalendar、設計が不十分で、混乱し、面倒であることが証明されています。

文字列入力に一致するカスタムフォーマッタを定義します。

String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );

として解析しますZonedDateTime

ZonedDateTime zdt = ZonedDateTime.parse( input , f );

あなたは年と月に興味があります。java.timeクラスにはYearMonth、そのためのクラスが含まれています。

YearMonth ym = YearMonth.from( zdt );

必要に応じて、年と月の番号を問い合わせることができます。

int year = ym.getYear();
int month = ym.getMonthValue();

ただし、このtoStringメソッドは標準のISO 8601形式で文字列を生成します。

String output = ym.toString();

これをすべてまとめます。

String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
YearMonth ym = YearMonth.from( zdt );
int year = ym.getYear();
int month = ym.getMonthValue();

コンソールにダンプします。

System.out.println( "input: " + input );
System.out.println( "zdt: " + zdt );
System.out.println( "ym: " + ym );

入力:2011年3月14日16:02:37 GMT

zdt:2011-03-14T16:02:37Z [GMT]

ym:2011-03

ライブコード

IdeOne.comで実行されているこのコードを参照してください。

変換

あなたがいる場合必要があります持っているCalendarオブジェクトを、あなたがに変換することができGregorianCalendar、古いクラスに追加使用して、新しい方法。

GregorianCalendar gc = GregorianCalendar.from( zdt );

java.timeについて

java.timeのフレームワークは、Java 8に組み込まれており、後にされています。これらのクラスは面倒古い取って代わるレガシーのような日付時刻クラスjava.util.DateCalendar&を、SimpleDateFormat

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

詳細については、Oracleチュートリアルを参照してください。また、スタックオーバーフローで多くの例と説明を検索してください。仕様はJSR 310です。

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

  • Java SE 8および SE 9以降
    • 内蔵。
    • 実装がバンドルされた標準Java APIの一部。
    • Java 9では、いくつかのマイナーな機能と修正が追加されています。
  • Java SE 6および SE 7
    • java.time機能の多くは、ThreeTen-BackportでJava 6および7にバックポートされています。
  • アンドロイド
    • ThreeTenABPのプロジェクトは、適応ThreeTen、バックポート、特にAndroidのための(上記の)。
    • 使い方…をご覧ください。

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


14

まあ、私はすでにのようなクラスに存在しているコードを複製するのは悪い考えだと思います SimpleDateFormat

一方、個人的には、可能であれば完全に回避しCalendar、代わりにJoda TimeDateを使用して、はるかに優れた設計の日時APIとして使用することをお勧めします。たとえば、スレッドセーフではないことに注意する必要があるため、使用するたびにスレッドローカル、同期、または新しいインスタンスが必要になります。Jodaパーサーとフォーマッタースレッドセーフです。SimpleDateFormat


ご意見をお寄せいただきありがとうございます。今後もJodaの使用を検討していきます。非常に役立つと思います
Doug Molineux

@Jon Skeet JodaはAndroidではデシリアライズしません。日付と時間を節約する必要がない限り、Jodaはほとんど価値がありません。
フランクザッパ

@FrankZappa:私はそれに同意しません-すべての日付/時刻の計算をJoda Timeで行うことができますが、シリアル化の目的で他の型(おそらく単純にするために文字列のみ)に変換できます。
ジョンスキート2017

申し訳ありませんが、反対票を投じなければなりませんでした。回答が古すぎます。最高ランクの回答になるには時代遅れです。今日java.timeがその道です。BasilBourqueが素晴らしい答えを出しました。
Scolytus、2018年

2
@Scolytus:上位(および承認済み)の回答は332票で、これは10票です。今より良い解決策がある7年以上前のすべての回答に反対票を投じると、反対票が足りなくなると思います...(バジルの回答は良いと私は同意し、私はそれを支持しました。)
ジョンスキート2018年

10

新しいカレンダーを作成する必要はありません。SimpleDateFormatはすでにその下のカレンダーを使用しています。

SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.EN_US);
Date date = sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done
Calendar cal = sdf.getCalendar();

(まだコメントはできません。そのため、新しい回答を作成しました)


1
ソリューションはエレガントに見えますが、次の2つの欠点があります。1. JavaDocは、期待どおりの動作を保証しません。2.少なくともJava 6の場合、カレンダーオブジェクトが複製される1353行目にパスがあります。したがって、次に!date.equals(cal.getTime())となります。
niels

5

SimpleDateFormat素晴らしいですが、何時間も使用する場合とHHは異なりhhます。HH24時間ベースの時間を返し、hhは12時間ベースの時間を返します。

たとえば、次は12時間の時間を返します。

SimpleDateFormat sdf = new SimpleDateFormat("hh:mm aa");

これは24時間の時間を返しますが、

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");

4

Z時間帯のパターンを時間帯で解析します

String aTime = "2017-10-25T11:39:00+09:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
try {
    Calendar cal = Calendar.getInstance();
    cal.setTime(sdf.parse(aTime));
    Log.i(TAG, "time = " + cal.getTimeInMillis()); 
} catch (ParseException e) {
    e.printStackTrace();
}

出力:UTC時間を返します

1508899140000

ここに画像の説明を入力してください

のようなパターンでタイムゾーンを設定しない場合yyyy-MM-dd'T'HH:mm:ssSimpleDateFormatで設定されているタイムゾーンを使用しますSetting



1

簡単な方法:

public Calendar stringToCalendar(String date, String pattern) throws ParseException {
    String DEFAULT_LOCALE_NAME = "pt";
    String DEFAULT_COUNTRY = "BR";
    Locale DEFAULT_LOCALE = new Locale(DEFAULT_LOCALE_NAME, DEFAULT_COUNTRY);
    SimpleDateFormat format = new SimpleDateFormat(pattern, LocaleUtils.DEFAULT_LOCALE);
    Date d = format.parse(date);
    Calendar c = getCalendar();
    c.setTime(d);
    return c;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.