web-dev-qa-db-fra.com

JodaTime - Comment obtenir l'heure actuelle en UTC

Je veux obtenir l'heure actuelle en UTC. Ce que je fais jusqu’à présent est la suivante (uniquement à des fins de test):

    DateTime dt = new DateTime();
    DateTimeZone tz = DateTimeZone.getDefault();
    LocalDateTime nowLocal = new LocalDateTime();
    DateTime nowUTC = nowLocal.toDateTime(DateTimeZone.UTC);

    Date d1 = nowLocal.toDate();
    Date d2 = nowUTC.toDate();

    L.d("tz: " + tz.toString());
    L.d("local: " + d1.toString());
    L.d("utc: " + d2.toString());
  • d1 est mon heure locale, c'est bon
  • d2 est mon heure locale + 1, mais devrait être l'heure locale - 1 ...

Mon fuseau horaire local est UTC + 1 (selon la sortie de débogage et la liste ici: https://www.joda.org/joda-time/timezones.html ) ...

Comment convertir correctement d'un fuseau horaire à un autre (y compris la représentation en millisecondes)?

MODIFIER

J'ai besoin de la date/millisecondes ... Il ne s'agit pas d'afficher l'heure correctement ....

EDIT 2

Maintenant, avec l'aide d'un commentaire et d'une réponse, j'ai essayé de suivre:

    DateTimeZone tz = DateTimeZone.getDefault();
    DateTime nowLocal = new DateTime();
    LocalDateTime nowUTC = nowLocal.withZone(DateTimeZone.UTC).toLocalDateTime();
    DateTime nowUTC2 = nowLocal.withZone(DateTimeZone.UTC);

    Date dLocal = nowLocal.toDate();
    Date dUTC = nowUTC.toDate();
    Date dUTC2 = nowUTC2.toDate();

    L.d(Temp.class, "------------------------");
    L.d(Temp.class, "tz    : " + tz.toString());
    L.d(Temp.class, "local : " + nowLocal +     " | " + dLocal.toString());
    L.d(Temp.class, "utc   : " + nowUTC +       " | " + dUTC.toString()); // <= WORKING SOLUTION
    L.d(Temp.class, "utc2  : " + nowUTC2 +      " | " + dUTC2.toString());

SORTIE

tz    : Europe/Belgrade
local : 2015-01-02T15:31:38.241+01:00 | Fri Jan 02 15:31:38 MEZ 2015
utc   : 2015-01-02T14:31:38.241 | Fri Jan 02 14:31:38 MEZ 2015
utc2  : 2015-01-02T14:31:38.241Z | Fri Jan 02 15:31:38 MEZ 2015

Ce que je voulais, c’est que la date locale affiche 15 heures et que la date précise affiche 14 heures .... Pour l’instant, cela semble fonctionner ...

----- EDIT3 - Solution finale -----

J'espère que c'est une bonne solution ... Je pense que je respecte tous les conseils que j'ai reçus ...

    DateTimeZone tz = DateTimeZone.getDefault();
    DateTime nowUTC = new DateTime(DateTimeZone.UTC);
    DateTime nowLocal = nowUTC.withZone(tz);

    // This will generate DIFFERENT Dates!!! As I want it!
    Date dLocal = nowLocal.toLocalDateTime().toDate();
    Date dUTC = nowUTC.toLocalDateTime().toDate();

    L.d("tz    : " + tz.toString());
    L.d("local : " + nowLocal +     " | " + dLocal.toString());
    L.d("utc   : " + nowUTC +       " | " + dUTC.toString());

Sortie:

tz    : Europe/Belgrade
local : 2015-01-03T21:15:35.170+01:00 | Sat Jan 03 21:15:35 MEZ 2015
utc   : 2015-01-03T20:15:35.170Z | Sat Jan 03 20:15:35 MEZ 2015
22
prom85

Vous rendez la tâche beaucoup plus compliquée que nécessaire:

DateTime dt = new DateTime(DateTimeZone.UTC);

Pas besoin de conversion. Si vous constatez que vous avez réellement besoin de convertir, vous pouvez utiliser withZone . Je vous suggérerais toutefois d'éviter de passer par LocalDateTime, car vous risqueriez ainsi de perdre des informations en raison des transitions de fuseaux horaires (deux instants différents peuvent avoir la même heure locale dans le même fuseau horaire, car les horloges remontent et se répètent. heure locale.

Cela dit, pour des raisons de testabilité, j’aime personnellement utiliser une interface Clock qui me permet d’obtenir l’heure actuelle (par exemple, en tant que Instant). Vous pouvez ensuite utiliser l'injection de dépendance pour injecter une horloge système réelle lors de l'exécution en production, ainsi qu'une fausse horloge avec une durée prédéfinie pour les tests. Le paquet Java.time de Java 8 intègre cette idée, btw.

67
Jon Skeet

Vous pouvez également utiliser la méthode statique now , ce qui la rend encore plus lisible.

DateTime.now(DateTimeZone.UTC)
9
Kobynet

Utilisez ceci 

DateTime.now().withZone(DateTimeZone.UTC)

et si vous voulez formater, vous pouvez utiliser

DateTime.now().withZone(DateTimeZone.UTC).toString("yyyyMMddHHmmss")
6
Naidu

S'il vous plaît essayez d'écouter Jon Skeets de bons conseils et commentaires. Voici une explication supplémentaire. Votre edit-2 contient une erreur:

DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowLocal = new DateTime();
LocalDateTime nowUTC = nowLocal.withZone(DateTimeZone.UTC).toLocalDateTime();
DateTime nowUTC2 = nowLocal.withZone(DateTimeZone.UTC);

Date dLocal = nowLocal.toDate();
Date dUTC = nowUTC.toDate();
Date dUTC2 = nowUTC2.toDate();

Si vous appelez toDate() sur un objet nowUTC de type LocalDateTime, vous pouvez avoir des surprises - voir javadoc . Joda-Time prétend utiliser the same fields dans Java.util.Date comme dans nowUTC. Qu'est-ce que ça veut dire? Analysons:

nowUTC.toString() produit 2015-01-02T14:31:38.241 C'est-à-dire sans fuseau horaire (notez le Z manquant à la fin), il s'agit donc simplement d'un horodatage local. Par contexte, nous savons que cela a été généré en UTC. Toutefois, à l'étape suivante, vous le convertissez en un Java.util.Date en utilisant la méthode susmentionnée. Cette méthode combine l’horodatage local et le fuseau horaire du système (Belgrade). CONSERVATION DES CHAMPS, MODIFICATION de l’instant. Donc, vous avez finalement mal corrigé votre instant. Et votre deuxième ligne est fausse.

Si vous voulez juste 

date d'affichage utc 14 heures

dans ce cas, n’utilisez pas la méthode de conversion discutable et trompeuse proposée par Joda-Time. Utilisez à la place un formateur dédié avec le motif "EEE MMM jj HH: mm: ss zzz yyyy" ou similaire (Joda-Time propose DateTimeFormatter). Définissez le décalage UTC sur ce formateur et imprimez-le. Terminé. Abandonnez complètement tout appel de Java.util.Date.toString(). De cette façon, vous n'avez même pas besoin de faire de conversion dangereuse du tout.

2
Meno Hochschild

De là: http://www.joda.org/joda-time/userguide.html#Changing_TimeZone

// get current moment in default time zone
DateTime dt = new DateTime();
// translate to London local time
DateTime dtLondon = dt.withZone(DateTimeZone.forID("Europe/London"));

La valeur résultante dtLondon a la même durée absolue en millisecondes, mais un ensemble différent de valeurs de champ.

Vous pouvez remplacer «Europe/London» par le fuseau horaire de votre choix (UTC). Voir cette liste de noms de fuseaux horaires appropriés .

2
Greg Kopff
    SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
    // or SimpleDateFormat sdf = new SimpleDateFormat( "MM/dd/yyyy KK:mm:ss a Z" );
    sdf.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
    System.out.println( sdf.format( new Date() ) 

);

Au lieu de System.out.println (sdf.format (new Date ())), mettez votre date locale

0
SW DEV07

J'ai corrigé cela avec ce convertisseur

public class DateTimeConverter implements AttributeConverter<DateTime, Date> {
    @Override
    public Date convertToDatabaseColumn(DateTime attribute) {
        return attribute == null ? null
                : new Date(attribute
                        .withZone(DateTimeZone.UTC)
                        .withZoneRetainFields(DateTimeZone.getDefault())
                        .getMillis());
    }

    @Override
    public DateTime convertToEntityAttribute(Date dbData) {
        return dbData == null ? null
               : new DateTime(dbData.getTime())
                        .withZoneRetainFields(DateTimeZone.UTC)
                        .withZone(DateTimeZone.getDefault());
    }
}

Les dates sont stockées au format UTC et récupérées avec votre fuseau horaire actuel.

0
Wicowyn