J'utilise JodaTime 1.6.2.
J'ai un LocalDate
que je dois convertir soit en (Joda) LocalDateTime
, soit en Java.sqlTimestamp
pour ormapping.
La raison en est que j'ai découvert comment convertir entre un LocalDateTime
et un Java.sql.Timestamp
:
LocalDateTime ldt = new LocalDateTime();
DateTimeFormatter dtf = DateTimeFormatter.forPattern("yyyy-MM-dd HH:mm:ss");
Timestamp ts = Timestamp.valueOf(ldt.toString(dtf));
Donc, si je peux simplement convertir entre LocalDate
et LocalDateTime
, je pourrai alors poursuivre la conversion en Java.sql.Timestamp
. Merci pour tous les coups de pouce dans la bonne direction!
Pour convertir les org.joda.time.LocalDate
en Java.sql.Timestamp
de JodaTime, faites simplement
_Timestamp timestamp = new Timestamp(localDate.toDateTimeAtStartOfDay().getMillis());
_
Pour convertir les org.joda.time.LocalDateTime
en Java.sql.Timestamp
de JodaTime, faites simplement
_Timestamp timestamp = new Timestamp(localDateTime.toDateTime().getMillis());
_
Pour convertir les versions de Java8 Java.time.LocalDate
en Java.sql.Timestamp
, faites simplement
_Timestamp timestamp = Timestamp.valueOf(localDate.atStartOfDay());
_
Pour convertir les versions de Java8 Java.time.LocalDateTime
en Java.sql.Timestamp
, faites simplement
_Timestamp timestamp = Timestamp.valueOf(localDateTime);
_
La meilleure façon d'utiliser Java 8 API de temps:
LocalDateTime ldt = timeStamp.toLocalDateTime();
Timestamp ts = Timestamp.valueOf(ldt);
À utiliser avec JPA inséré dans votre modèle ( https://weblogs.Java.net/blog/montanajava/archive/2014/06/17/using-Java-8-datetime-classes-jpa ):
@Converter(autoApply = true)
public class LocalDateTimeConverter implements AttributeConverter<LocalDateTime, Timestamp> {
@Override
public Timestamp convertToDatabaseColumn(LocalDateTime ldt) {
return Timestamp.valueOf(ldt);
}
@Override
public LocalDateTime convertToEntityAttribute(Timestamp ts) {
return ts.toLocalDateTime();
}
}
Alors maintenant, le fuseau horaire est indépendant du temps relatif. De plus, il est facile à faire:
LocalDate ld = ldt.toLocalDate();
LocalTime lt = ldt.toLocalTime();
Mise en page:
DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
String str = ldt.format(DATE_TME_FORMATTER);
ldt = LocalDateTime.parse(str, DATE_TME_FORMATTER);
UPDATE: postgres 9.4.1208, HSQLDB 2.4.0, etc., comprennent Java 8 API sans temps!
Le projet Joda-Time est en mode maintenance, maintenant remplacé par les classes Java.time.
Java.time.Instant
.LocalDateTime
Java.sql.Timestamp
_Capturer le moment actuel en UTC.
_Instant.now()
_
Pour stocker ce moment dans la base de données:
_myPreparedStatement.setObject( … , Instant.now() ) // Writes an `Instant` to database.
_
Pour récupérer ce moment dans la base de données:
_myResultSet.getObject( … , Instant.class ) // Instantiates a `Instant`
_
Pour ajuster l'heure de l'horloge murale à celle d'un fuseau horaire particulier.
_instant.atZone( z ) // Instantiates a `ZonedDateTime`
_
LocalDateTime
est la mauvaise classeLes autres réponses sont correctes, mais elles ne permettent pas de souligner que LocalDateTime
est la classe qui ne convient pas.
À la fois Java.time et Joda-Time, un LocalDateTime
manque délibérément de concept de fuseau horaire ou de décalage par rapport à UTC. En tant que tel, il représente pas un moment, et pas un point sur la timeline. LocalDateTime
représente une idée approximative de potentiels moments sur une plage d’environ 26-27 heures.
Utilisez LocalDateTime
lorsque la zone/le décalage est inconnu (situation défavorable) ou lorsque le décalage de zone est indéterminé. Par exemple, "Noël commence au premier instant du 25 décembre 2018" serait représenté par un LocalDateTime
.
Utilisez un ZonedDateTime
pour représenter un moment dans un fuseau horaire particulier. Par exemple, Noël commençant dans une zone particulière telle que _Pacific/Auckland
_ ou _America/Montreal
_ serait représenté par un objet ZonedDateTime
.
Pendant un moment toujours en UTC, utilisez Instant
.
_Instant instant = Instant.now() ; // Capture the current moment in UTC.
_
Appliquer un fuseau horaire. Même moment, même point sur la timeline, mais affiché avec une heure différente.
_ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, different wall-clock time.
_
Donc, si je peux juste convertir entre LocalDate et LocalDateTime,
Non, mauvaise stratégie. Si vous avez une valeur de date uniquement et que vous voulez une valeur de date-heure, vous devez spécifier une heure. Cette heure peut ne pas être valide à cette date pour une zone particulière - auquel cas la classe ZonedDateTime
ajuste automatiquement l'heure selon les besoins.
_LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 ) ;
LocalTime lt = LocalTime.of( 14 , 0 ) ; // 14:00 = 2 PM.
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
_
Si vous voulez que le premier moment de la journée soit votre heure, laissez Java.time déterminer ce moment. Ne supposez pas que la journée commence à 00:00:00. Les anomalies telles que l'heure d'été (DST) signifient que la journée peut commencer à une autre heure, telle que 01:00:00.
_ZonedDateTime zdt = ld.atStartOfDay( z ) ;
_
Java.sql.Timestamp
_ est la mauvaise classeLe Java.sql.Timestamp
fait partie des anciennes classes de date-heure problématiques qui sont maintenant héritées, entièrement supplantées par les classes Java.time. Cette classe a été utilisée pour représenter un moment dans UTC avec une résolution de nanosecondes . Ce but est maintenant servi avec Java.time.Instant
.
getObject
/setObject
À partir de JDBC 4.2 et ultérieur, votre pilote JDBC peut échanger directement des objets Java.time avec la base de données en appelant:
Par exemple:
_myPreparedStatement.setObject( … , instant ) ;
_
… et …
_Instant instant = myResultSet.getObject( … , Instant.class ) ;
_
Si vous devez vous connecter avec l'ancien code non encore mis à jour avec Java.time, effectuez la conversion en utilisant de nouvelles méthodes ajoutées aux anciennes classes.
_Instant instant = myJavaSqlTimestamp.toInstant() ; // Going from legacy class to modern class.
_
…et…
_Java.sql.Timestamp myJavaSqlTimestamp = Java.sql.Timestamp.from( instant ) ; // Going from modern class to legacy class.
_
Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciennes et obsolètes anciennes classes telles que Java.util.Date
, Calendar
, & SimpleDateFormat
.
Le projet Joda-Time , désormais en mode de maintenance , conseille la migration vers le fichier Java = classes.
Pour en savoir plus, voir le Tutoriel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .
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.*
_ 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 des classes utiles telles que Interval
, YearWeek
, YearQuarter
et plus .
Selon votre fuseau horaire, vous risquez de perdre quelques minutes (1650-01-01 00:00:00 devient 1649-12-31 23:52:58)
Utilisez le code suivant pour éviter cela
new Timestamp(localDateTime.getYear() - 1900, localDateTime.getMonthOfYear() - 1, localDateTime.getDayOfMonth(), localDateTime.getHourOfDay(), localDateTime.getMinuteOfHour(), localDateTime.getSecondOfMinute(), fractional);
Puisque Joda est en train de s'estomper, quelqu'un voudra peut-être convertir LocaltDate
en LocalDateTime
en Java 8. En Java 8 LocalDateTime
, il donnera manière de créer une instance LocalDateTime
en utilisant LocalDate
et LocalTime
. Vérifier ici.
public static LocalDateTime of (date du LocalDate, heure du LocalTime)
Échantillon serait,
// just to create a sample LocalDate
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate ld = LocalDate.parse("20180306", dtf);
// convert ld into a LocalDateTime
// We need to specify the LocalTime component here as well, it can be any accepted value
LocalDateTime ldt = LocalDateTime.of(ld, LocalTime.of(0,0)); // 2018-03-06T00:00
Juste pour référence, pour obtenir les secondes d’époque ci-dessous peut être utilisé,
ZoneId zoneId = ZoneId.systemDefault();
long Epoch = ldt.atZone(zoneId).toEpochSecond();
// If you only care about UTC
long epochUTC = ldt.toEpochSecond(ZoneOffset.UTC);
appel de fonction asStartOfDay()
sur l'objet Java.time.LocalDate
renvoie un objet Java.time.LocalDateTime
Java8 +
import Java.time.Instant;
Instant.now().getEpochSecond(); //timestamp in seconds format (int)
Instant.now().toEpochMilli(); // timestamp in milliseconds format (long)