web-dev-qa-db-fra.com

Conversion de LocalDate en LocalDateTime ou Java.sql.Timestamp

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!

107
IAmYourFaja

JodaTime

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());
_

JavaTime

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);
_
240
BalusC

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!

52
GKislin

tl; dr

Le projet Joda-Time est en mode maintenance, maintenant remplacé par les classes Java.time.

  • Utilisez simplement la classe Java.time.Instant.
  • Pas besoin d:
    • LocalDateTime
    • _Java.sql.Timestamp_
    • Les cordes

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 classe

Les 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 classe

Le 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 .

JDBC 4.2 avec 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 ) ;
_

Convertir l'héritage ⬌ moderne

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.
_

À propos de Java.time

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 .

11
Basil Bourque

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);
5
user1302021

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);
2
prime

appel de fonction asStartOfDay() sur l'objet Java.time.LocalDate renvoie un objet Java.time.LocalDateTime

1
Ahmad sibai

Java8 +

import Java.time.Instant;
Instant.now().getEpochSecond(); //timestamp in seconds format (int)
Instant.now().toEpochMilli(); // timestamp in milliseconds format (long)
0
Mohamed.Abdo