webentwicklung-frage-antwort-db.com.de

Konvertieren Sie Java-Datum in UTC-Zeichenfolge

Die Methode Java.util.DatetoString() zeigt das Datum in der lokalen Zeitzone an. 

Es gibt mehrere allgemeine Szenarien, in denen die Daten in UTC gedruckt werden sollen, einschließlich Protokolle, Datenexport und Kommunikation mit externen Programmen.

  • Wie kann ich am besten eine String-Darstellung von Java.util.Date in UTC erstellen?
  • Wie kann das toString()-Format von j.u.Date, das nicht sortierbar ist (Danke, @JonSkeet!) Durch ein besseres Format ersetzt werden?

Nachtrag

Ich denke, dass die Standardmethode, das Datum in einem benutzerdefinierten Format und in einer Zeitzone zu drucken, ziemlich langwierig ist:

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));

Ich suchte nach einem One-Liner wie:

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

Nach den nützlichen Anmerkungen habe ich den Datumsformatierer komplett neu aufgebaut. Die Nutzung soll:

  • Kurz sein (ein Liner)
  • Stellen Sie Einwegobjekte (Zeitzone, Format) als Strings dar
  • Unterstützt nützliche, sortierbare ISO-Formate und das Legacy-Format aus der Box

Wenn Sie diesen Code für nützlich halten, kann ich den Quellcode und eine JAR-Datei in github veröffentlichen.

Verwendungszweck

// 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

(Dieser Code ist auch Gegenstand von einer Frage zu 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

In Java 8 und höher ist das neue Java.time-Paket eingebaut ( Tutorial ). Inspiriert von Joda-Time, definiert durch JSR 310 und erweitert um das ThreeTen-Extra -Projekt.

Die beste Lösung ist, sortiere Datums-/Zeitobjekte statt Zeichenfolgen. Aber wenn Sie in Strings arbeiten müssen, lesen Sie weiter.

Ein Instant repräsentiert einen Moment auf der Timeline, im Wesentlichen in UTC (genaue Angaben finden Sie in der Klasse doc). Die Implementierung von toString verwendet standardmäßig das Format DateTimeFormatter.ISO_INSTANT . Dieses Format enthält null, drei, sechs oder neun Ziffern, um einen Sekundenbruchteil bis zu einer Genauigkeit von Nanosekunden anzuzeigen. 

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

Wenn Sie mit der alten Date-Klasse interoperieren müssen, konvertieren Sie nach/from Java.time über neue Methoden, die den alten Klassen hinzugefügt wurden. Beispiel: Date::toInstant.

myJavaUtilDate.toInstant().toString()

Möglicherweise möchten Sie ein alternatives Formatierungsprogramm verwenden, wenn Sie eine konstante Anzahl von Stellen in Sekundenbruchteilen oder keine Sekundenbruchteile benötigen.

Wenn Sie Bruchteile einer Sekunde abschneiden möchten, verwenden Sie ZonedDateTime anstelle von Instant und rufen die Methode Methode zum Ändern des Bruchs auf Null auf. 

Beachten Sie, dass wir für ZonedDateTime eine Zeitzone angeben müssen (also den Namen). In unserem Fall bedeutet das UTC. Die Unterklasse von ZoneID , ZoneOffset enthält eine praktische Konstante für UTC . Wenn Sie die Zeitzone weglassen, wird implizit die aktuelle Standardzeitzone der JVM angewendet.

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

Joda-Zeit

UPDATE: Das Joda-Time-Projekt befindet sich jetzt im Wartungsmodus. Das Team empfiehlt die Migration zu den Java.time-Klassen. 

Ich suchte nach einem Einzeiler

Einfach, wenn Sie die Bibliothek Joda-Time 2.3 verwenden. ISO 8601 ist die Standardformatierung.

Zeitzone

Beachten Sie im folgenden Codebeispiel, dass ich eine Zeitzone und nicht von der Standardzeitzone abhängig mache. In diesem Fall spezifiziere ich UTC für Ihre Frage. Die Variable Z am Ende, die als "Zulu" gesprochen wird, bedeutet keinen Zeitzonenversatz von UTC.

Beispielcode

// import org.joda.time.*;

String output = new DateTime( DateTimeZone.UTC );

Ausgabe…

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

Der folgende vereinfachte Code, basierend auf der oben akzeptierten Antwort , hat für mich funktioniert:

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();
    }
}

Ich hoffe das hilft jemandem.

6
Vikram

Java.time.stant

Verwenden Sie einfach Instant von Java.time.

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

Dies wurde gerade gedruckt:

2018-01-27T09:35:23.179612Z

Instant.toString gibt immer UTC-Zeit an.

Die Ausgabe ist normalerweise sortierbar, es gibt jedoch unglückliche Ausnahmen. toString gibt Ihnen genug Gruppen von drei Dezimalstellen, um die Genauigkeit zu rendern, die sie hat. Auf dem Java 9 auf meinem Mac scheint die Genauigkeit von Instant.now() Mikrosekunden zu sein, aber wir sollten davon ausgehen, dass in etwa einem von tausend Fällen eine ganze Anzahl von Millisekunden erreicht wird und nur drei Dezimalstellen ausgegeben werden. Zeichenfolgen mit einer ungleichen Anzahl von Dezimalzahlen werden in der falschen Reihenfolge sortiert (es sei denn, Sie schreiben einen benutzerdefinierten Vergleicher, um dies zu berücksichtigen).

Instant ist eine der Klassen in Java.time, der modernen Java-API für Datum und Uhrzeit, die ich wärmstens empfehle, anstatt der veralteten Date-Klasse. Java.time ist in Java 8 und höher integriert und wurde auch nach Java 6 und 7 zurückportiert.

2
Ole V.V.

Wenn XStream eine Abhängigkeit ist, versuchen Sie Folgendes:

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

Warum nicht einfach Java.text.SimpleDateFormat verwenden?

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

Oder siehe: http://www.tutorialspoint.com/Java/java_date_time.htm

0
Will

Wenn Sie nur Java.util.Date verwenden möchten, können Sie hier einen kleinen Trick verwenden:

String dateString = Long.toString (Date.UTC (date.getYear (), date.getMonth (), date.getDate (), date.getHours (), date.getMinutes (), date.getSeconds ()));

0
Gaurav Arora