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
必要以上に複雑にしています:
DateTime dt = new DateTime(DateTimeZone.UTC);
いいえconversionはまったく必要ありません。実際に変換する必要がある場合は、 withZone
を使用できます。 avoidLocalDateTime
を経由することをお勧めしますが、そのようにすると、タイムゾーンの遷移(2つの異なるクロックは戻って現地時間を繰り返すため、インスタントは同じタイムゾーンで同じ現地時間を持つことができます。
このすべてを言ったが、テストしやすいように、私は個人的に現在の時刻を取得できるClock
インターフェイスを使用するのが好きです(たとえば、Instant
として)。その後、依存性注入を使用して、実稼働環境で実際のシステムクロックを注入し、テスト用に事前設定された時間で偽のクロックを注入できます。 Java 8のJava.time
パッケージには、このアイデアが組み込まれています。
静的メソッド now を使用して、さらに読みやすくすることもできます。
DateTime.now(DateTimeZone.UTC)
これを使って
DateTime.now().withZone(DateTimeZone.UTC)
そして、フォーマットしたい場合は、使用することができます
DateTime.now().withZone(DateTimeZone.UTC).toString("yyyyMMddHHmmss")
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
のオブジェクトLocalDateTime
でtoDate()
を呼び出すと、驚きを得ることができます- 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()
の呼び出しを完全に放棄します。この方法では、危険な変換を行う必要さえありません。
ここから: 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)の代わりに「ヨーロッパ/ロンドン」を使用できます。 適切なタイムゾーン名のこのリスト を参照してください。
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())の代わりにローカル日付を入れます
このコンバーターでこれを修正しました
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として保存され、現在のタイムゾーンで復元されます