¿Cómo configurar la zona horaria de java.util.Date?

Resuelto Amit asked hace 14 años • 11 respuestas

He analizado a java.util.Datedesde a Stringpero está configurando la zona horaria local como la zona horaria del dateobjeto.

La zona horaria no se especifica en el Stringorigen desde el que Datese analiza. Quiero establecer una zona horaria específica del dateobjeto.

¿Cómo puedo hacer eso?

Amit avatar May 23 '10 17:05 Amit
Aceptado

Utilice formato de fecha. Por ejemplo,

SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = isoFormat.parse("2010-05-23T09:01:02");
ZZ Coder avatar May 23 '2010 10:05 ZZ Coder

Tenga en cuenta que java.util.Datelos objetos no contienen información de zona horaria por sí mismos; no puede establecer la zona horaria en un Dateobjeto. Lo único que Datecontiene un objeto es una cantidad de milisegundos desde la "época": el 1 de enero de 1970, 00:00:00 UTC.

Como muestra ZZ Coder, usted configura la zona horaria en el DateFormatobjeto para indicarle en qué zona horaria desea mostrar la fecha y la hora.

Jesper avatar May 23 '2010 14:05 Jesper

tl; dr

…analizado… desde una cadena… la zona horaria no está especificada… Quiero establecer una zona horaria específica

LocalDateTime.parse( "2018-01-23T01:23:45.123456789" )  // Parse string, lacking an offset-from-UTC and lacking a time zone, as a `LocalDateTime`.
    .atZone( ZoneId.of( "Africa/Tunis" ) )              // Assign the time zone for which you are certain this date-time was intended. Instantiates a `ZonedDateTime` object.

No hay zona horaria en juDate

Como indicaron las otras respuestas correctas, java.util.Date no tiene zona horaria . Representa UTC /GMT (sin desplazamiento de zona horaria). Muy confuso porque su toStringmétodo aplica la zona horaria predeterminada de la JVM al generar una representación de cadena.

Evite la cita judaica

Por esta y muchas otras razones, debe evitar el uso de java.util.Date & .Calendar & java.text.SimpleDateFormat integrados. Son notoriamente problemáticos.

En su lugar, utilice el paquete java.time incluido con Java 8 .

java.tiempo

Las clases java.time pueden representar un momento en la línea de tiempo de tres maneras:

  • UTC ( Instant)
  • Con un desplazamiento ( OffsetDateTimecon ZoneOffset)
  • Con zona horaria ( ZonedDateTimecon ZoneId)

Instant

En java.time , el componente básico es Instantun momento en la línea de tiempo en UTC. Utilice Instantobjetos para gran parte de su lógica empresarial.

Instant instant = Instant.now();

OffsetDateTime

Aplique un desplazamiento desde UTC para ajustarse a la hora del reloj de pared de alguna localidad .

Aplique a ZoneOffsetpara obtener un OffsetDateTime.

ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );

ZonedDateTime

Mejor es aplicar una zona horaria , un desplazamiento más las reglas para manejar anomalías como el horario de verano (DST) .

Aplique a ZoneIda an Instantpara obtener un ZonedDateTime. Especifique siempre un nombre de zona horaria adecuado . Nunca utilice 3 o 4 abreviaturas como ESTo ISTque no sean únicas ni estandarizadas.

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

LocalDateTime

Si la cadena de entrada carecía de algún indicador de desplazamiento o zona, analícela como un archivo LocalDateTime.

Si está seguro de la zona horaria deseada, asigne un ZoneIdpara producir un archivo ZonedDateTime. Vea el ejemplo de código anterior en la sección tl;dr en la parte superior.

Cadenas formateadas

Llame al toStringmétodo en cualquiera de estas tres clases para generar una cadena que represente el valor de fecha y hora en el formato estándar ISO 8601 . La ZonedDateTimeclase amplía el formato estándar añadiendo el nombre de la zona horaria entre paréntesis.

