Horodatage UTC + Joda Time
J'essaie d'obtenir de l'UTC TimeStamp dans un programme Java simple à l'aide de Joda:
public Timestamp getCurrentUTC(LocalDateTime date, DateTimeZone srcTZ, DateTimeZone dstTZ, Locale l) {
DateTime srcDateTime = date.toDateTime(srcTZ);
DateTime dstDateTime = srcDateTime.toDateTime(dstTZ);
System.out.println("UTC Time:" + dstDateTime.getMillis());
System.out.println("UTC Time:" + new Timestamp(dstDateTime.getMillis()));
return new Timestamp(dstDateTime.getMillis());
}
La sortie du programme est comme suit:
UTC Time:1378265162047
UTC Time:2013-09-03 23:26:02.047
La valeur en millisecondes est la bonne heure UTC (c'est à dire confirmé avec GMT-4
fuseau horaire)
La deuxième valeur est la EST
fuseau horaire.
Ce dont j'ai besoin est la valeur UTC inchangée, comme java.sql.Timestamp
(c'est à dire TZ indépendant),
pour une base de données à écrire. Est-ce possible?
Edit 1
DateTime srcDateTime = date.toDateTime(srcTZ);
DateTime dstDateTime = srcDateTime.toDateTime(dstTZ);
System.out.println("UTC Time:" + dstDateTime.getMillis());
Je sais que srcDateTime
est la date locale (GMT-4), et dstDateTime
est
UTC (GMT-0). Les valeurs de sortie de l'dates sont les suivantes:
Source Date:2013-09-04T09:10:43.683-04:00
Destination Date: 2013-09-04T13:10:43.683Z
J'ai essayé toutes les combinaisons pour essayer d'obtenir la valeur UTC de dstDateTime
comme java.sql.TimeStamp:
System.out.println("UTC Time:" + dstDateTime.getMillis());
System.out.println("UTC Time:" + new Timestamp(srcDateTime.toDateTime(DateTimeZone.UTC).getMillis()));
System.out.println("UTC Time:" + new Timestamp(dstDateTime.toDateTime(DateTimeZone.UTC).getMillis()));
La sortie d'impression pour les essais de:
UTC Time:1378298760226 - Correct UTC
UTC Time:2013-09-04 08:46:00.226 - Incorrect Local Date Time instead of the Expected UTC
UTC Time:2013-09-04 08:46:00.226 - Incorrect Local Date Time instead of the Expected UTC
La première ligne d'impression est la bonne horodatage UTC. Tout ce que je besoin est que même valeur
type de java.sql.TimeStamp. De rien, j'ai essayé toujours renvoyées à la date locale en temps
de la machine.
Edit 2
J'ai essayé le suivant:
System.out.println("UTC Timestamp:" + date.toDateTime(srcTZ).getMillis());
System.out.println("UTC Timestamp:" + new Timestamp(date.toDateTime(srcTZ).getMillis()));
La sortie est comme suit:
UTC Time:1378342856315 - Correct UTC Time
UTC Timestap:2013-09-04 21:00:56.315 - Local Time other than the expected UTC Time
Chaque fois que j'essaie de convertir un TimeStamp, je lâche la validité de la valeur UTC que je suis après.
En termes des paramètres de la méthode:
srcTZ = DateTimeZone.forTimeZone(TimeZone.getTimeZone("America/Montreal")
dstTZ = DateTimeZone.forTimeZone(TimeZone.getTimeZone("Etc/UTC"))
Local l = new Locale("en", "CA")
Toute aide est grandement appréciée.
Nick.
Modifier 3
Bonjour Matt,
Je vous remercie beaucoup pour votre réponse. Nous obtenons les mêmes résultats que vous. Ne sais pas la chose à propos de l'impression, etc.., Plus précisément:
System.out.println("UTC Timestamp:" + srcDateTime.toDateTime(dstTZ).getMillis());
System.out.println("UTC Timestamp:" + srcDateTime.toDateTime(dstTZ));
System.out.println("UTC Timestamp:" + new Timestamp(srcDateTime.toDateTime(dstTZ).getMillis()));
Les Rendements De La Sortie:
UTC Timestamp:1378389098468 - Correct UTC Timestap (Thu, 05 Sep 2013 13:51:38 GMT)
UTC Timestamp:2013-09-05T13:51:38.468Z - Correct UTC Time
UTC Timestamp:2013-09-05 09:51:38.468 - Local time is printed, UTC is expected
Le problème a été porté à mon attention lorsque nous avons réalisé que la DB est le stockage de l'heure locale au lieu de l'UTC:
+---------------------+
| effectivedate |
+---------------------+
| 2013-09-05 09:34:11 |
+---------------------+
Mysql fuseau horaire est réglé sur '-00:00'
mysql> SELECT CURRENT_TIMESTAMP;
+---------------------+
| CURRENT_TIMESTAMP |
+---------------------+
| 2013-09-05 13:48:09 |
+---------------------+
Débogage de l'application à l'aide d'eclipse débogueur nous nous sommes rendu compte que la date locale en temps (2013-09-05 09:51:38.468) a été passé à la DB (ne Peut pas afficher les images, pas assez de points...). Le type de données est directement à l'Horodateur, sans manipulation de chaîne. Peut-être que le débogueur eclipse est à l'aide de String.println()
fonction, pas sûr..
J'ai vraiment apprécié toute l'aide au débogage de notre application. Ne veulent pas prendre beaucoup de temps (sans jeu de mot) et de l'effort...
Salutations,
Nick.
- "La valeur en millisecondes est la bonne heure UTC (ie GMT-4)" Cette déclaration ne fait pas de sens pour moi. N'est-ce pas l'heure UTC toujours GMT-0?
- cette réponse pourrait aider
- Bonjour cravate, désolé, j'ai corrigé le travail. Je voulais calculer locale, de l'TZ GMT-4. Je suis en train d'essayer d'obtenir GMT-0 comme d'Horodatage. RC, toString ne fonctionnera pas. Nous en avons besoin en timestamp. Je sais que toSTring retourne la bonne valeur.
Vous devez vous connecter pour publier un commentaire.
J'espère que cela sauve quelqu'un de 3 jours de la connerie. Définir le fuseau horaire par défaut quelque part logique dans votre code. Rend les choses plus portable que le fait d'avoir à définir une variable env etc.. Vous pouvez le faire par adjonction, quelque part logique de votre code, Constructeur, etc..:
DateTimeZone.setDefault(DateTimeZone.UTC);
Vous pouvez imprimer UTC, concaténer UTC quoi que...
TimeZone.setDefault(TimeZone)
](docs.oracle.com/javase/7/docs/api/java/util/TimeZone.html#setDefault(java.util.TimeZone). Vous pouvez aussi régler l'utilisateur.fuseau horaire du système de la propriété pour obtenir les deux en un seul passage. Si vous définissez le Fuseau horaire (en utilisant le système de la propriété ou de l'appel du code) avant de toucher les Joda code puis il sera ramasser votre réglage. Voir mon commentaire à ma réponse il y a quelques jours pour le réglage de laTimeZone
.Essayer ce programme court, il doit illustrer ce qui se passe:
Sur mon ordinateur, il affiche:
Comme vous pouvez le voir, vous pouvez obtenir à l'heure UTC, soit avec
.toInstant()
, ou avec.toDateTime(DateTimeZone.UTC)
. Mais même si vous appelez ni de ces, vous aurez toujours la valeur UTC lorsque vous appelezgetMillis()
.Donc, le problème n'est pas avec JodaTime. Le problème est dans la façon dont vous évaluez vos résultats.
Lorsque vous créez un
java.sql.Timestamp
, vous êtes de passage dans les millisecondes de 1/1/1970 UTC. C'est seulement quand vous affichage que c'est l'application du fuseau horaire local du résultat.En supposant que vous êtes de passage à une base de données comme un
Timestamp
et ne pas faire certaines interm représentation de chaîne, alors vous devriez être bien. Juste parce qu'il semble que l'heure locale lorsque vous appelezSystem.out.println
, ne veut pas dire que c'est une, heure locale, à l'interne.La
java.sql.Timestamp
classe étendjava.util.Date
- qui est l'endroit où il obtient ce problème.Timestamp
est sauvés dans l'heure locale, vous êtes peut-être la construction de votre requête SQL avec la concaténation de chaîne au lieu de passer des paramètres? Juste une supposition.J'ai eu du mal avec cela pendant des heures et finalement trouvé une solution.
Je suis en utilisant PlayFramework - vous ne savez pas si cela va aider quelqu'un, mais pour ma base de données paramétrage de la connexion j'ai eu à utiliser:
(ajouter le '&serverTimezone=UTC')
Vous avez besoin de la valeur UTC ou vous pouvez simplement utiliser l'Horodatage.la méthode toString ()? cela va vous donner la forme d'un temps de chaîne pour une utilisation dans les instructions SQL.
LocalDateTime
déjà exclut le fuseau horaire, ce qui signifie qu'il signifie littéralement le, heure locale, lorsque l'utilisateur entre "leur" temps (par exemple, pour un enterrement invitation, qui sera toujours dans le temps local) ou il est déjà en UTC si vous planifié à l'avance.Si votre
date
est déjà dans lesrcTZ
'sDateTimeZone
, mais chargé commeLocalDateTime
, alors vous devriez retournerAlternativement, si vous êtes sûr que le
date
est déjà en UTC, qui est GMT+0, alors vous pouvez retournerEnfin, la plupart des bases de données d'accepter le timestamp comme un ISO chaîne mise en forme, qui est la valeur par défaut
toString
de sortie:date
est dans un fuseau horaire comme l'EST/GMT-4, alors vous avez besoin de les convertir à unDateTime
objet qui fuseau horaire, ce qui devrait être la première étapetoDateTime(srcTZ)
. À ce stade, vous devriez avoir la réelle date/heure dans sa fuseau horaire. À partir de là, vous n'avez pas réellement besoin de fairetoDateTime(DateTimeZone.UTC)
, mais vous devriez être capable d'utilisergetMillis()
comme dansdate.toDateTime(srcTZ).getMillis()
.date
,srcTZ
et même ladstTZ
?TimeZone
UTC/GMT:TimeZone.setDefault(TimeZone.getTimeZone("GMT"))
. Cela ne doit être fait qu'une fois, de préférence au démarrage. Pour éviter d'écrire du code, vous pouvez également définir la"user.timezone"
système de la propriété, qui va le mettre (utiliser-Duser.timezone=GMT
UTC).