with specific settimezone manejo horas example ejemplo create convert change java sql date timestamp

specific - localdate java example



Fecha Java e IndicaciĆ³n de fecha y hora desde el instante de ZonedDateTime UTC (2)

Tengo una aplicación Java en la que me gustaría tener la hora en UTC. Actualmente, el código usa una mezcla de java.util.Date y java.sql.Timestamp . Para obtener el tiempo en UTC, el programador antes que yo utilizó:

Por Fecha:

Date.from(ZonedDateTime.now(ZoneOffset.UTC)).toInstant();

Para Timestamp:

Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());

Sin embargo, he realizado múltiples pruebas con este código y ambas líneas devuelven la fecha / hora actual (en mi zona horaria actual). De todo lo que he leído, parece que Date / Timestamp no tiene un valor zoneOffset, pero no puedo encontrar una declaración concreta de esto.

¿Hay alguna forma de mantener la zona horaria (UTC) dentro de los objetos de Fecha u Hora, o necesito hacer alguna refactorización y usar el objeto ZonedDateTime actual en toda mi aplicación? ¿Este objeto ZonedDateTime también será compatible con el objeto Timestamp actual para sql?

Ejemplo:

public static void main (String args[]) { ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC); Timestamp timestamp = Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant()); Date date = Date.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant()); System.out.println("ZonedDateTime: " + zonedDateTime); System.out.println("Timestamp: " + timestamp); System.out.println("Date: " + date); }

Salida:

ZonedDateTime: 2017-04-06T15:46:33.099Z Timestamp: 2017-04-06 10:46:33.109 Date: Thu Apr 06 10:46:33 CDT 2017


En Java, Date representa un punto en el tiempo. No está relacionado con la marca de tiempo. Cuando llama al método toString() de un objeto Date , lo convierte a la marca de tiempo predeterminada de Platform, por ejemplo, Following imprimirá la fecha / hora en UTC (ya que establece la zona horaria predeterminada en UTC):

TimeZone.setDefault(TimeZone.getTimeZone("UTC")); ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC); Timestamp timestamp = Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant()); Date date = Date.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant()); System.out.println("ZonedDateTime: " + zonedDateTime); System.out.println("Timestamp: " + timestamp); System.out.println("Date: " + date);


Usando java.time

El programador antes que usted estaba haciendo uso de las nuevas clases modernas de java.time que ahora suplantan a las viejas y legadas clases de fecha y hora heredadas como Date , Calendar , Timestamp .

Instant

La clase Instant representa un momento en la línea de tiempo en UTC con una resolución de nanosegundos (hasta nueve (9) dígitos de una fracción decimal). Para obtener el momento actual en UTC es completamente simple: Instant.now .

Instant instant = Instant.now();

Mudado

Debes mantenerte en las clases java.time y evitar las clases heredadas. Pero si es absolutamente necesario, como la interfaz con el código anterior aún no actualizado para java.time, puede convertir a / desde java.time. Busque nuevos métodos en clases antiguas. El equivalente de la clase heredada java.util.Date es Instant .

java.util.Date d = java.util.Date.from( myInstant); // To legacy from modern. Instant instant = myJavaUtilDate.toInstant(); // To modern from legacy.

JDBC

Evite las clases heredadas de fecha y hora. Use clases java.time en su lugar.

El controlador compatible con JDBC 4.2 puede direccionar directamente los tipos java.time llamando a PreparedStatement::setObject y ResultSet::getObject .

myPreparedStatement.setObject( … , instant ) ;

... y ...

Instant instant = myResultSet.getObject( … , Instant.class ) ;

De lo contrario, vuelva a utilizar los tipos java.sql, pero lo más brevemente posible. Use nuevos métodos de conversión agregados a las clases antiguas.

myPreparedStatement.setTimestamp( … , java.sql.Timestamp.from( instant ) ) ;

... y ...

Instant instant = myResultSet.getTimestamp( … ).toInstant() ;

No es necesario ZonedDateTime

Tenga en cuenta que no teníamos necesidad de su ZonedDateTime mencionado ya que dijo que solo estaba interesado en UTC. Los objetos Instant están siempre en UTC. Eso significa que el código original que citó:

Date.from(ZonedDateTime.now(ZoneOffset.UTC)).toInstant();

... podría simplemente haberse acortado a:

Date.from( Instant.now() ;

Tenga en cuenta que java.util.Date está siempre en UTC. Sin embargo, lamentablemente, toString aplica la zona horaria predeterminada actual de la JVM implícitamente al generar la cadena. Esta anti-característica crea confusión sin fin, como puede ver al buscar en Desbordamiento de pila.

Si desea ver el valor UTC de su objeto Instant través del objetivo de la hora del reloj de pared de una región, asigne un ZoneId zona ZoneId para obtener un ZoneDateTime .

Especifique un nombre de zona horaria adecuada en el formato continent/region , como America/Montreal , Africa/Casablanca o Pacific/Auckland . Nunca utilice la abreviatura de 3-4 letras, como CDT o EST o IST ya que no son zonas horarias verdaderas, no están estandarizadas y ni siquiera son únicas (!).

ZoneId z = ZoneId.of( "America/Chicago" ); ZonedDateTime zdt = instant.atZone( z );

Acerca de java.time

El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las problemáticas antiguas clases heredadas 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 para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .

¿Dónde obtener las clases de java.time?

  • Java SE 8 y SE 9 y posteriores
    • Incorporado.
    • Parte de la API Java estándar con una implementación integrada.
    • Java 9 agrega algunas características y correcciones menores.
  • Java SE 6 y SE 7
    • Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
  • Androide
    • El proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente) específicamente para Android.
    • Consulte Cómo utilizar ThreeTenABP ....

El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval , YearWeek , YearQuarter y más .