質問

一連のミリ秒を取る次のコード(RSSフィードからのものであるため、文字列になります。以下の例はクイックテストプログラムです)を持ち、それらのミリを日付オブジェクトに変換します。

public static void main(String[] args) {
    String ms = "1302805253";
    SimpleDateFormat dateFormatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(Long.parseLong(ms));

    try {
        String dateFormat = dateFormatter.format(calendar.getTime());
        System.out.println("Date Format = " + dateFormat);

        Date dateParse = dateFormatter.parse(dateFormatter.format(calendar.getTime()));
        System.out.println("Date Parse  = " + dateParse);
    } catch (ParseException e) {
        // TODO: handle exception
    }
}


Output:
    Date Format = Fri, 16 Jan 1970 02:53:25 GMT
    Date Parse  = Fri Jan 16 03:53:25 GMT 1970

ご覧のとおり、カレンダーオブジェクトのフォーマットと結果の文字列の解析の間に、1時間が失われています。また、出力のフォーマットが変更されました。なぜこれが起こっているのか、そしてそれを回避する方法について誰も私を助けることができますか?日付オブジェクトを「日付形式」出力と同じ形式にしたい。

役に立ちましたか?

解決

英国がそうしなかったので、それが起こっていると思います 実際に 1970年にGMTを使用すると、Javaはその周りにバグがあります... フォーマット 1970年の日付は、英国がGMTを使用しているかのようですが、実際にオフセットを変更することはありませんでした。簡単な例:

Date date = new Date(0);
SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy HH:mm:ss zzz");
sdf.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println(sdf.format(date));

結果:

01 Jan 1970 01:00:00 GMT

GMTの午前1時だと主張していることに注意してください...これは間違っています。これ だった ヨーロッパ/ロンドンの時間の午前1時ですが、ヨーロッパ/ロンドンはGMTを観察していませんでした。

ジョーダ時間 BSTを印刷するという点でこれを正しく理解してください - しかし、Jodaの時間は好きではありません 解析 タイムゾーンの略語を備えた値。ただし、タイムゾーンを使用することができます オフェット 代わりは:

import org.joda.time.*;
import org.joda.time.format.*;

public class Test {
    public static void main(String[] args) throws Exception {
        DateTime date = new DateTime(0, DateTimeZone.forID("Europe/London"));

        DateTimeFormatter formatter = DateTimeFormat.forPattern(
            "dd MMM yyyy HH:mm:ss Z");

        String text = formatter.print(date); // 01 Jan 1970 01:00:00 +0100
        System.out.println(text);

        DateTime parsed = formatter.parseDateTime(text);
        System.out.println(parsed.equals(date)); // true
    }
}

他のヒント

Jon Skeetによる回答 正しい。

Java.Time

Java.timeを通して同じ入力を実行して、結果を確認しましょう。

aを指定します 適切なタイムゾーン名. 。次のような3-4文字の略語を使用しないでください BST, EST, 、 また IST それらは真のタイムゾーンではなく、標準化されておらず、ユニークでさえありません(!)。だから私たちは使用します Europe/London.

Instant クラスは、タイムラインの瞬間を表します UTC の決議付き ナノ秒.

String input = "1302805253";
long millis = Long.parseLong ( input );
Instant instant = Instant.ofEpochMilli ( millis );

タイムゾーンを適用してaを生成します ZonedDateTime 物体。

ZoneId zoneId = ZoneId.of ( "Europe/London" );
ZonedDateTime zdt = instant.atZone ( zoneId );

コンソールにダンプします。確かにわかります Europe/London その瞬間、UTCの1時間先です。したがって、時刻はそうです 02 ではなく時間 01 時間。どちらもタイムライン上の同じ同時モーメントを表し、2つの異なるレンズを通して見たばかりです 壁2回.

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

入力:1302805253 |インスタント:1970-01-16T01:53:25.253Z | ZDT:1970-01-16T02:53:25.253+01:00 [ヨーロッパ/ロンドン

全体の秒

ちなみに、私はあなたの入力文字列が表すと思われます 全体 1970年のEPOCH以来の数秒ではなく、UTCではなく ミリ秒. 。数秒として2011年に日付を取得し、この質問が投稿されたと解釈しました。

String output = Instant.ofEpochSecond ( Long.parseLong ( "1302805253" ) ).atZone ( ZoneId.of ( "Europe/London" ) ).toString ();

2011-04-14T19:20:53+01:00 [ヨーロッパ/ロンドン

Java.timeについて

Java.Time フレームワークはJava 8以降に組み込まれています。これらのクラスは、古い厄介な日付クラスに取って代わります java.util.Date, .Calendar, & java.text.SimpleDateFormat.

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

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

Java.timeの機能の多くは、Java 6と7にバックポートされています Threeten-Backport さらに適応します アンドロイドThreetenabp.

Threeten-Extra プロジェクトは、追加のクラスでJava.Timeを延長します。このプロジェクトは、Java.timeに将来の追加の可能性の実証済みの基盤です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top