final Timestamp rawDateTime = Timestamp.valueOf("2031-04-25 18:30:00"); final ZoneId zoneId = ZoneId.of("Asia/Calcutta"); final ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant( Instant.ofEpochMilli(rawDateTime.getTime()), zoneId); // here we are getting output as 2031-04-25T18:30+05:30[Asia/Calcutta] final ZonedDateTime zonedDateTime1 = ZonedDateTime.of(rawDateTime.toLocalDateTime(), zoneId); // here we are getting output as 2031-04-25T18:30+05:30[Asia/Calcutta] But I want to get the converted date time as 2031-04-26 00:00:00+5:30 as my timestamp value is in the UTC Timezone.Please help.
3 Réponses :
Premièrement, vous ne devez pas utiliser Timestamp
. Vous pouvez utiliser DateTimeFormatter
pour analyser en un LocalDateTime
.
Vous zonez ensuite ce LocalDateTime
en UTC avant de passer à la zone Calcutta avec ZonedDateTime.withZoneSameInstant
.
DateTimeFormatter formatter = new DateTimeFormatterBuilder() .append(DateTimeFormatter.ISO_LOCAL_DATE) .appendLiteral(' ') .append(DateTimeFormatter.ISO_LOCAL_TIME) .toFormatter(); LocalDateTime localDateTime = LocalDateTime.parse("2031-04-25 18:30:00", formatter); ZoneId calcuttaZone = ZoneId.of("Asia/Calcutta"); ZonedDateTime calcuttaZonedDateTime = localDateTime.atZone(ZoneOffset.UTC) .withZoneSameInstant(calcuttaZone);
DateTimeFormatter.ofPattern ("aaaa-MM-jj HH: mm: ss [XXX]"). Format (calcuttaZonedDateTime) doit indiquer la date formatée - c'est-à-dire 2031-04-26 00: 00: 00 + 5: 30 dans ce cas .
Au lieu de ZonedDateTime avec des zones nommées ayant des normes (supra-) nationales comme les économies de jour, utilisez OffsetDateTime.
Instant raw = Instant.parse("2031-04-25T18:30:00Z"); ZonedDateTime zoned = raw.atZone(ZoneId.of("Asia/Calcutta")); OffsetDateTime offset = OffsetDateTime.from(zoned);
L'analyse par défaut est pour le format ISO.
Z
signifie zéro, UTC, +0: 00. 2031-04-26T00: 00 + 05: 30
. Ce qui précède est particulièrement sujet aux erreurs si l'heure d'été est impliquée, comme dans Heure d'Europe centrale avec différents décalages +1: 00 et +2: 00.
OffsetDateTime utc = OffsetDateTime.parse("2031-04-25T18:30:00Z"); OffsetDateTime asia = utc.withOffsetSameInstant(ZoneOffset.ofHoursMinutes(5, 30));
Pas vraiment recommandé. Alors que Asia / Calcutta
explique pourquoi le décalage de +05: 30 est souhaité, ZoneOffset.ofHoursMinutes (5, 30)
ne le fait pas. Et ce dernier se cassera si le Parlement indien décide un jour de passer à un nombre entier d'heures de UTC ou d'introduire l'heure d'été (DST) (le risque peut ne pas être grand dans ce cas particulier, mais en général, l'utilisation de l'ID de zone est le meilleur pratique; d'autres zones changent de décalage plus souvent que prévu).
@ OleV.V. Je suis d'accord, mais un décalage était nécessaire, et pas Asia / Calcutta. Pour cette raison, j'ai mentionné la différence, c'est-à-dire «norme nationale» et DST. Mais OffsetDateTime laisse en effet tomber des informations précieuses. Le PO voulait une date UTC représentée comme un décalage indien. Pour un CET avec l'heure d'été, je serais passé par un ZoneId.
Instant n'analysera pas la chaîne de la forme '2031-04-25 18:30:00', un DateTimeFormatter ou LocalDate.parse sera nécessaire pour créer un Instant, dans un premier temps.
@ user1653941 oui. L'ISO prescrit un T
au lieu d'un espace devant la partie temps . Pour une analyse par défaut.
Utilisation de DateTimeFormatter pour formater ZonedDateTime:
2031-04-26 00:00:00+5:30
Le résultat:
final Timestamp rawDateTime = Timestamp.valueOf("2031-04-25 18:30:00"); LocalDateTime ldt = rawDateTime.toLocalDateTime(); final ZoneId zoneId = ZoneId.of("Asia/Calcutta"); ZonedDateTime zdt = ldt.atZone(ZoneId.of("UTC")) .withZoneSameInstant(zoneId); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[XXX]"); System.out.println(formatter.format(zdt));
Modifié: selon le commentaire de @Ole VV - L'heure de la date locale doit être convertie en heure de zone, avant d'appliquer le format:
2031-04-25 23:00:00+05:30 2031-04-25 18:30:00+05:30
Cela donnera la sortie:
final Timestamp rawDateTime = Timestamp.valueOf("2031-04-25 18:30:00"); final ZoneId zoneId = ZoneId.of("Asia/Calcutta"); final ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant( Instant.ofEpochMilli(rawDateTime.getTime()), zoneId); // here we are getting output as 2031-04-25T18:30+05:30[Asia/Calcutta] DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[XXX]"); System.out.println(formatter.format(zonedDateTime)); final ZonedDateTime zonedDateTime1 = ZonedDateTime.of(rawDateTime.toLocalDateTime(), zoneId); // here we are getting output as 2031-04-25T18:30+05:30[Asia/Calcutta] System.out.println(formatter.format(zonedDateTime1));
À droite, l'heure de la date locale doit être convertie en heure de la zone dans la zone demandée. Ont édité, merci. Il doit donner le résultat souhaité.
Votre code ne se compile pas. Il vous manque un point-virgule sur la première ligne et "Asia / Calcutta" n'est pas un
ZoneId
, c'est uneString
. Veuillez vous assurer que votre code fait réellement ce que vous prétendez faire avant de le publier sur Stack Overflow.Puisque vous utilisez java.time, l'API de date et d'heure Java moderne, vous devez éviter la classe
Timestamp
, elle appartient aux anciennes classes obsolètes qui ont maintenant été remplacées. Utilisez plutôtInstant
(ou dans des cas particuliersLocalDateTime
).Copie possible de Java: comment convertir un Horodatage UTC à l'heure locale? et bien d'autres questions. Veuillez rechercher et trouver.