¿Cómo convertir java.util.Date a java.sql.Date?


453

Estoy tratando de usar un java.util.Datecomo entrada y luego crear una consulta con él, así que necesito un java.sql.Date.

Me sorprendió descubrir que no podía hacer la conversión implícita o explícitamente, pero ni siquiera sé cómo haría esto, ya que la API de Java todavía es bastante nueva para mí.


Puede encontrar un problema similar aquí stackoverflow.com/questions/12131068/…
Lem

Para mí, resultó que no necesitaba convertirme. Había un import java.sql.*en mi código, anulando el java.util.date y causando problemas al asignar valores de fecha que estaban bien con el último pero no con el primero. HTH
HumanInDisguise

1
@DavidAckerman ¿Entiende que un java.util.Date es una fecha y una hora del día, pero un java.sql.Date es solo una fecha sin una hora del día? (En realidad, hay una hora del día, pero eso se ignora, un mal truco de un diseño de clase) En SQL, DATEsignifica solo fecha.
Basil Bourque

2
De hecho, no estaba al tanto de los matices en el '09, y dado que esta pregunta es tan popular, he cambiado la respuesta aceptada a una que es más moderna y completa. ¡Gracias a todos por sus comentarios!
David Ackerman

Respuestas:


89

tl; dr

¿Cómo convertir java.util.Date a java.sql.Date?

No lo hagas Ambas clases están pasadas de moda.

  • Utilice las clases java.time en lugar de heredadas java.util.Datey java.sql.Datecon JDBC 4.2 o posterior.
  • Convierta a / desde java.time si interopera con código que aún no se ha actualizado a java.time.

Ejemplo de consulta con 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.
)

Reemplazos:

  • Instanten lugar de java.util.Date
    Ambos representan un momento en UTC. pero ahora con nanosegundos en lugar de milisegundos.
  • LocalDateen lugar de java.sql.Date
    Ambos representan un valor de solo fecha sin hora del día y sin zona horaria.

Detalles

Si está intentando trabajar con valores de solo fecha (sin hora del día, sin zona horaria), use la LocalDateclase en lugar de java.util.Date.

Tabla de tipos de fecha y hora en Java (tanto heredados como modernos) y en el estándar SQL.

java.time

En Java 8 y versiones posteriores, el nuevo paquete java.time ha suplantado las viejas clases problemáticas de fecha y hora agrupadas con versiones anteriores de Java . Vea el tutorial de Oracle . Gran parte de la funcionalidad se ha transferido a Java 6 y 7 en ThreeTen-Backport y se ha adaptado aún más a Android en ThreeTenABP .

Un tipo de datos SQL DATE está destinado a ser solo de fecha, sin hora del día ni zona horaria. Java nunca tuvo precisamente esa clase † hasta java.time.LocalDateen Java 8. Creemos ese valor obteniendo la fecha de hoy de acuerdo con una zona horaria particular (la zona horaria es importante para determinar una fecha como un nuevo día amanece más temprano en París que en Montreal, para ejemplo).

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

En este punto, podemos haber terminado. Si su controlador JDBC cumple con la especificación JDBC 4.2 , debería poder pasar una LocalDatevía setObjecten una PreparedStatementpara almacenar en un campo FECHA SQL.

myPreparedStatement.setObject( 1 , localDate );

Del mismo modo, use ResultSet::getObjectpara buscar desde una columna FECHA SQL a un LocalDateobjeto Java . Especificar la clase en el segundo argumento hace que su código sea seguro .

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

En otras palabras, toda esta pregunta es irrelevante en JDBC 4.2 o posterior.

Si su controlador JDBC no funciona de esta manera, debe recurrir a la conversión a los tipos java.sql.

Convertir a java.sql.Date

Para convertir, use nuevos métodos agregados a las antiguas clases de fecha y hora. Podemos llamar java.sql.Date.valueOf(…)para convertir a LocalDate.

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

Y yendo en la otra dirección.

LocalDate localDate = sqlDate.toLocalDate();

Convertir de java.util.Date

