J'obtiens le timestamp UTC de la base de données que je mets dans une instance JodaTime DateTime
DateTime dt = new DateTime(timestamp.getTime());
Il stocke l'heure parfaitement dire 10:00 AM
Mais avec le fuseau horaire local. Par exemple, je suis dans le fuseau horaire IST qui est à +5: 30 de UTC
J'ai essayé beaucoup de choses pour changer le fuseau horaire, mais chaque chose change l'heure de 10:00 AM
À autre chose en utilisant une différence de +5: 30.
Y at-il un moyen par lequel je peux changer TimeZone sans affecter le temps actuel
EDIT: Si mon heure actuelle est:
2013-09-25 11:27:34 AM UTC
Voici le résultat lorsque j'utilise cette new DateTime(timestamp.getTime());
2013-09-25 11:27:34 AM Asia/Kolkata
Et voici le résultat lorsque j'utilise ceci new DateTime(timestamp.getTime(), DateTimeZone.UTC)
;
2013-09-25 05:57:34 AM UTC
Vous pouvez utiliser la classe LocalDateTime
LocalDateTime dt = new LocalDateTime(t.getTime());
et convertir LocalDateTime
en DateTime
DateTime dt = new LocalDateTime(timestamp.getTime()).toDateTime(DateTimeZone.UTC);
Joda DateTime
traite n'importe quel moment en millis comme "millis depuis 1970 dans le fuseau horaire actuel ". Ainsi, lorsque vous créez l'instance DateTime
, celle-ci est créée avec le fuseau horaire actuel.
Vous pouvez utiliser la méthode withZoneRetainFields()
de DateTime
pour modifier le fuseau horaire sans modifier les chiffres de la date.
Si votre horodatage est le: 2015-01-01T00: 00: 00.000-0500 (c'est l'heure locale [pour moi])
Essaye ça:
DateTime localDt = new DateTime(timestamp.getTime())
.withZoneRetainFields(DateTimeZone.UTC)
.withZone(DateTimeZone.getDefault());
2014-12-31T19: 00: 00.000-05: 00
Décomposition: Cela vous donne un DateTime correspondant à votre horodatage, en spécifiant qu'il est en UTC:
new DateTime(timestamp.getTime())
.withZoneRetainFields(DateTimeZone.UTC)
2015-01-01T00: 00: 00.000Z
Cela vous donne un DateTime mais avec l'heure convertie à votre heure locale:
new DateTime(timestamp.getTime())
.withZoneRetainFields(DateTimeZone.UTC)
.withZone(DateTimeZone.getDefault());
2014-12-31T19: 00: 00.000-05: 00
Voici comment je le fais:
private DateTime convertLocalToUTC(DateTime eventDateTime) {
// get your local timezone
DateTimeZone localTZ = DateTimeZone.getDefault();
// convert the input local datetime to utc
long eventMillsInUTCTimeZone = localTZ.convertLocalToUTC(eventDateTime.getMillis(), false);
DateTime evenDateTimeInUTCTimeZone = new DateTime(eventMillsInUTCTimeZone);
return evenDateTimeInUTCTimeZone.toDate();
}
Aucune des réponses fournies n'a réellement expliqué le problème. Le vrai problème est que les hypothèses initiales étaient incorrectes. L'horodatage de la base de données a été créé à l'aide du fuseau horaire local de la machine virtuelle Java Asia/Kolkata
Et non de l'heure UTC. C'est le comportement par défaut avec JDBC, raison pour laquelle il est toujours recommandé de définir votre fuseau horaire JVM sur UTC.
Si l'horodatage de la base de données était en fait:
2013-09-25 11:27:34 AM UTC
Ou au format ISO-8601:
2013-09-25T11:27:34Z // The trailing 'Z' means UTC
Ensuite, utiliser le constructeur new DateTime(timestamp, DateTimeZone.UTC)
fonctionne bien. Voir par vous-même:
Timestamp timestamp = new Timestamp(1380108454000L);
DateTime dt = new DateTime(timestamp.getTime(), DateTimeZone.UTC);
System.out.println(dt); // => 2013-09-25T11:27:34.000Z
Si vous vous demandez comment j'ai obtenu 1380108454000L
, J'ai simplement utilisé les classes d'analyse syntaxique de Joda:
ISODateTimeFormat.dateTimeParser().parseMillis("2013-09-25T11:27:34Z")
Il existe également des sites Web en ligne sur lesquels vous pouvez entrer une date, une heure et un fuseau horaire. La valeur Epoch est renvoyée en millisecondes ou inversement. C'est parfois bon comme contrôle de santé mentale.
// https://www.epochconverter.com
Input: 1380108454000 Click: "Timestamp to Human Date"
Assuming that this timestamp is in milliseconds:
GMT: Wednesday, September 25, 2013 11:27:34 AM
N'oubliez pas non plus que la classe Java.sql.Timestamp
Est corrélée à la classe Joda/Java 8+ Instant
. Parfois, il est plus facile de convertir des classes équivalentes pour repérer des bogues comme celui-ci plus tôt.
J'ai eu le même problème. Après avoir lu cet ensemble de réponses utiles, et compte tenu de mes besoins particuliers et des objets disponibles, je l'ai résolu en utilisant un autre constructeur DateTime:
new DateTime("2012-04-23T18:25:46.511Z", DateTimeZone.UTC)
J'ai aussi une autre approche qui m'a été très utile. Je souhaitais que mon thread de flux de travail temporaire soit modifié en un fuseau horaire spécifique (en préservant l'heure), puis une fois le code terminé, je rétablis le fuseau horaire d'origine. Il se trouve que lorsque vous utilisez des bibliothèques Joda, vous devez:
TimeZone.setDefault(TimeZone.getTimeZone(myTempTimeZone));
TimeZone.setDefault(timeZone);
Ce n'est pas assez. Nous devons également modifier le fuseau horaire dans DateTimeZone comme suit:
@Before
public void setUp() throws Exception {
timeZone = TimeZone.getDefault();
dateTimeZone = DateTimeZone.getDefault();
}
@After
public void tearDown() throws Exception {
TimeZone.setDefault(timeZone);
DateTimeZone.setDefault(dateTimeZone);
}
@Test
public void myTest() throws Exception {
TimeZone.setDefault(TimeZone.getTimeZone(myTempTimeZone));
DateTimeZone.setDefault(DateTimeZone.forID(myTempTimeZone));
//TODO
// my code with an specific timezone conserving time
}
J'espère que cela aide aussi quelqu'un d'autre.