web-dev-qa-db-ja.com

JodaTime-UTCで現在時刻を取得する方法

UTCで現在の時刻を取得したい。これまで私がやっていることは、次のことです(テスト目的でのみ)。

    DateTime dt = new DateTime();
    DateTimeZone tz = DateTimeZone.getDefault();
    LocalDateTime nowLocal = new LocalDateTime();
    DateTime nowUTC = nowLocal.toDateTime(DateTimeZone.UTC);

    Date d1 = nowLocal.toDate();
    Date d2 = nowUTC.toDate();

    L.d("tz: " + tz.toString());
    L.d("local: " + d1.toString());
    L.d("utc: " + d2.toString());
  • d1は現地時間です、それでいいです
  • d2は現地時間+ 1ですが、現地時間でなければなりません-1 ...

私のローカルタイムゾーンはUTC + 1です(デバッグ出力とここのリストによると: https://www.joda.org/joda-time/timezones.html )...

あるタイムゾーンから別のタイムゾーン(ミリ秒表現を含む)に正しく変換するにはどうすればよいですか?

[〜#〜] edit [〜#〜]

日付/ミリ秒が必要です...時刻を正しく表示することではありません...

EDIT 2

今、コメントと回答の助けを借りて、私は次のことを試しました:

    DateTimeZone tz = DateTimeZone.getDefault();
    DateTime nowLocal = new DateTime();
    LocalDateTime nowUTC = nowLocal.withZone(DateTimeZone.UTC).toLocalDateTime();
    DateTime nowUTC2 = nowLocal.withZone(DateTimeZone.UTC);

    Date dLocal = nowLocal.toDate();
    Date dUTC = nowUTC.toDate();
    Date dUTC2 = nowUTC2.toDate();

    L.d(Temp.class, "------------------------");
    L.d(Temp.class, "tz    : " + tz.toString());
    L.d(Temp.class, "local : " + nowLocal +     " | " + dLocal.toString());
    L.d(Temp.class, "utc   : " + nowUTC +       " | " + dUTC.toString()); // <= WORKING SOLUTION
    L.d(Temp.class, "utc2  : " + nowUTC2 +      " | " + dUTC2.toString());

[〜#〜] output [〜#〜]

tz    : Europe/Belgrade
local : 2015-01-02T15:31:38.241+01:00 | Fri Jan 02 15:31:38 MEZ 2015
utc   : 2015-01-02T14:31:38.241 | Fri Jan 02 14:31:38 MEZ 2015
utc2  : 2015-01-02T14:31:38.241Z | Fri Jan 02 15:31:38 MEZ 2015

私が欲しかったのは、現地の日付が15時を表示し、UTCの日付が14時を表示することでした...今のところ、これはうまくいくようです...

----- EDIT3-最終的な解決策-----

うまくいけば、これは良い解決策です...私は私が得たすべてのヒントを尊重していると思います...

    DateTimeZone tz = DateTimeZone.getDefault();
    DateTime nowUTC = new DateTime(DateTimeZone.UTC);
    DateTime nowLocal = nowUTC.withZone(tz);

    // This will generate DIFFERENT Dates!!! As I want it!
    Date dLocal = nowLocal.toLocalDateTime().toDate();
    Date dUTC = nowUTC.toLocalDateTime().toDate();

    L.d("tz    : " + tz.toString());
    L.d("local : " + nowLocal +     " | " + dLocal.toString());
    L.d("utc   : " + nowUTC +       " | " + dUTC.toString());

出力:

tz    : Europe/Belgrade
local : 2015-01-03T21:15:35.170+01:00 | Sat Jan 03 21:15:35 MEZ 2015
utc   : 2015-01-03T20:15:35.170Z | Sat Jan 03 20:15:35 MEZ 2015
22
prom85

必要以上に複雑にしています:

DateTime dt = new DateTime(DateTimeZone.UTC);

いいえconversionはまったく必要ありません。実際に変換する必要がある場合は、 withZone を使用できます。 avoidLocalDateTimeを経由することをお勧めしますが、そのようにすると、タイムゾーンの遷移(2つの異なるクロックは戻って現地時間を繰り返すため、インスタントは同じタイムゾーンで同じ現地時間を持つことができます。

このすべてを言ったが、テストしやすいように、私は個人的に現在の時刻を取得できるClockインターフェイスを使用するのが好きです(たとえば、Instantとして)。その後、依存性注入を使用して、実稼働環境で実際のシステムクロックを注入し、テスト用に事前設定された時間で偽のクロックを注入できます。 Java 8のJava.timeパッケージには、このアイデアが組み込まれています。

71
Jon Skeet

静的メソッド now を使用して、さらに読みやすくすることもできます。

DateTime.now(DateTimeZone.UTC)
10
Kobynet

これを使って

DateTime.now().withZone(DateTimeZone.UTC)

そして、フォーマットしたい場合は、使用することができます

DateTime.now().withZone(DateTimeZone.UTC).toString("yyyyMMddHHmmss")
8
Naidu

Jon Skeetsの良いアドバイスとコメントを聞いてみてください。ここで追加の説明。 edit-2に誤りがあります:

_DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowLocal = new DateTime();
LocalDateTime nowUTC = nowLocal.withZone(DateTimeZone.UTC).toLocalDateTime();
DateTime nowUTC2 = nowLocal.withZone(DateTimeZone.UTC);

Date dLocal = nowLocal.toDate();
Date dUTC = nowUTC.toDate();
Date dUTC2 = nowUTC2.toDate();
_

タイプnowUTCのオブジェクトLocalDateTimetoDate()を呼び出すと、驚きを得ることができます- javadoc を参照してください。 Joda-Timeは、nowUTCのように_the same fields_で_Java.util.Date_を使用すると主張しています。これは何を意味するのでしょうか?分析しましょう:

nowUTC.toString()は_2015-01-02T14:31:38.241_を生成します。これはタイムゾーンがないため(最後にZがないことに注意してください)、単なるローカルタイムスタンプになります。コンテキストにより、UTCで生成されたことがわかります。ただし、次の手順では、上記の方法を使用して_Java.util.Date_に変換します。このメソッドは、ローカルタイムスタンプとシステムタイムゾーン(ベオグラード)を組み合わせてFIELDSを保存するため、インスタントを変更します。あなたはついにあなたのインスタントを誤って修正しました。そして、2行目が間違っています。

ただ欲しいなら

utcの日付は14時を表示します

joda-Timeが提供する疑わしく誤解を招く変換方法を使用しないでください。代わりに、パターン「EEE MMM dd HH:mm:ss zzz yyyy」または同様の専用のフォーマッターを使用してください(Joda-TimeはDateTimeFormatterを提供します)。このフォーマッタでUTCオフセットを設定して印刷します。できたJava.util.Date.toString()の呼び出しを完全に放棄します。この方法では、危険な変換を行う必要さえありません。

3
Meno Hochschild

ここから: http://www.joda.org/joda-time/userguide.html#Changing_TimeZone

// get current moment in default time zone
DateTime dt = new DateTime();
// translate to London local time
DateTime dtLondon = dt.withZone(DateTimeZone.forID("Europe/London"));

結果の値dtLondonの絶対ミリ秒時間は同じですが、フィールド値のセットが異なります。

希望するタイムゾーン(UTC)の代わりに「ヨーロッパ/ロンドン」を使用できます。 適切なタイムゾーン名のこのリスト を参照してください。

2
Greg Kopff
    SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
    // or SimpleDateFormat sdf = new SimpleDateFormat( "MM/dd/yyyy KK:mm:ss a Z" );
    sdf.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
    System.out.println( sdf.format( new Date() ) 

);

System.out.println(sdf.format(new Date())の代わりにローカル日付を入れます

0
SW DEV07

このコンバーターでこれを修正しました

public class DateTimeConverter implements AttributeConverter<DateTime, Date> {
    @Override
    public Date convertToDatabaseColumn(DateTime attribute) {
        return attribute == null ? null
                : new Date(attribute
                        .withZone(DateTimeZone.UTC)
                        .withZoneRetainFields(DateTimeZone.getDefault())
                        .getMillis());
    }

    @Override
    public DateTime convertToEntityAttribute(Date dbData) {
        return dbData == null ? null
               : new DateTime(dbData.getTime())
                        .withZoneRetainFields(DateTimeZone.UTC)
                        .withZone(DateTimeZone.getDefault());
    }
}

日付はUTCとして保存され、現在のタイムゾーンで復元されます

0
Wicowyn