UTC
pensar, trabajar y almacenar datos en UTC en lugar de cualquier zona horaria. Piense en UTC como One True Time, y todas las demás zonas horarias son meras variaciones. Por lo tanto, al codificar, olvídate de tu propia zona horaria. Haga su lógica de negocio, registro, almacenamiento de datos e intercambio de datos en UTC. Sugiero que cada programador mantenga un segundo reloj en su escritorio configurado en UTC.
java.time
La forma moderna es java.time las clases.
El mencionado proyecto Joda-Time proporcionó la inspiración para las clases java.time, y el proyecto ahora está en modo de mantenimiento con el equipo que recomienda la migración a clases java.time.
El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las viejas y problemáticas clases de fecha y hora legacy, como java.util.Date
, .Calendar
, & java.text.SimpleDateFormat
.
Para obtener más información, consulte el Oracle Tutorial. Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310.
¿Dónde obtener las clases java.time?
- Java SE 8 y SE 9 y más tarde
- incorporado.
- Parte de la API estándar de Java con una implementación integrada.
- Java 9 agrega algunas características menores y correcciones.
- Java SE 6 y SE 7
- Gran parte de la funcionalidad de back-java.time está portado a Java 6 & 7 en ThreeTen-Backport.
- Android
- El proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente) para Android específicamente.
- Ver How to use….
El proyecto se extiende ThreeTen-Extra 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 more.
ISO 8601
Cuando seria un valor de fecha y hora al texto, utilizar el estándar ISO 8601.
Por ejemplo, una fecha y hora en UTC es 2016-10-17T01:24:35Z
donde Z
es la abreviatura de Zulu
y significa UTC. Para otros offset-from-UTC, al final aparece el desplazamiento de horas y minutos, como 2016-01-23T12:34:56+05:30
. Las clases java.time extienden este formato estándar para agregar el nombre de la zona horaria (si se conoce) entre corchetes, como 2016-01-23T12:34:56+05:30[Asia/Kolkata]
.
La norma tiene muchos otros formatos prácticos así incluso para durations, intervals, ordinals y year-week.
Base de datos
Para el almacenamiento de base de datos, el uso de tipos de fecha y hora para los valores de fecha y hora, como el SQL standard data types que son principalmente DATE
, TIME
, y TIMESTAMP WITH TIME ZONE
.
Deje que su JDBC driver haga el trabajo pesado. El controlador maneja los detalles esenciales sobre la mediación y la adaptación entre las partes internas de cómo maneja Java los datos y cómo maneja la base de datos los datos de su lado. Pero asegúrese de practicar con datos de ejemplo para conocer los comportamientos de su controlador y su base de datos. El estándar SQL define muy poco sobre el manejo de la fecha y hora, por lo que los comportamientos varían ampliamente, sorprendentemente.
Si utiliza un controlador JDBC que cumpla con JDBC 4.2 y posterior, puede buscar y almacenar los tipos de java.time directamente a través de los métodos ResultSet::getObject
y PreparedStatement::setObject
.
Instant instant = myResultSet.getObject(…);
myPreparedStatement.setObject(… , instant);
Para los controladores más antiguos, tendrá que recurrir a la conversión a través de los tipos java.sql. Busque nuevos métodos de conversión agregados a las clases antiguas. Por ejemplo, java.sql.Timestamp.toInstant()
.
Instant instant = myResultSet.getTimestamp(…).toInstant();
myPreparedStatement.setObject(… , java.sql.Timestamp.from(instant));
Utilice los tipos java.sql lo más brevemente posible. Son un truco mal diseñado, como java.sql.Date
enmascarado como un valor de fecha solamente, pero en realidad como una subclase de java.util.Date
, de hecho tiene una hora establecida en el 00:00:00
en UTC. Y, oh, se supone que debes ignorar el hecho de que esa herencia dice el doc de la clase. Un desastre feo.
código Ejemplo
Consigue el momento actual en GMT.
Instant instant = Instant.now();
Almacenamiento y ir a buscar que Instant
objeto a/desde una base de datos se muestra arriba.
Para generar una cadena ISO 8601, simplemente llame al toString
. El javatodas las clases de tiempo usan formatos ISO 8601 por defecto para analizar y generar cadenas de sus diversos valores de fecha y hora.
String output = instant.toString();
Ajuste en cualquier desplazamiento-de-UTC aplicando una ZoneOffset
para obtener una OffsetDateTime
. Llame al toString
para generar un String en formato ISO 8601.
ZoneOffset offset = ZoneOffset.ofHoursMinutes(5 , 30);
OffsetDateTime odt = instant.atOffset(offset);
Una zona horaria es un desplazamiento más un conjunto de reglas para el manejo de anomalías tales como Daylight Saving Time (DST). Cuando necesite ver ese mismo momento a través del objetivo de alguna región propia wall-clock time, aplique una zona horaria (ZoneId
) para obtener un objeto ZonedDateTime
.
Especifique un proper time zone name en el formato de continent/region
. Nunca use la abreviatura de 3-4 letras, como EST
o IST
, ya que no son zonas horarias verdaderas, no están estandarizadas y ni siquiera son únicas (!).
ZoneId z = ZoneId.of("Asia/Kolkata");
ZonedDateTime zdt = instant.atZone(z);
En la otra dirección, se puede extraer un Instant
de un OffsetDateTime
o ZonedDateTime
llamando toInstant
.
Instant instant = zdt.toInstant();
Formateo
Para su presentación al usuario como cadenas en formatos que no sean ISO 8601, search Stack Overflow para el uso de la clase DateTimeFormatter
.
Si bien puede especificar un formato personalizado, generalmente es mejor dejar que java.time se localice automáticamente. Para localizar, especifique:
FormatStyle
para determinar cuánto tiempo o abreviar debe ser la cadena.
Locale
para determinar (a) el idioma humano para la traducción del nombre del día, nombre del mes y demás, y (b) las normas culturales que deciden los problemas de abreviatura, mayúsculas, puntuación, etc.
Ejemplo:
Locale l = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(l);
String output = zdt.format(f);
Conversión
mejor para evitar los tipos de fecha y hora de legado siempre que sea posible. Pero si trabaja con un código antiguo que aún no se ha actualizado para los tipos java.time, puede convertir a/desde los tipos java.time. Para más detalles, vea la pregunta, Convert java.util.Date to what “java.time” type?.
utilizar objetos
utilizar objetos en lugar de simples primitivas codificados y cadenas simples. Por ejemplo:
- No utilice 1-7 para representar un día de la semana, utilice el
DayOfWeek
enumeración como DayOfWeek.TUESDAY
.
- En lugar de pasar una cuerda como una fecha, pase alrededor de
LocalDate
objetos.
- En lugar de pasar un par de enteros por un año y un mes, pase alrededor de
YearMonth
objetos.
- En lugar de 1-12 por un mes, use la enumeración
Month
mucho más legible, como Month.JANUARY
.
El uso de tales objetos hace que su código sea más autodocumentado, garantiza valores válidos y proporciona type-safety.
bla bla bla, joda time, bla bla bla ... –