Marca de tiempo de Java: ¿cómo puedo crear una marca de tiempo con la fecha 23/09/2007?

Respuestas:

154

Por Timestamp, supongo que quieres decir java.sql.Timestamp. Notarás que esta clase tiene un constructor que acepta un longargumento. Puedes analizar esto usando la DateFormatclase:

DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date date = dateFormat.parse("23/09/2007");
long time = date.getTime();
new Timestamp(time);
Adam Paynter
fuente
1
El formato de fecha ISO normal es aaaa-MM-dd; de lo contrario, ¡genial!
vidstige
1
nueva marca de tiempo (hora); dando el error de que ningún constructor como este toma un valor largo :(
Bhanu Sharma
1
@Bhanu Los documentos muestran que esto toma un valor largo y parece funcionar correctamente: docs.oracle.com/javase/7/docs/api/java/sql/…
Hazok
Para su información, las clases de fecha y hora antiguas 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 versiones posteriores. Consulte el tutorial de Oracle .
Basil Bourque
121

¿Qué pasa con esto?

java.sql.Timestamp timestamp = java.sql.Timestamp.valueOf("2007-09-23 10:10:10.0");
pigouina
fuente
1
Timestamp timestamp = Timestamp.valueOf ("2007-09-23 10: 10: 10.0"); muestra que el método valueOf no está definido para el tipo Timestamp en jDK 7
Ashish Ratan
nueva marca de tiempo (hora); dando el error de que ningún constructor como este toma un valor de cadena :(
Bhanu Sharma
@Bhanu El constructor toma el tiempo de Unix en milisegundos. Utilice el método estático valueOf si desea obtener una marca de tiempo de una cadena.
Hazok
4
Esta parece ser la mejor respuesta a la pregunta.
Hazok
1
La mejor respuesta tiene Date, que está obsoleta, es una mala práctica usarla. Esta respuesta es mejor. Gracias
Alberici
18

¿Qué quieres decir con la marca de tiempo? Si te refieres a milisegundos desde la época de Unix:

GregorianCalendar cal = new GregorianCalendar(2007, 9 - 1, 23);
long millis = cal.getTimeInMillis();

Si desea un objeto java.sql.Timestamp real:

Timestamp ts = new Timestamp(millis);
Matthew Flaschen
fuente
2
INCORRECTO y no se compilará. Error de compilación: 09 es un número octal, pero 9 está fuera del rango de los octales. Error de lógica: el mes está basado en 0, obtendrá el 23 de OCTUBRE de 2007
user85421
No puedo obtener un error lógico si no se compila. :) En serio, buenas capturas, Carlos. El octal lo atrapé antes pero pegué mal de todos modos. :(
Matthew Flaschen
En realidad, el constructor de marca de tiempo está depurado en lugar de que pueda usar el método Timestamp.valueOf ()
Shiva Komuravelly
@ShivaKomuravelly, no todos los constructores de marca de tiempo están en desuso y al menos no, lo que toma tanto como milisegundos, el constructor que toma la fecha como argumento está en desuso
sin nombre
Y hay una constante para eso (en lugar de mes = 9):Calendar.SEPTEMBER
Guillaume Husta
11

tl; dr

java.sql.Timestamp.from (
    LocalDate.of ( 2007 , 9 , 23 )
             .atStartOfDay( ZoneId.of ( "America/Montreal" ) )
             .toInstant()
)

java.time

Actualicemos esta página mostrando el código usando java.time marco integrado en Java 8 y posteriores.

Estas nuevas clases están inspiradas en Joda-Time , definida por JSR 310 y ampliada por ThreeTen-Extra proyecto . Sustituyen a las antiguas clases de fecha y hora notoriamente problemáticas incluidas con las primeras versiones de Java.

En java.time, an Instantes un momento en la línea de tiempo en UTC. A ZonedDateTimees un Instant ajustado a una zona horaria ( ZoneId).

La zona horaria es crucial aquí. Una fecha deSeptember 23, 2007 no se puede traducir a un momento en la línea de tiempo sin aplicar una zona horaria. Considere que un nuevo día amanece antes en París que en Montreal, donde todavía es “ayer”.

Además, un java.sql.Timestamp representa tanto una fecha como una hora del día. Por lo tanto, debemos inyectar una hora del día para que coincida con la fecha. Suponemos que desea que el primer momento del día sea la hora del día. Tenga en cuenta que este no es siempre el momento00:00:00.0 debido al horario de verano y posiblemente a otras anomalías.

Tenga en cuenta que, a diferencia de la antigua clase java.util.Date, y a diferencia de Joda-Time, los tipos java.time tienen una resolución de nanosegundos en lugar de milisegundos. Esto coincide con la resolución de java.sql.Timestamp.

Tenga en cuenta que java.sql.Timestamp tiene la mala costumbre de aplicar implícitamente la zona horaria predeterminada actual de su JVM a su valor de fecha y hora al generar una representación de cadena a través de su toStringmétodo. Aquí puede ver mi America/Los_Angeleszona horaria aplicada. Por el contrario, las clases java.time son más sensatas, utilizando el estándar ISO 8601 formatos .

LocalDate d = LocalDate.of ( 2007 , 9 , 23 ) ;
ZoneId z = ZoneId.of ( "America/Montreal" ) ;
ZonedDateTime zdt = d.atStartOfDay( z ) ;
Instant instant = zdt.toInstant() ;
java.sql.Timestamp ts = java.sql.Timestamp.from ( instant ) ;

Volcar a la consola.

System.out.println ( "d: " + d + " = zdt: " + zdt + " = instant: " + instant + " = ts: " + ts );

Cuando se ejecuta.

d: 2007-09-23 = zdt: 2007-09-23T00: 00-04: 00 [America / Montreal] = instant: 2007-09-23T04: 00: 00Z = ts: 2007-09-22 21:00: 00.0

Por cierto, a partir de JDBC 4.2, puede usar los tipos java.time directamente. No es necesario java.sql.Timestamp.

  • PreparedStatement.setObject
  • ResultSet.getObject

Acerca de 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 se necesitan cuerdas, no se necesitan java.sql.*clases.

¿Dónde obtener las clases java.time?

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 .

Albahaca Bourque
fuente
3
Me pregunto cómo puedo hacer que OP o mods marquen su respuesta como la correcta. La respuesta aceptada está tan desactualizada.
sttaq
Muy bonito, excepto por un error tipográfico. asStartOfDay () debe ser atStartOfDay ().
Tullochgorum
@Tullochgorum fijo. Gracias. Para su información, en Stack Overflow, puede realizar esas ediciones usted mismo, si así lo desea.
Basil Bourque
5

También puede hacer lo siguiente:

// untested
Calendar cal = GregorianCalendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 23);// I might have the wrong Calendar constant...
cal.set(Calendar.MONTH, 8);// -1 as month is zero-based
cal.set(Calendar.YEAR, 2009);
Timestamp tstamp = new Timestamp(cal.getTimeInMillis());
Alex
fuente
2
INCORRECTO: pruebe un System.out.println del resultado. Obtendrá algo como: "2009-10-23 15: 26: 56.171" El mes se basa en 0, por lo que el 9 es octubre.
user85421
Sabía que una de esas constantes estaba basada en cero, gracias. Publicación actualizada.
Alex
1
Ah, y puse 'no probado' :)
Alex
4

