Comment convertir java.util.Date en java.sql.Date?

453

J'essaie d'utiliser une java.util.Dateentrée et puis de créer une requête avec elle - j'ai donc besoin d'une java.sql.Date.

J'ai été surpris de constater qu'il ne pouvait pas effectuer la conversion implicitement ou explicitement - mais je ne sais même pas comment je procéderais, car l'API Java est encore assez nouvelle pour moi.

David Ackerman
la source
Vous pouvez trouver un problème similaire ici stackoverflow.com/questions/12131068/…
Lem
Pour moi, il s'est avéré que je n'avais pas besoin de me convertir. Il y avait un import java.sql.*dans mon code, remplaçant java.util.date et causant ainsi des problèmes lors de l'attribution de valeurs de date qui convenaient à ce dernier mais pas au premier. HTH
HumanInDisguise
1
@DavidAckerman Comprenez-vous qu'un java.util.Date est une date et une heure, mais qu'un java.sql.Date n'est qu'une date sans heure? (En fait, il y a un moment de la journée mais qui est ignoré, un mauvais piratage d'une conception de classe) En SQL, DATEsignifie date uniquement.
Basil Bourque
2
En effet, je n'étais pas au courant des nuances de 2009, et puisque cette question est si populaire, j'ai changé la réponse acceptée en une réponse à la fois plus moderne et complète. Merci à tous pour votre contribution!
David Ackerman

Réponses:

89

tl; dr

Comment convertir java.util.Date en java.sql.Date?

Non. Les deux classes sont dépassées.

  • Utilisez les classes java.time au lieu de legacy java.util.Date& java.sql.Dateavec JDBC 4.2 ou version ultérieure.
  • Convertir vers / à partir de java.time si interagissant avec du code non encore mis à jour vers java.time.

Exemple de requête avec PreparedStatement.

myPreparedStatement.setObject( 
     ,                                         // Specify the ordinal number of which argument in SQL statement.
    myJavaUtilDate.toInstant()                  // Convert from legacy class `java.util.Date` (a moment in UTC) to a modern `java.time.Instant` (a moment in UTC).
        .atZone( ZoneId.of( "Africa/Tunis" ) )  // Adjust from UTC to a particular time zone, to determine a date. Instantiating a `ZonedDateTime`.
        .toLocalDate()                          // Extract a date-only `java.time.LocalDate` object from the date-time `ZonedDateTime` object.
)

Remplaçants:

  • Instantau lieu de java.util.Date
    Both représentent un moment en UTC. mais maintenant avec des nanosecondes au lieu de millisecondes.
  • LocalDateau lieu de java.sql.Date
    Both représentent une valeur de date uniquement sans heure et sans fuseau horaire.

Détails

Si vous essayez de travailler avec des valeurs de date uniquement (pas d'heure, pas de fuseau horaire), utilisez LocalDateplutôt la classe que java.util.Date.

Tableau des types date-heure en Java (ancien et moderne) et dans le standard SQL.

java.time

Dans Java 8 et versions ultérieures, les anciennes classes de date-heure gênantes regroupées avec les premières versions de Java ont été remplacées par le nouveau package java.time . Voir Oracle Tutorial . Une grande partie de la fonctionnalité a été rétroportée vers Java 6 et 7 dans ThreeTen-Backport et adaptée à Android dans ThreeTenABP .

Un type de données SQL DATE est censé être à date uniquement, sans heure et sans fuseau horaire. Java n'a jamais eu précisément une telle classe † qu'en java.time.LocalDateJava 8. Créons une telle valeur en obtenant la date d'aujourd'hui en fonction d'un fuseau horaire particulier (le fuseau horaire est important pour déterminer une date comme un nouveau jour se lève plus tôt à Paris qu'à Montréal, pour exemple).

LocalDate todayLocalDate = LocalDate.now( ZoneId.of( "America/Montreal" ) );  // Use proper "continent/region" time zone names; never use 3-4 letter codes like "EST" or "IST".

À ce stade, nous pouvons avoir terminé. Si votre pilote JDBC est conforme à la spécification JDBC 4.2 , vous devriez pouvoir passer un LocalDatevia setObjectsur un PreparedStatementpour le stocker dans un champ SQL DATE.

myPreparedStatement.setObject( 1 , localDate );

De même, utilisez ResultSet::getObjectpour extraire d'une colonne SQL DATE vers un LocalDateobjet Java . La spécification de la classe dans le deuxième argument rend votre code sûr pour le type .

LocalDate localDate = ResultSet.getObject( 1 , LocalDate.class );

En d'autres termes, toute cette question n'est pas pertinente sous JDBC 4.2 ou version ultérieure.

Si votre pilote JDBC ne fonctionne pas de cette manière, vous devez vous replier sur la conversion aux types java.sql.

Convertir en java.sql.Date

Pour convertir, utilisez de nouvelles méthodes ajoutées aux anciennes classes date-heure. Nous pouvons appeler java.sql.Date.valueOf(…)pour convertir un LocalDate.

java.sql.Date sqlDate = java.sql.Date.valueOf( todayLocalDate );

Et aller dans l'autre sens.

LocalDate localDate = sqlDate.toLocalDate();

Conversion de java.util.Date

Bien que vous deviez éviter d'utiliser les anciennes classes de date-heure, vous pourriez être obligé de le faire lorsque vous travaillez avec du code existant. Si c'est le cas, vous pouvez convertir vers / depuis java.time.

Parcourez la Instantclasse, qui représente un moment de la chronologie en UTC. Une Instantidée est similaire à une java.util.Date. Mais notez qu'il Instanta une résolution jusqu'à nanosecondes alors qu'il java.util.Daten'a qu'une résolution en millisecondes .

Pour convertir, utilisez de nouvelles méthodes ajoutées aux anciennes classes. Par exemple, java.util.Date.from( Instant )et java.util.Date::toInstant.

Instant instant = myUtilDate.toInstant();

Pour déterminer une date, nous avons besoin du contexte d'un fuseau horaire. Pour un moment donné, la date varie dans le monde entier par fuseau horaire. Appliquez un ZoneIdpour obtenir un ZonedDateTime.

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
LocalDate localDate = zdt.toLocalDate();

† La classe java.sql.Date prétend être datée uniquement sans heure, mais fait en fait une heure, ajustée à minuit. Déroutant? Oui, les anciennes classes de date-heure sont un gâchis.


À propos de java.time

Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciens gênants hérités des classes date-heure tels que java.util.Date, Calendar, et SimpleDateFormat.

Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers les classes java.time .

Pour en savoir plus, consultez le didacticiel 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 version ultérieure. Pas besoin de chaînes, pas besoin de java.sql.*cours.

Où obtenir les classes java.time?

Tableau de la bibliothèque java.time à utiliser avec quelle version de Java ou Android

Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour de futurs ajouts possibles à java.time. Vous trouverez peut - être des classes utiles ici, comme Interval, YearWeek, YearQuarteret plus .

Basil Bourque
la source
478

Ça ne fait rien....

public class MainClass {

  public static void main(String[] args) {
    java.util.Date utilDate = new java.util.Date();
    java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
    System.out.println("utilDate:" + utilDate);
    System.out.println("sqlDate:" + sqlDate);

  }

}

l'explique. Le lien est http://www.java2s.com/Tutorial/Java/0040__Data-Type/ConvertfromajavautilDateObjecttoajavasqlDateObject.htm

David Ackerman
la source
34
Ce n'est pas une conversion explicite! À partir du Javadoc: "Si la valeur en millisecondes donnée contient des informations d'heure, le pilote définira les composants d'heure sur l'heure dans le fuseau horaire par défaut (le fuseau horaire de la machine virtuelle Java exécutant l'application) qui correspond à zéro GMT." Peu importe l'heure à laquelle vous utilisez votre java.util.Date, il sera inséré en tant que 00:00:00 dans une colonne avec le type de données défini sur DATE.
1
@David Ackerman ..... cette méthode retourne les epochsecondsie millisecondes après 1,JAN,1970. Mais que faire si nous voulons stocker la date d'une personne avant cette date ... ou quelque chose comme0000-00-00 as default
Arjun KP
31
Dans mon cas, la bonne réponse est <code> java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp (utilDate.getTime ()); </code>, car il préserve les champs horaires.
Alberto de Paola
2
@ wired00 Oui, les anciennes classes date-heure fournies avec les premières versions de Java sont un gâchis , mal conçues, y compris quelques hacks grossiers. Dans la mesure du possible, essayez d'utiliser le nouveau framework java.time dans Java 8 et versions ultérieures. Ces nouvelles classes supplantent les anciennes. Les classes java.time et les anciennes classes ont des méthodes pratiques pour la conversion dans les deux sens - utiles pendant que nous attendons que les pilotes JDBC soient mis à jour pour utiliser directement les nouveaux types java.time.
Basil Bourque
1
@ wired00 Voir ma nouvelle réponse à cette question pour savoir comment utiliser java.time. Recherchez également StackOverflow pour de nombreux autres exemples.
Basil Bourque
39

Avec l'autre réponse, vous pouvez avoir des problèmes avec les informations de temps (comparer les dates avec des résultats inattendus!)

Je suggère:

java.util.Calendar cal = Calendar.getInstance();
java.util.Date utilDate = new java.util.Date(); // your util date
cal.setTime(utilDate);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);    
java.sql.Date sqlDate = new java.sql.Date(cal.getTime().getTime()); // your sql date
System.out.println("utilDate:" + utilDate);
System.out.println("sqlDate:" + sqlDate);
Maurice
la source
5
S'il utilise java.sql.Date pour une colonne Date dans une base de données, ces informations d'heure seront tronquées. Vous avez sur-conçu la solution à mon avis.
darioo
4
Oui, je l'ai peut-être fait. J'ai parfois besoin de comparer le java.sql.Data avec la date actuelle et à mon humble avis, c'est la meilleure façon. J'espère que ça peut aider.
mauretto
Pour info, les anciennes classes de date-heure terriblement gênantes telles que java.util.Date, java.util.Calendaret java.text.SimpleDateFormatsont désormais héritées , supplantées par les classes java.time intégrées à Java 8 et versions ultérieures. Voir Tutoriel par Oracle .
Basil Bourque
Bien sûr, ce sujet était il y a environ 10 ans, avant java 8.
mauretto
26

Cette fonction renverra une date SQL convertie à partir d'un objet date java.

public java.sql.Date convertJavaDateToSqlDate(java.util.Date date) {
    return new java.sql.Date(date.getTime());
}
chétan
la source
18

La conversion java.util.Dataen java.sql.Dataperdra heure, minute et seconde. Donc, si c'est possible, je vous suggère d'utiliser java.sql.Timestampcomme ceci:

prepareStatement.setTimestamp(1, new Timestamp(utilDate.getTime()));

Pour plus d'informations, vous pouvez vérifier cette question .

shellbye
la source
16

Dans mon cas de choisir la date de JXDatePicker (calendrier java) et de la stocker dans la base de données en tant que type de date SQL, ci-dessous fonctionne très bien.

java.sql.Date date = new java.sql.Date(pickedDate.getDate().getTime());

où pickDate est l'objet de JXDatePicker

Jack Jay
la source
5

Cette fonction renverra une date SQL convertie à partir d'un objet date java.

public static java.sql.Date convertFromJAVADateToSQLDate(
            java.util.Date javaDate) {
        java.sql.Date sqlDate = null;
        if (javaDate != null) {
            sqlDate = new Date(javaDate.getTime());
        }
        return sqlDate;
    }
Tanmay kumar shaw
la source
3

Formatez d'abord votre java.util.Date. Utilisez ensuite la date formatée pour obtenir la date dans java.sql.Date

java.util.Date utilDate = "Your date"
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
final String stringDate= dateFormat.format(utilDate);
final java.sql.Date sqlDate=  java.sql.Date.valueOf(stringDate);
hackfield
la source
2

Voici l'exemple de conversion d'Util Date en Sql date et ya ceci est un exemple ce que j'utilise dans mon projet pourrait aussi vous être utile.

java.util.Date utilStartDate = table_Login.getDob();(orwhat ever date your give form obj)
java.sql.Date sqlStartDate = new java.sql.Date(utilStartDate.getTime());(converting date)
Kishan Bheemajiyani
la source
2

Je suis novice: après avoir beaucoup couru, cela a fonctionné. La pensée pourrait être utile

     String bufDt =  bDOB.getText();  //data from form
     DateFormat dF = new SimpleDateFormat("dd-MM-yyyy"); //data in form is in this format
     Date bbdt = (Date)dF.parse(bufDt);  // string data is converted into java util date
     DateFormat dsF = new SimpleDateFormat("yyyy-MM-dd"); //converted date is reformatted for conversion to sql.date
     String ndt = dsF.format(bbdt); // java util date is converted to compatible java sql date
     java.sql.Date sqlDate=  java.sql.Date.valueOf(ndt);  // finally data from the form is convered to java sql. date for placing in database
PKSawmy
la source
Pour info, les anciennes classes de date-heure terriblement gênantes telles que java.util.Date, java.util.Calendaret java.text.SimpleDateFormatsont désormais héritées , supplantées par les classes java.time intégrées à Java 8 et versions ultérieures. Voir Tutoriel par Oracle .
Basil Bourque
2
java.sql.Date sqlDate = new java.sql.Date(javaDate.getTime());

Ici javaDate est l'instance de java.util.Date

Rajeev Ranjan
la source
1
Cela ne semble pas vraiment ajouter quelque chose de nouveau par rapport aux réponses de David Ackerman, chetan et Tanmay kumar shaw, n'est-ce pas?
Ole VV
1

Méthode de comparaison de 2 dates (util.date ou sql.date)

 public static boolean isSameDay(Date a, Date b) {
    Calendar calA = new GregorianCalendar();
    calA.setTime(a);

    Calendar calB = new GregorianCalendar();
    calB.setTime(b);

    final int yearA = calA.get(Calendar.YEAR);
    final int monthA = calA.get(Calendar.MONTH);
    final int dayA = calA.get(Calendar.DAY_OF_YEAR);

    final int yearB = calB.get(Calendar.YEAR);
    final int monthB = calB.get(Calendar.MONTH);
    final int dayB = calB.get(Calendar.DAY_OF_YEAR);

    return yearA == yearB && monthA == monthB && dayA == dayB;
}
Donovan Thomson
la source
0

essayez avec ça

public static String toMysqlDateStr(Date date) {
    String dateForMySql = "";
    if (date == null) {
        dateForMySql = null;
    } else {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateForMySql = sdf.format(date);
    }

    return dateForMySql;
}
kapil das
la source
-1

Je pense que la meilleure façon de convertir est:

static java.sql.Timestamp SQLDateTime(Long utilDate) {
    return new java.sql.Timestamp(utilDate);
}

Date date = new Date();
java.sql.Timestamp dt = SQLDateTime(date.getTime());

Si vous souhaitez insérer la dtvariable dans une table SQL, vous pouvez faire:

insert into table (expireAt) values ('"+dt+"');
user6043502
la source
1
Cela semble être essentiellement le même que cette réponse publiée un an plus tôt.
Bernhard Barker
-3

J'utilise le code suivant, essayez-le

DateFormat fm= new SimpleDateFormatter();

spécifiez par exemple le format de la date souhaitée "DD-MM_YYYY"ou 'YYYY-mm-dd' utilisez le type de données java Date comme

fm.format("object of java.util.date");

alors il analysera votre date

UmeshA
la source
-3

Vous pouvez utiliser cette méthode pour convertir la date d'utilisation en date sql,

DateUtilities.convertUtilDateToSql(java.util.Date)
Emmanuel Angelo.R
la source
Il n'y a pas de classe DateUtilities dans la bibliothèque Java standard (et je ne trouve même pas cette méthode du tout à partir d'une recherche rapide sur Google). S'il s'agit d'une bibliothèque spécifique, vous pouvez en dire autant et inclure un lien vers les documents.
Bernhard Barker
-4

J'essayais le codage suivant qui fonctionnait bien.

java.util.Date utilDate = new java.util.Date ();
java.sql.Date sqlDate = new java.sql.Date (utilDate);

PONRAJ
la source
-8

Si vous utilisez Mysql une colonne de date peut être passée une représentation de chaîne de cette date

donc j'utilise la classe DateFormatter pour la formater, puis la définir comme une chaîne dans l'instruction sql ou l'instruction préparée

voici l'illustration du code:

private String converUtilDateToSqlDate(java.util.Date utilDate) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String sqlDate = sdf.format(utilDate);
    return sqlDate;
}

String date = converUtilDateToSqlDate (otherTransaction.getTransDate ());

// puis passez cette date dans votre instruction sql

Benjamin Ndugga
la source
14
Bienvenue sur stackoverflow, j'ai quelques commentaires à votre réponse. La question était "comment convertir un java.util.Date en java.sql.Date". Le code que vous avez collé formate un java.util.Date en aaaa-MM-jj. Ceci est en fait d'une utilité limitée dans ce contexte car vous devez passer le java.sql.Date directement aux pilotes jdbc au lieu de le faire en tant que chaîne.
jontro