String outputInstant = instant.toString(); // Ex: 2011-12-03T10:15:30Z
String outputOdt = odt.toString(); // Ex: 2007-12-03T10:15:30+01:00
String outputZdt = zdt.toString(); // Ex: 2007-12-03T10:15:30+01:00[Europe/Paris]

Para otros formatos utilice la DateTimeFormatterclase. Generalmente es mejor dejar que esa clase genere formatos localizados utilizando el lenguaje humano y las normas culturales esperados del usuario. O puede especificar un formato particular.


Tabla de todos los tipos de fecha y hora en Java, tanto modernos como heredados


Acerca de java.time

El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases reemplazan a las antiguas y problemáticas clases de fecha y hora heredadas , como java.util.Date, Calendary SimpleDateFormat.

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 .

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

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. Hibernate 5 y JPA 2.2 admiten java.time .

¿Dónde obtener las clases java.time?

  • Java SE 8 , Java SE 9 , Java SE 10 , Java SE 11 y posteriores: parte de la API de Java estándar con una implementación incluida.
    • Java 9 trajo algunas características y correcciones menores.
  • Java SE 6 y Java SE 7
    • La mayor parte de la funcionalidad java.time está adaptada a Java 6 y 7 en ThreeTen-Backport .
  • Androide
    • Versiones posteriores de implementaciones de paquetes de Android (26+) de las clases java.time .
    • Para Android anterior (<26), un proceso conocido como eliminación de azúcar de API aporta un subconjunto de la funcionalidad java.time que no estaba integrada originalmente en Android.
      • Si el desazucar no ofrece lo que necesitas, el proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente) a Android. Consulte Cómo utilizar ThreeTenABP… .

Tiempo Joda

Si bien Joda-Time todavía se mantiene activamente, sus creadores nos han dicho que migremos a java.time tan pronto como sea conveniente. Dejo esta sección intacta como referencia, pero sugiero usar la java.timesección anterior en su lugar.

En Joda-Time , un objeto de fecha y hora ( DateTime) realmente conoce su zona horaria asignada. Eso significa una desviación de UTC y las reglas y el historial del horario de verano (DST) de esa zona horaria y otras anomalías similares.

String input = "2014-01-02T03:04:05";
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( input, timeZone );
DateTime dateTimeUtcGmt = dateTimeIndia.withZone( DateTimeZone.UTC );

Llame al toStringmétodo para generar una cadena en formato ISO 8601 .

String output = dateTimeIndia.toString();

Joda-Time también ofrece amplias capacidades para generar todo tipo de formatos de cadenas.

Si es necesario, puede convertir de Joda-Time DateTime a java.util.Date.

Java.util.Date date = dateTimeIndia.toDate();

Busque en StackOverflow "joda date" para encontrar muchos más ejemplos, algunos bastante detallados.


En realidad , hay una zona horaria integrada en java.util.Date, que se utiliza para algunas funciones internas (consulte los comentarios en esta respuesta). Pero esta zona horaria interna no está expuesta como una propiedad y no se puede configurar. Esta zona horaria interna no es la que utiliza el toStringmétodo para generar una representación de cadena del valor de fecha y hora; en su lugar, la zona horaria predeterminada actual de la JVM se aplica sobre la marcha. Entonces, como abreviatura, solemos decir "juDate no tiene zona horaria". ¿Confuso? Sí. Otra razón más para evitar estas viejas y cansadas clases.

Basil Bourque avatar Mar 02 '2014 10:03 Basil Bourque

También puedes configurar la zona horaria a nivel de JVM.

Date date1 = new Date();
System.out.println(date1);

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
// or pass in a command line arg: -Duser.timezone="UTC"

Date date2 = new Date();
System.out.println(date2);

producción:

Thu Sep 05 10:11:12 EDT 2013
Thu Sep 05 14:11:12 UTC 2013
starmer avatar Sep 05 '2013 14:09 starmer