Si bien debe evitar el uso de las antiguas clases de fecha y hora, puede verse obligado a hacerlo cuando trabaje con el código existente. Si es así, puede convertir a / desde java.time.

Ir a través de la Instantclase, que representa un momento en la línea de tiempo en UTC. An Instantes similar en idea a a java.util.Date. Pero tenga en cuenta que Instanttiene una resolución de hasta nanosegundos, mientras que java.util.Datesolo tiene una resolución de milisegundos .

Para convertir, use nuevos métodos agregados a las clases antiguas. Por ejemplo, java.util.Date.from( Instant )y java.util.Date::toInstant.

Instant instant = myUtilDate.toInstant();

Para determinar una fecha, necesitamos el contexto de una zona horaria. Para cualquier momento, la fecha varía en todo el mundo por zona horaria. Aplica a ZoneIdpara obtener a ZonedDateTime.

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

† La clase java.sql.Date pretende ser solo de fecha sin una hora del día, pero en realidad hace una hora del día, ajustada a la medianoche. ¿Confuso? Sí, las antiguas clases de fecha y hora son un desastre.


Sobre java.time

El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases suplantar la vieja problemáticos heredados clases de fecha y hora como java.util.Date, Calendar, y SimpleDateFormat.

El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .

Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .

Puede intercambiar objetos java.time directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No hay necesidad de cadenas, no hay necesidad de java.sql.*clases.

¿Dónde obtener las clases java.time?

Tabla de qué biblioteca java.time usar con qué versión de Java o Android

El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Usted puede encontrar algunas clases útiles aquí, como Interval, YearWeek, YearQuarter, y más .


478

No importa....

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

  }

}

lo explica El enlace es http://www.java2s.com/Tutorial/Java/0040__Data-Type/ConvertfromajavautilDateObjecttoajavasqlDateObject.htm


34
¡Esta no es una conversión explícita! Del Javadoc: "Si el valor de milisegundos dado contiene información de hora, el controlador establecerá los componentes de hora en la zona horaria predeterminada (la zona horaria de la máquina virtual Java que ejecuta la aplicación) que corresponde a cero GMT". Entonces, no importa cuál sea su tiempo en su java.util.Date, se insertará como 00:00:00 en una columna con el tipo de datos establecido en DATE.

1
@David Ackerman ..... este método devuelve, epochsecondses decir, milisegundos después 1,JAN,1970. Pero ¿qué pasa si queremos almacenar la fecha de una persona antes de esta fecha ... o algo así?0000-00-00 as default
Arjun KP

31
En mi caso, la respuesta correcta es <code> java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp (utilDate.getTime ()); </code>, porque conserva los campos de tiempo.
Alberto de Paola

2
@ wired00 Sí, las antiguas clases de fecha y hora incluidas con las primeras versiones de Java son un desastre , mal diseñadas, incluidos algunos hacks burdos. Siempre que sea posible, intente utilizar el nuevo marco java.time en Java 8 y versiones posteriores. Estas nuevas clases suplantan a las viejas. Las clases java.time y las clases antiguas tienen algunos métodos convenientes para la conversión de ida y vuelta, útil mientras esperamos que los controladores JDBC se actualicen para utilizar directamente los nuevos tipos java.time.
Basil Bourque

1
@ wired00 Vea mi nueva respuesta a esta pregunta sobre cómo usar java.time. También busque en StackOverflow muchos más ejemplos.
Basil Bourque

39

Con la otra respuesta, puede tener problemas con la información del tiempo (¡compare las fechas con resultados inesperados!)

Yo sugiero:

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

55
Si usa java.sql.Date para una columna Fecha en una base de datos, esa información de tiempo se truncará. Usted ha modificado la solución en mi opinión.
darioo

44
Sí, tal vez lo hice. A veces necesito comparar java.sql.Data con la fecha actual y, en mi opinión, esta es la mejor manera. Espero que pueda ayudar.
mauretto

