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.
Sin zona horaria en juDate
Como indicaron las otras respuestas correctas, un java.util.Date no tiene zona horaria † . Representa UTC / GMT (sin desplazamiento de zona horaria). Muy confuso porque su toString
método aplica la zona horaria predeterminada de la JVM al generar una representación de cadena.
Evite el juDate
Por esta y muchas otras razones, debe evitar usar el java.util.Date & .Calendar & java.text.SimpleDateFormat incorporado. Son notoriamente problemáticos.
En su lugar, use el paquete java.time incluido con Java 8 .
java.time
Las clases java.time pueden representar un momento en la línea de tiempo de tres maneras:
- UTC (
Instant
)
- Con un desplazamiento (
OffsetDateTime
con ZoneOffset
)
- Con una zona horaria (
ZonedDateTime
con ZoneId
)
Instant
En java.time , el elemento básico es Instant
un momento en la línea de tiempo en UTC. Use Instant
objetos para gran parte de su lógica empresarial.
Instant instant = Instant.now();
OffsetDateTime
Aplique un desplazamiento desde UTC para ajustar la hora del reloj de pared de alguna localidad .
Aplica un ZoneOffset
para obtener un OffsetDateTime
.
ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
Es mejor aplicar una zona horaria , un desplazamiento más las reglas para manejar anomalías como el horario de verano (DST) .
Aplica una ZoneId
a una Instant
para obtener una ZonedDateTime
. Siempre especifique un nombre de zona horaria adecuado . Nunca use 3-4 abreviaturas como EST
o IST
que 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, analice como a LocalDateTime
.
Si está seguro de la zona horaria prevista, asigne a ZoneId
para producir a ZonedDateTime
. Vea el ejemplo de código anterior en la sección tl; dr en la parte superior.
Cadenas formateadas
Llame al toString
mé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 ZonedDateTime
clase extiende el formato estándar agregando 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, use la DateTimeFormatter
clase. En general, es mejor dejar que esa clase genere formatos localizados utilizando el lenguaje humano y las normas culturales esperadas por el usuario. O puede especificar un formato particular.
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?
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 .
Joda-Time
Si bien Joda-Time aún 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.time
sección anterior en su lugar.
En Joda-Time , un objeto de fecha y hora ( DateTime
) realmente conoce su zona horaria asignada. Eso significa una compensación de UTC y las reglas y el historial del horario de verano de esa zona horaria (DST) 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 toString
método para generar una cadena en formato ISO 8601 .
String output = dateTimeIndia.toString();
Joda-Time también ofrece capacidades ricas para generar todo tipo de otros formatos de cadena.
Si es necesario, puede convertir de Joda-Time DateTime a java.util.Date.
Java.util.Date date = dateTimeIndia.toDate();
Busque StackOverflow para "joda date" para encontrar muchos más ejemplos, algunos bastante detallados.
† En realidad no es una zona horaria incrustada en un java.util.Date, que se utiliza para algunas funciones internas (véanse los comentarios sobre esta respuesta). Pero esta zona horaria interna no está expuesta como una propiedad y no se puede establecer. Esta zona horaria interna no es la utilizada por el toString
método para generar una representación de cadena del valor de fecha y hora; en cambio, la zona horaria predeterminada actual de la JVM se aplica sobre la marcha. Entonces, como taquigrafía, a menudo decimos "juDate no tiene zona horaria". ¿Confuso? Si. Otra razón más para evitar estas viejas clases cansadas.