J'essaie de définir une date indépendante du serveur dans ma base de données et je pense que la meilleure pratique consiste à définir un DateTime UTC. Mon serveur de base de données est Cassandra et le pilote de base de données pour Java ne comprend que le type Date.
En supposant que, dans mon code, j'utilise le nouveau Java 8 ZonedDateTime pour obtenir l'heure UTC maintenant (ZonedDateTime.now(ZoneOffset.UTC)
), comment puis-je convertir cette instance ZonedDateTime en classe de date "héritée"?
Vous pouvez convertir ZonedDateTime en un instant que vous pouvez utiliser directement avec Date.
Date.from(Java.time.ZonedDateTime.now().toInstant());
Voici un exemple de conversion de l'heure système actuelle en UTC. Cela implique de formater ZonedDateTime en tant que chaîne, puis l'objet chaîne sera analysé en un objet date à l'aide de Java.text DateFormat.
ZonedDateTime zdt = ZonedDateTime.now(ZoneOffset.UTC);
final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss");
final DateFormat FORMATTER_YYYYMMDD_HH_MM_SS = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
String dateStr = zdt.format(DATETIME_FORMATTER);
Date utcDate = null;
try {
utcDate = FORMATTER_YYYYMMDD_HH_MM_SS.parse(dateStr);
}catch (ParseException ex){
ex.printStackTrace();
}
Si vous utilisez le port arrière ThreeTen pour Android et que vous ne pouvez pas utiliser le Date.from(Instant instant)
plus récent (qui requiert un minimum de 26 API), vous pouvez utiliser:
ZonedDateTime zdt = ZonedDateTime.now();
Date date = new Date(zdt.toInstant().toEpochMilli());
ou:
Date date = DateTimeUtils.toDate(zdt.toInstant());
Veuillez également lire les conseils dans Réponse de Basil Bourque
Si vous êtes intéressé seulement maintenant, utilisez simplement:
Date d = new Date();
Pour ce faire, utilisez les classes Java.time intégrées à Java 8 et versions ultérieures.
ZonedDateTime temporal = ...
long epochSecond = temporal.getLong(INSTANT_SECONDS);
int nanoOfSecond = temporal.get(NANO_OF_SECOND);
Date date = new Date(epochSecond * 1000 + nanoOfSecond / 1000000);
Pour une application de menu fixe comme beehuang, vous devez définir votre fuseau horaire.
Sinon, vous pouvez utiliser withZoneSameLocal . Par exemple:
2014-07-01T00: 00 + 02: 00 [GMT + 02: 00] est converti par
Date.from(zonedDateTime.withZoneSameLocal(ZoneId.systemDefault()).toInstant())
à mar. juil. 01 00:00:00 CEST 2014 et par
Date.from(zonedDateTime.toInstant())
à lun. juin 30 22:00:00 UTC 2014
Je l'utilise.
public class TimeTools {
public static Date getTaipeiNowDate() {
Instant now = Instant.now();
ZoneId zoneId = ZoneId.of("Asia/Taipei");
ZonedDateTime dateAndTimeInTai = ZonedDateTime.ofInstant(now, zoneId);
try {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateAndTimeInTai.toString().substring(0, 19).replace("T", " "));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
Parce que
Date.from(Java.time.ZonedDateTime.ofInstant(now, zoneId).toInstant());
Ce n'est pas un travail !!! Si vous exécutez votre application sur votre ordinateur, ce n'est pas un problème. Mais si vous exécutez dans n’importe quelle région d’AWS, de Docker ou de GCP, le problème sera généré. Parce que l'ordinateur n'est pas votre fuseau horaire sur le Cloud. Vous devez définir votre fuseau horaire correctement dans le code. Par exemple, Asie/Taipei. Ensuite, il corrigera dans AWS ou Docker ou GCP.
public class App {
public static void main(String[] args) {
Instant now = Instant.now();
ZoneId zoneId = ZoneId.of("Australia/Sydney");
ZonedDateTime dateAndTimeInLA = ZonedDateTime.ofInstant(now, zoneId);
try {
Date ans = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateAndTimeInLA.toString().substring(0, 19).replace("T", " "));
System.out.println("ans="+ans);
} catch (ParseException e) {
}
Date wrongAns = Date.from(Java.time.ZonedDateTime.ofInstant(now, zoneId).toInstant());
System.out.println("wrongAns="+wrongAns);
}
}