Convertir la date Java en chaîne UTC

Le java.util.Date toString() méthode affiche la date dans le fuseau horaire local.

Il existe plusieurs scénarios courants où nous voulons que les données soient imprimées dans UTC , y compris les journaux, l'exportation de données et la communication avec des programmes externes.

  • Quelle est la meilleure façon de créer une représentation de chaîne de java.util.Date en UTC?
  • Comment remplacer le format toString() de la date J. U., qui n'est pas triable (merci, @JonSkeet!) avec une meilleure format?

Additif

Je pense que la manière standard d'Imprimer la date dans un format personnalisé et un fuseau horaire est assez fastidieuse:

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

, je cherchais un one-liner comme:

System.out.println(prettyPrint(date, "yyyy-MM-dd'T'HH:mm:ss.SSS zzz", "UTC"));
26
demandé sur Basil Bourque 2012-07-02 17:05:52

7 réponses

Java.temps

Dans Java 8 et plus tard, nous avons le nouveau java.temps paquet construit dans (tutoriel ). Inspiré par Joda-Time, défini par JSR 310, et étendu par le projetThreeTen-Extra .

La meilleure solution est de trier vos objets date-heure plutôt que des chaînes. Mais si vous devez travailler dans des chaînes, lisez la suite.

Un Instant représente un moment sur le montage, en gros, en UTC (voir classe de doc précise détail). L'toString la mise en œuvre utilise le DateTimeFormatter.ISO_INSTANT le format par défaut. Ce format comprend zéro, trois, six ou neuf chiffres chiffres nécessaires pour afficher une fraction de seconde jusqu'à nanoseconde Précision.

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

Si vous devez interopérer avec l'ancienne classe Date, convertissez vers / depuis java.le temps moyen de nouvelles méthodes ajoutées aux anciennes classes. Exemple: Date::toInstant.

myJavaUtilDate.toInstant().toString()

Vous pouvez utiliser un autre formateur si vous avez besoin d'un nombre cohérent de chiffres dans la seconde fractionnaire ou si vous n'avez pas besoin de seconde fractionnaire.

Une autre route si vous voulez tronquer des fractions de seconde consiste à utiliser ZonedDateTime au lieu de Instant, en appelant sa méthode pour changer la fraction à zéro.

Notez qu'il faut spécifier un fuseau horaire pour ZonedDateTime (donc le nom). Dans notre cas, cela signifie que l'heure UTC. La sous-classe de ZoneID, ZoneOffset, titulaire d'une pratique constante pour l'UTC. Si nous omettons le fuseau horaire, le courant de la JVM fuseau horaire par défaut est implicitement appliqué.

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

Joda-Time

UPDATE: le projet Joda-Time est maintenant en mode maintenance, l'équipe conseillant la migration vers java.les classes de temps.

, je cherchais un one-liner

Facile si vous utilisez la bibliothèqueJoda-Time 2.3. ISO 8601 {[20] } est la mise en forme par défaut.

Fuseau Horaire

Dans l'exemple de code ci-dessous, notez que je spécifie une heure zone plutôt que selon le fuseau horaire par défaut. Dans ce cas, je spécifie UTC par votre question. Le Z à la fin, parlé comme "Zoulou", signifie aucun décalage de fuseau horaire par rapport à UTC.

Exemple De Code

// import org.joda.time.*;

String output = new DateTime( DateTimeZone.UTC );

Sortie...

2013-12-12T18:29:50.588Z
24
répondu Basil Bourque 2018-01-28 18:24:20

Suite aux commentaires utiles, j'ai complètement reconstruit le formateur de date. L'utilisation est supposée:

  • être court (une doublure)
  • représente les objets jetables (fuseau horaire, format) sous forme de Chaînes
  • prend en charge les formats ISO utiles et triables et le format hérité de la boîte

Si vous considérez ce code utile, je peux publier la source et un JAR dans github.

Utilisation

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

(Ce code est également l'objet de un question sur la révision du code 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 <adam@matan.name>
 * @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
répondu Adam Matan 2017-04-13 12:40:37

Le code simplifié suivant, basé sur la réponse acceptée ci-dessus , a fonctionné pour moi:

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

J'espère que cela aide quelqu'un.

6
répondu Vikram 2017-05-23 11:47:08

Java.temps.Instantanée

Suffit d'utiliser Instant de java.time.

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

Ceci vient d'être imprimé:

2018-01-27T09:35:23.179612Z

Instant.toString donne toujours l'heure UTC.

La sortie est généralement triable, mais il y a des exceptions malheureuses. toString vous donne suffisamment de groupes de trois décimales pour rendre la précision qu'il détient. Sur le Java 9 sur mon Mac, la précision de Instant.now() semble être microsecondes, mais nous devrions nous attendre à ce que dans environ un cas sur mille, il frappera un nombre entier de millisecondes et imprimer seulement trois décimales. Les chaînes avec un nombre inégal de décimales seront triées dans le mauvais ordre (sauf si vous écrivez un comparateur personnalisé pour en tenir compte).

Instant est l'une des classes de java.time, L'API Java date et heure moderne, que je vous recommande chaleureusement d'utiliser à la place de la classe Date obsolète. java.time est intégré à Java 8 et versions ultérieures et a également été rétroporté à Java 6 et 7.

2
répondu Ole V.V. 2018-01-28 06:10:36

Si XStream est une dépendance, essayez:

new com.thoughtworks.xstream.converters.basic.DateConverter().toString(date)
1
répondu Jesse Glick 2013-05-22 01:32:51

Pourquoi ne pas simplement utiliser java.texte.SimpleDateFormat ?

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

Ou voir: http://www.tutorialspoint.com/java/java_date_time.htm

0
répondu Will 2013-11-19 14:33:17

Eh Bien, si vous voulez utiliser java.util.Date seulement, voici une petite astuce que vous pouvez utiliser:

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

0
répondu Gaurav Arora 2017-01-09 11:20:57