web-dev-qa-db-ja.com

ジョーダ時間で時間を変更せずにタイムゾーンを変換する方法

JodaTime DateTimeインスタンスに設定しているデータベースからUTCタイムスタンプを取得しています

_DateTime dt = new DateTime(timestamp.getTime());
_

それは完全に_10:00 AM_と言う時間を保存しますが、ローカルタイムゾーンを使用します。たとえば、UTCから+5:30のISTタイムゾーンにいます

タイムゾーンを変更するために多くのことを試してみましたが、すべてのことで、時間を_10:00 AM_から+5:30の差を使用して他の何かに変更します

現在の時間に影響を与えずにTimeZoneを変更できる方法はありますか

編集:私の現在の時間が:

_2013-09-25 11:27:34 AM      UTC
_

以下は、このnew DateTime(timestamp.getTime());を使用したときの結果です

_2013-09-25 11:27:34 AM  Asia/Kolkata
_

そして、このnew DateTime(timestamp.getTime(), DateTimeZone.UTC);を使用した場合の結果は次のとおりです。

_2013-09-25 05:57:34 AM  UTC
_
53
Abhi

クラス LocalDateTime を使用できます

LocalDateTime dt = new LocalDateTime(t.getTime()); 

LocalDateTimeDateTimeに変換します

DateTime dt = new LocalDateTime(timestamp.getTime()).toDateTime(DateTimeZone.UTC);  

Joda DateTimeは、「currentタイムゾーンの1970年以降のミリ秒」のように、ミリ単位の時間を扱います。したがって、DateTimeインスタンスを作成すると、現在のタイムゾーンで作成されます。

46
Ilya

DateTimewithZoneRetainFields()メソッドを使用して、日付の数字を変更せずにタイムゾーンを変更できます。

45
jgm

タイムスタンプが2015-01-01T00:00:00.000-0500の場合(これは現地時間です(私にとって))

これを試して:

DateTime localDt = new DateTime(timestamp.getTime())
    .withZoneRetainFields(DateTimeZone.UTC)
    .withZone(DateTimeZone.getDefault());

2014-12-31T19:00:00.000-05:00

分解:タイムスタンプに対応するDateTimeを提供し、UTCであることを指定します。

new DateTime(timestamp.getTime())
    .withZoneRetainFields(DateTimeZone.UTC)

2015-01-01T00:00:00.000Z

これにより、DateTimeが得られますが、時刻は現地時間に変換されます。

new DateTime(timestamp.getTime())
    .withZoneRetainFields(DateTimeZone.UTC)
    .withZone(DateTimeZone.getDefault());

2014-12-31T19:00:00.000-05:00

12
StvnBrkdll

以下にその方法を示します。

private DateTime convertLocalToUTC(DateTime eventDateTime) {

        // get your local timezone
        DateTimeZone localTZ = DateTimeZone.getDefault();

        // convert the input local datetime to utc  
        long eventMillsInUTCTimeZone = localTZ.convertLocalToUTC(eventDateTime.getMillis(), false);

        DateTime evenDateTimeInUTCTimeZone = new DateTime(eventMillsInUTCTimeZone);

        return evenDateTimeInUTCTimeZone.toDate();
}
2
Robert

与えられた答えのどれも実際に問題を説明していませんでした。本当の問題は、最初の仮定が間違っていたことです。データベースからのタイムスタンプは、UTCではなくローカルJVMタイムゾーン_Asia/Kolkata_を使用して作成されました。これはJDBCのデフォルトの動作であるため、JVMタイムゾーンをUTCに設定することをお勧めします。

データベースからのタイムスタンプが実際にあった場合:

_2013-09-25 11:27:34 AM UTC
_

またはISO-8601形式:

_2013-09-25T11:27:34Z // The trailing 'Z' means UTC
_

次に、new DateTime(timestamp, DateTimeZone.UTC)コンストラクターを使用すると正常に機能します。自分で見て:

_Timestamp timestamp = new Timestamp(1380108454000L);
DateTime dt = new DateTime(timestamp.getTime(), DateTimeZone.UTC);
System.out.println(dt); // => 2013-09-25T11:27:34.000Z
_

_1380108454000L_がどのように得られたのか疑問に思っている場合は、単にJoda解析クラスを使用しました。

_ISODateTimeFormat.dateTimeParser().parseMillis("2013-09-25T11:27:34Z")
_

または、日付、時刻、およびタイムゾーンを入力できるオンラインWebサイトがあり、ミリ秒単位でエポック値を返します(逆も同様)。健全性チェックとしても良い場合があります。

_// https://www.epochconverter.com
Input: 1380108454000  Click: "Timestamp to Human Date"
Assuming that this timestamp is in milliseconds:
GMT: Wednesday, September 25, 2013 11:27:34 AM
_

また、_Java.sql.Timestamp_クラスは、Joda/Java 8+ Instantクラスと大まかに相関していることに留意してください。以前にこのようなバグを見つけるために、同等のクラス間で変換する方が簡単な場合があります。

1
nogridbag

同じ問題がありました。この一連の有用な回答を読んで、特定のニーズと使用可能なオブジェクトを考えて、別のDateTimeコンストラクターを使用して解決しました。

new DateTime("2012-04-23T18:25:46.511Z", DateTimeZone.UTC)
1
Ben Weaver

また、私にとって非常に役立つ別のアプローチがあります。ワークフロースレッドを一時的に特定のタイムゾーンに変更して(時間を節約する)、コードが終了したら、元のタイムゾーンを再度設定しました。 jodaライブラリを使用している場合、次のことを行うことがわかります。

TimeZone.setDefault(TimeZone.getTimeZone(myTempTimeZone));
TimeZone.setDefault(timeZone);

足りません。また、DateTimeZoneのTimeZoneを次のように変更する必要があります。

@Before
public void setUp() throws Exception {
    timeZone = TimeZone.getDefault();
    dateTimeZone = DateTimeZone.getDefault();
}

@After
public void tearDown() throws Exception {
    TimeZone.setDefault(timeZone);
    DateTimeZone.setDefault(dateTimeZone);
}

@Test
public void myTest() throws Exception {
    TimeZone.setDefault(TimeZone.getTimeZone(myTempTimeZone));
    DateTimeZone.setDefault(DateTimeZone.forID(myTempTimeZone));
    //TODO
    // my code with an specific timezone conserving time
}

それが他の誰かにも役立つことを願っています。

0
leonardo derks