Je reçois l'exception suivante en essayant de convertir Java.util.Date
à Java.time.LocalDate
.
Java.time.DateTimeException: Unable to obtain ZonedDateTime from TemporalAccessor: 2014-08-19T05:28:16.768Z of type Java.time.Instant
Le code est le suivant:
public static Date getNearestQuarterStartDate(Date calculateFromDate){
int[] quaterStartMonths={1,4,7,10};
Date startDate=null;
ZonedDateTime d=ZonedDateTime.from(calculateFromDate.toInstant());
int frmDateMonth=d.getMonth().getValue();
Quelque chose ne va pas dans la façon dont j'utilise la classe ZonedDateTime
?
Selon la documentation, ceci devrait convertir un Java.util.Date
objet à ZonedDateTime
. Le format de date ci-dessus est standard Date?
Dois-je avoir recours au temps de Joda?
Si quelqu'un pouvait faire une suggestion, ce serait génial.
Pour transformer un Instant
en un ZonedDateTime
, ZonedDateTime
offre la méthode ZonedDateTime.ofInstant(Instant, ZoneId)
. Alors
Donc, en supposant que vous souhaitiez un ZonedDateTime
dans le fuseau horaire par défaut, votre code devrait être
ZonedDateTime d = ZonedDateTime.ofInstant(calculateFromDate.toInstant(),
ZoneId.systemDefault());
Pour obtenir un ZonedDateTime à partir d’une date, vous pouvez utiliser:
calculateFromDate.toInstant().atZone(ZoneId.systemDefault())
Vous pouvez ensuite appeler la méthode toLocalDate
si vous avez besoin d'un LocalDate. Voir aussi: Convertir Java.util.Date en Java.time.LocalDate
Le Answer by assylias et le Answer by JB Nizet sont corrects:
Java.util.Date::toInstant
.Instant::atZone
, en passant un ZoneId
, résultant en un ZonedDateTime
.Mais votre exemple de code vise les quartiers. Pour cela, lisez la suite.
Pas besoin de rouler vous-même la gestion des quartiers. Utilisez une classe déjà écrite et testée.
org.threeten.extra.YearQuarter
Les classes Java.time sont étendues par le projet ThreeTen-Extra . Parmi les nombreuses classes pratiques fournies dans cette bibliothèque, vous trouverez Quarter
et YearQuarter
.
Commencez par obtenir votre ZonedDateTime
.
ZonedId z = ZoneID.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = myJavaUtilDate.toInstant().atZone( z ) ;
Déterminez le trimestre de l'année pour cette date.
YearQuarter yq = YearQuarter.from( zdt ) ;
Ensuite, nous avons besoin de la date de début de ce trimestre.
LocalDate quarterStart = yq.atDay( 1 ) ;
Bien que je ne le recommande pas nécessairement, vous pouvez utiliser une seule ligne de code plutôt que d'implémenter une méthode.
LocalDate quarterStart = // Represent a date-only, without time-of-day and without time zone.
YearQuarter // Represent a specific quarter using the ThreeTen-Extra class `org.threeten.extra.YearQuarter`.
.from( // Given a moment, determine its year-quarter.
myJavaUtilDate // Terrible legacy class `Java.util.Date` represents a moment in UTC as a count of milliseconds since the Epoch of 1970-01-01T00:00:00Z. Avoid using this class if at all possible.
.toInstant() // New method on old class to convert from legacy to modern. `Instant` represents a moment in UTC as a count of nanoseconds since the Epoch of 1970-01-01T00:00:00Z.
.atZone( // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone). Same moment, same point on the timeline, different wall-clock time.
ZoneID.of( "Africa/Tunis" ) // Specify a time zone using proper `Continent/Region` format. Never use 2-4 letter pseudo-zone such as `PST` or `EST` or `IST`.
) // Returns a `ZonedDateTime` object.
) // Returns a `YearQuarter` object.
.atDay( 1 ) // Returns a `LocalDate` object, the first day of the quarter.
;
À propos, si vous pouvez éliminer votre utilisation de Java.util.Date
tout à fait, faites-le. C'est une classe terrible , avec ses frères et soeurs tels que Calendar
. Utilisez Date
uniquement où vous devez, lorsque vous vous connectez avec un ancien code non encore mis à jour vers Java.time .
Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent l'ancien problème - legacy classes date-heure telles que Java.util.Date
, Calendar
, & SimpleDateFormat
.
Pour en savoir plus, consultez le Oracle Tutorial . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 31 .
Le projet Joda-Time , maintenant en mode de maintenance , conseille de migrer vers le Java.time = cours.
Vous pouvez échanger des objets Java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou une version ultérieure. Pas besoin de chaînes, pas besoin de Java.sql.*
Des classes.
Où obtenir les classes Java.time?
Le projet ThreeTen-Extra étend Java.time avec des classes supplémentaires. Ce projet est un terrain d’essai pour d’éventuels ajouts à Java.time. Vous pouvez trouver ici quelques classes utiles telles que Interval
, YearWeek
, YearQuarter
, et plus .
La réponse n'a pas fonctionné pour moi sur Java 10 stockant util.Date en UTC.
Date.toInstant () semble convertir EpochMillis dans le fuseau horaire local du serveur.
ZDT.ofInstant (instant, zoneId) et instant.atZone (zoneId) semblent juste taguer sur un TZ à l'instant, mais c'est déjà foiré.
Je ne pouvais pas trouver un moyen d'empêcher Date.toInstant () de modifier l'heure UTC avec le fuseau horaire du système.
La seule façon pour moi de contourner ce problème était de passer par la classe sql.Timestamp:
new Java.sql.Timestamp(date.getTime()).toLocalDateTime()
.atZone(ZoneId.of("UTC"))
.withZoneSameInstant(desiredTZ)