tl; dr
- Uso java.time clases en lugar de legado
java.util.Date
& java.sql.Date
con JDBC 4.2 o posterior.
- Convierta a/desde java.time si está funcionando con código aún no actualizado a java.time.
Consulta de ejemplo 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.
)
detalles
Si usted está tratando de trabajar con valores de fecha de sólo (no, no zona horaria de hora del día), utilice la clase LocalDate
en lugar de java.util.Date
.
java.time
En Java 8 y versiones posteriores, las clases de fecha y hora viejas problemáticas que vienen con las primeras versiones de Java han sido suplantada por la nueva java.time package. Ver Oracle Tutorial. Gran parte de la funcionalidad se ha retrotraído a Java 6 & 7 en ThreeTen-Backport y adaptada a Android en ThreeTenABP.
A SQL data typeDATE
está destinado a ser solo de fecha, sin hora del día ni zona horaria. Java nunca tuvo precisamente dicha clase † hasta el java.time.LocalDate
en Java 8. Creemos ese valor obteniendo la fecha de hoy de acuerdo con un huso horario particular (la zona horaria es importante para determinar una fecha como un nuevo día amanece antes en París que en Montreal, por 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 estar listos. Si su JDBC driver cumple con JDBC 4.2 spec, debe poder pasar un LocalDate
a través de setObject
en un PreparedStatement
para almacenar en un campo de FECHA SQL.
myPreparedStatement.setObject(1 , localDate);
mismo modo, utilizar ResultSet::getObject
a buscar a partir de una columna FECHA SQL a un LocalDate
objeto Java. Al especificar la clase en el segundo argumento, aparece el código type-safe.
LocalDate localDate = ResultSet.getObject(1 , LocalDate.class);
En otras palabras, toda esta pregunta es irrelevante bajo 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, utilizan los nuevos métodos añadidos a las clases de fecha y hora de edad. Podemos llamar al java.sql.Date.valueOf(…)
para convertir un LocalDate
.
java.sql.Date sqlDate = java.sql.Date.valueOf(todayLocalDate);
Y yendo en la otra dirección.
LocalDate localDate = sqlDate.toLocalDate();
La conversión de java.util.Date
Mientras que usted debe evitar el uso de las clases de fecha y hora de edad, se verá forzado a la hora de trabajar con el código existente. Si es así, puede convertir a/desde java.time.
Pase por la clase Instant
, que representa un momento en la línea de tiempo en UTC. Un Instant
es similar en idea a un java.util.Date
. Pero tenga en cuenta que Instant
tiene una resolución de hasta nanoseconds, mientras que java.util.Date
tiene solo milliseconds de resolución.
Para convertir, use los métodos nuevos 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 dado, la fecha varía alrededor del mundo por zona horaria. Aplique un ZoneId
para obtener un ZonedDateTime
.
ZoneId zoneId = ZoneId.of ("America/Montreal");
ZonedDateTime zdt = ZonedDateTime.ofInstant (instant , zoneId);
LocalDate localDate = zdt.toLocalDate();
† La clase java.sql.Date pretende ser de sólo fecha sin la hora del día, pero en realidad hace una hora del día, ajustado a un tiempo la medianoche. ¿Confuso? Sí, las viejas clases de fecha y hora son un desastre.
se puede encontrar un problema similar aquí http://stackoverflow.com/questions/12131068/error-casting-java-util-date -into-java-sql-date – Lem
Para mí, resultó que no necesitaba convertir. Había un 'import java.sql. *' En mi código, anulando java.util.date y causando problemas al asignar valores de fecha que estaban bien con este último pero no con el primero. HTH – HumanInDisguise
@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 truco defectuoso de un diseño de clase). En SQL, 'DATE' significa fecha solamente. –