Según la API, el constructor que aceptaría año, mes, etc. está obsoleto. En su lugar, debe usar el Constructor que acepta un archivo. Puede usar una implementación de Calendario para construir la fecha que desee y acceder a la representación de tiempo como un largo, por ejemplo, con el método getTimeInMillis .

Philipp
fuente
1

En aras de la integridad, también una solución con Joda-Time versión 2.5 y su DateTimeclase:

new Timestamp(new DateTime(2007, 9, 23, 0, 0, DateTimeZone.forID( "America/Montreal" )).getMillis())
usuario152468
fuente
1
Buena respuesta, pero te perdiste una pieza crucial : la zona horaria . Si omite una zona horaria, la zona horaria predeterminada actual de la JVM se aplica al DateTimeobjeto. Eso significa que sus resultados variarán entre varias computadoras o la configuración del sistema operativo host o la configuración de JVM. Para obtener resultados predecibles, pase una zona horaria a ese DateTimeconstructor. Elija el nombre de la zona horaria adecuada para su intención. Por ejemplo, DateTimeZone.forID( "America/Montreal" )o DateTimeZone.UTC.
Basil Bourque
Ese código podría ser más breve. No es necesario convertir a java.util.Date para obtener y pasar milisegundos desde época . Pregúntele al DateTimeobjeto sus milisegundos desde la época. Reemplazar .toDate().getTime()con .getMillis().
Basil Bourque
@BasilBourque Dependiendo de las circunstancias, es posible que desee omitir la zona horaria para obtener resultados predecibles. "En su zona horaria actual" puede ser un resultado perfectamente razonable y predecible. ¿Por qué codificar una zona horaria o pedirles a los usuarios que configuren manualmente una zona horaria cuando su computadora ya tiene una zona horaria configurada? Ciertamente, me sorprendería bastante si una aplicación en mi computadora comenzara a generar fechas ajustadas a la zona horaria de América / Montreal.
dan carter
@dancarter Omitir la zona horaria opcional genera confusión. La omisión plantea la ambigüedad de (a) si el programador pretendía confiar en el valor predeterminado implícito o (b) si el programador no consideró los problemas de la zona horaria (como es demasiado común). Si realmente desea utilizar la zona horaria predeterminada actual de la JVM, dígalo explícitamente llamando DateTimeZone.getDefault()y pasando el resultado como argumento opcional. (Por cierto, lo mismo ocurre con el Locale.getDefault()mismo problema sobre la ambigüedad de los argumentos opcionales.)
Basil Bourque
-1

Una respuesta más general sería importar java.util.Date, luego, cuando necesite establecer un timestampigual a la fecha actual, simplemente configúrelo igual a new Date().

CSquid
fuente
porque ** Fecha ("cadena"); ** está en desuso
Ashish Ratan