Para su información, las antiguas clases de fecha y hora terriblemente problemáticas como java.util.Date, java.util.Calendary java.text.SimpleDateFormatahora son heredadas , suplantadas por las clases java.time integradas en Java 8 y posteriores. Ver Tutorial de Oracle .
Basil Bourque

Por supuesto, este tema fue hace unos 10 años, antes de Java 8.
mauretto

26

Esta función devolverá una fecha SQL convertida del objeto de fecha java.

public java.sql.Date convertJavaDateToSqlDate(java.util.Date date) {
    return new java.sql.Date(date.getTime());
}

18

La conversión java.util.Dataa java.sql.Dataperderá horas, minutos y segundos. Entonces, si es posible, le sugiero que use java.sql.Timestampasí:

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

Para más información, puede consultar esta pregunta .


16

En mi caso de elegir la fecha de JXDatePicker (calendario de Java) y almacenarla en la base de datos como tipo de fecha SQL, a continuación funciona bien.

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

donde pickDate es objeto de JXDatePicker


5

Esta función devolverá una fecha SQL convertida del objeto de fecha 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;
    }

3

Formatee su fecha java.util.Date primero. Luego use la fecha formateada para obtener la fecha en 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);

2

Aquí el ejemplo de convertir Util Date a Sql date y este es un ejemplo de lo que estoy usando en mi proyecto también podría serle útil.

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)

2

Soy un novato: después de mucho correr esto funcionó. El pensamiento puede ser útil.

     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

Para su información, las antiguas clases de fecha y hora terriblemente problemáticas como java.util.Date, java.util.Calendary java.text.SimpleDateFormatahora son heredadas , suplantadas por las clases java.time integradas en Java 8 y posteriores. Ver Tutorial de Oracle .
Basil Bourque

2
java.sql.Date sqlDate = new java.sql.Date(javaDate.getTime());

Aquí javaDate es la instancia de java.util.Date


1
Realmente no parece agregar nada nuevo en comparación con las respuestas de David Ackerman, Chetan y Tanmay Kumar Shaw, ¿verdad?
Ole VV

1

Método para comparar 2 fechas (util.date o 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;
}

0

prueba con esto

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;
}

-1

Creo que la mejor manera de convertir es:

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 desea insertar la dtvariable en una tabla SQL, puede hacer:

insert into table (expireAt) values ('"+dt+"');

1
Esto parece ser esencialmente lo mismo que esta respuesta publicada un año antes.
Bernhard Barker, el

-3

Estoy usando el siguiente código, pruébalo

DateFormat fm= new SimpleDateFormatter();

especifique el formato de la fecha que desea, por ejemplo, "DD-MM_YYYY"o 'YYYY-mm-dd' luego use el tipo de datos Java Date como

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

entonces analizará tu fecha


-3

Puede usar este método para convertir la fecha de utilidad a la fecha sql,

DateUtilities.convertUtilDateToSql(java.util.Date)

No hay una clase DateUtilities en la biblioteca Java estándar (y ni siquiera puedo encontrar este método en ninguna parte de una búsqueda rápida en Google). Si esto es de una biblioteca específica, es posible que desee decir tanto e incluir un enlace a los documentos.
Bernhard Barker, el

-4

Estaba intentando la siguiente codificación que funcionó bien.

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


-8

Si está usando MySQL, una columna de fecha puede pasar una representación de cadena de esta fecha

así que uso la clase DateFormatter para formatearlo y luego configurarlo como una cadena en la instrucción sql o declaración preparada

Aquí está la ilustración del código:

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

Fecha de cadena = converUtilDateToSqlDate (otherTransaction.getTransDate ());

// luego pasa esta fecha en tu declaración sql


14
Bienvenido a stackoverflow, tengo algunos comentarios a su respuesta. La pregunta era "cómo convertir un java.util.Date a java.sql.Date". El código que pegó formatea una fecha java.util.Date como aaaa-MM-dd. En realidad, esto es de uso limitado en este contexto, ya que debe pasar el java.sql.Date directamente a los controladores jdbc en lugar de hacerlo como una cadena.
jontro
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.