web-dev-qa-db-ja.com

変換Java DateからUTC文字列

Java.util.DatetoString()メソッドは、ローカルタイムゾーンの日付を表示します。

ログ、データエクスポート、外部プログラムとの通信など、データを [〜#〜] utc [〜#〜] で出力する一般的なシナリオがいくつかあります。

  • UTCで_Java.util.Date_の文字列表現を作成する最良の方法は何ですか?
  • J.u.DateのtoString()形式を、ソートできない(@JonSkeet!)より良い形式に置き換える方法は?

補遺

カスタム形式とタイムゾーンで日付を印刷する標準的な方法は非常に面倒だと思います。

_final Date date = new Date();
final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS zzz";
final SimpleDateFormat sdf = new SimpleDateFormat(ISO_FORMAT);
final TimeZone utc = TimeZone.getTimeZone("UTC");
sdf.setTimeZone(utc);
System.out.println(sdf.format(date));
_

私は次のようなワンライナーを探していました:

_System.out.println(prettyPrint(date, "yyyy-MM-dd'T'HH:mm:ss.SSS zzz", "UTC"));
_
28
Adam Matan

有用なコメントに続いて、日付フォーマッターを完全に再構築しました。使用法は次のとおりです。

  • 短くする(ライナー1つ)
  • 使い捨てオブジェクト(タイムゾーン、形式)を文字列として表す
  • 便利でソート可能なISO形式と、ボックスからのレガシー形式をサポート

このコードが便利だと思われる場合は、githubでソースとJARを公開できます。

使用法

// The problem - not UTC
Date.toString()                      
"Tue Jul 03 14:54:24 IDT 2012"

// ISO format, now
PrettyDate.now()        
"2012-07-03T11:54:24.256 UTC"

// ISO format, specific date
PrettyDate.toString(new Date())         
"2012-07-03T11:54:24.256 UTC"

// Legacy format, specific date
PrettyDate.toLegacyString(new Date())   
"Tue Jul 03 11:54:24 UTC 2012"

// ISO, specific date and time zone
PrettyDate.toString(moonLandingDate, "yyyy-MM-dd hh:mm:ss zzz", "CST") 
"1969-07-20 03:17:40 CDT"

// Specific format and date
PrettyDate.toString(moonLandingDate, "yyyy-MM-dd")
"1969-07-20"

// ISO, specific date
PrettyDate.toString(moonLandingDate)
"1969-07-20T20:17:40.234 UTC"

// Legacy, specific date
PrettyDate.toLegacyString(moonLandingDate)
"Wed Jul 20 08:17:40 UTC 1969"

コード

(このコードは Code Review stackexchangeに関する質問の主題でもあります

import Java.text.SimpleDateFormat;
import Java.util.Date;
import Java.util.TimeZone;

/**
 * Formats dates to sortable UTC strings in compliance with ISO-8601.
 * 
 * @author Adam Matan <[email protected]>
 * @see http://stackoverflow.com/questions/11294307/convert-Java-date-to-utc-string/11294308
 */
public class PrettyDate {
    public static String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS zzz";
    public static String LEGACY_FORMAT = "EEE MMM dd hh:mm:ss zzz yyyy";
    private static final TimeZone utc = TimeZone.getTimeZone("UTC");
    private static final SimpleDateFormat legacyFormatter = new SimpleDateFormat(LEGACY_FORMAT);
    private static final SimpleDateFormat isoFormatter = new SimpleDateFormat(ISO_FORMAT);
    static {
        legacyFormatter.setTimeZone(utc);
        isoFormatter.setTimeZone(utc);
    }

    /**
     * Formats the current time in a sortable ISO-8601 UTC format.
     * 
     * @return Current time in ISO-8601 format, e.g. :
     *         "2012-07-03T07:59:09.206 UTC"
     */
    public static String now() {
        return PrettyDate.toString(new Date());
    }

    /**
     * Formats a given date in a sortable ISO-8601 UTC format.
     * 
     * <pre>
     * <code>
     * final Calendar moonLandingCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
     * moonLandingCalendar.set(1969, 7, 20, 20, 18, 0);
     * final Date moonLandingDate = moonLandingCalendar.getTime();
     * System.out.println("UTCDate.toString moon:       " + PrettyDate.toString(moonLandingDate));
     * >>> UTCDate.toString moon:       1969-08-20T20:18:00.209 UTC
     * </code>
     * </pre>
     * 
     * @param date
     *            Valid Date object.
     * @return The given date in ISO-8601 format.
     * 
     */

    public static String toString(final Date date) {
        return isoFormatter.format(date);
    }

    /**
     * Formats a given date in the standard Java Date.toString(), using UTC
     * instead of locale time zone.
     * 
     * <pre>
     * <code>
     * System.out.println(UTCDate.toLegacyString(new Date()));
     * >>> "Tue Jul 03 07:33:57 UTC 2012"
     * </code>
     * </pre>
     * 
     * @param date
     *            Valid Date object.
     * @return The given date in Legacy Date.toString() format, e.g.
     *         "Tue Jul 03 09:34:17 IDT 2012"
     */
    public static String toLegacyString(final Date date) {
        return legacyFormatter.format(date);
    }

    /**
     * Formats a date in any given format at UTC.
     * 
     * <pre>
     * <code>
     * final Calendar moonLandingCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
     * moonLandingCalendar.set(1969, 7, 20, 20, 17, 40);
     * final Date moonLandingDate = moonLandingCalendar.getTime();
     * PrettyDate.toString(moonLandingDate, "yyyy-MM-dd")
     * >>> "1969-08-20"
     * </code>
     * </pre>
     * 
     * 
     * @param date
     *            Valid Date object.
     * @param format
     *            String representation of the format, e.g. "yyyy-MM-dd"
     * @return The given date formatted in the given format.
     */
    public static String toString(final Date date, final String format) {
        return toString(date, format, "UTC");
    }

    /**
     * Formats a date at any given format String, at any given Timezone String.
     * 
     * 
     * @param date
     *            Valid Date object
     * @param format
     *            String representation of the format, e.g. "yyyy-MM-dd HH:mm"
     * @param timezone
     *            String representation of the time zone, e.g. "CST"
     * @return The formatted date in the given time zone.
     */
    public static String toString(final Date date, final String format, final String timezone) {
        final TimeZone tz = TimeZone.getTimeZone(timezone);
        final SimpleDateFormat formatter = new SimpleDateFormat(format);
        formatter.setTimeZone(tz);
        return formatter.format(date);
    }
}
14
Adam Matan

Java.time

Java 8以降では、新しい Java.timeパッケージ が組み込まれています( Tutorial )。Joda-Timeに触発され、 JSR 310、および ThreeTen-Extra プロジェクトによって拡張されました。

最良の解決策は、文字列ではなく日時オブジェクトをソートすることです。しかし、文字列で作業する必要がある場合は、読み進めてください。

Instant は、基本的に [〜#〜] utc [〜#〜] のタイムライン上の瞬間を表します(正確な詳細については、クラスのドキュメントを参照してください)。 toString 実装では DateTimeFormatter.ISO_INSTANT デフォルトでフォーマット。このフォーマットには、必要に応じてゼロ、3、6、または9桁の数字が含まれ、秒の小数部を ナノ秒 精度で表示します。

String output = Instant.now().toString(); // Example: '2015-12-03T10:15:30.120Z'

古いDateクラスと相互運用する必要がある場合は、古いクラスに追加された新しいメソッドを介してJava.timeとの間で変換します。例:Date::toInstant

myJavaUtilDate.toInstant().toString()

小数秒で一貫した桁数が必要な場合、または小数秒が必要ない場合は、代替フォーマッタを使用することができます。

秒の端数を切り捨てる場合の別のルートは、ZonedDateTimeの代わりにInstantを使用し、その 端数をゼロに変更するメソッド を呼び出すことです。

ZonedDateTime(したがって名前)のタイムゾーンを指定する必要があることに注意してください。この場合、UTCを意味します。 ZoneIDZoneOffset のサブクラスは、便利な TCの定数 を保持します。タイムゾーンを省略すると、JVMの 現在のデフォルトタイムゾーン が暗黙的に適用されます。

String output = ZonedDateTime.now( ZoneOffset.UTC ).withNano( 0 ).toString();  // Example: 2015-08-27T19:28:58Z

ジョーダタイム

UPDATE:Joda -Timeプロジェクトは、Java.timeクラスへの移行を推奨するチームとともに、メンテナンスモードになりました。

ワンライナーを探していました

Joda-Time 2.3ライブラリを使用すると簡単です。 ISO 8601 がデフォルトのフォーマットです。

タイムゾーン

次のコード例では、デフォルトのタイムゾーンに依存するのではなく、タイムゾーンを指定していることに注意してください。この場合、質問ごとに [〜#〜] utc [〜#〜] を指定しています。末尾のZは「Zulu」と呼ばれ、UTCからのタイムゾーンオフセットがないことを意味します。

サンプルコード

// import org.joda.time.*;

String output = new DateTime( DateTimeZone.UTC );

出力…

2013-12-12T18:29:50.588Z
27
Basil Bourque

上記の受け入れられた答え に基づいた次の単純化されたコードは、私のために働いた:

public class GetSync {
    public static String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS zzz";
    private static final TimeZone utc = TimeZone.getTimeZone("UTC");
    private static final SimpleDateFormat isoFormatter = new SimpleDateFormat(ISO_FORMAT);
    static {
        isoFormatter.setTimeZone(utc);
    }

    public static String now() {
        return isoFormatter.format(new Date()).toString();
    }
}

これが誰かの助けになることを願っています。

6
Vikram

Java.time.Instant

Instant of _Java.time_を使用するだけです。

_    System.out.println(Instant.now());
_

これはちょうど印刷されました:

_2018-01-27T09:35:23.179612Z
_

_Instant.toString_は常にUTC時間を提供します。

出力は通常はソート可能ですが、残念な例外があります。 toStringは、保持する精度をレンダリングするのに十分な3つの小数のグループを提供します。私のMacのJava 9では、Instant.now()の精度はマイクロ秒のようです。小数点以下の桁数が等しくない文字列は、間違った順序でソートされます(これを考慮するカスタムコンパレーターを作成しない限り)。

Instantは_Java.time_のクラスの1つであり、最新のJava日付と時刻のAPIです。古いDateの代わりに使用することをお勧めしますクラス。_Java.time_はJava 8以降に組み込まれており、Java 6および7にバックポートされています。

2
Ole V.V.

XStreamが依存関係の場合は、次を試してください。

new com.thoughtworks.xstream.converters.basic.DateConverter().toString(date)
1
Jesse Glick

なぜJava.text.SimpleDateFormatを使用しないのですか?

Date someDate = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String s = df.format(someDate);

または、以下を参照してください http://www.tutorialspoint.com/Java/java_date_time.htm

0
Will

Java.util.Dateのみを使用する場合は、使用できる小さなトリックがあります。

文字列dateString = Long.toString(Date.UTC(date.getYear()、date.getMonth()、date.getDate()、date.getHours()、date.getMinutes()、date.getSeconds()));

0
Gaurav Arora