Java 8 agregó una nueva API java.time para trabajar con fechas y horas ( JSR 310 ).
Tengo fecha y hora como cadena (por ejemplo "2014-04-08 12:30"
). ¿Cómo puedo obtener una LocalDateTime
instancia de la cadena dada?
Después de que termine de trabajar con el LocalDateTime
objeto: ¿Cómo puedo convertir la LocalDateTime
instancia a una cadena con el mismo formato que se muestra arriba?
ZonedDateTime
lugar de unLocalDateTime
. El nombre es contra-intuitivo; EstoLocal
significa cualquier localidad en general en lugar de una zona horaria específica. Como tal, unLocalDateTime
objeto no está vinculado a la línea de tiempo. Para tener significado, para obtener un momento específico en la línea de tiempo, debe aplicar una zona horaria.LocalDateTime
vs.ZonedDateTime
vs.OffsetDateTime
vs.Instant
vs.LocalDate
vs.LocalTime
, cómo mantener la calma sobre por qué es tan complicado y cómo hacerlo bien en el primer disparo.LocalDateTime
probablemente habría sido nombradoZonelessOffsetlessDateTime
.Respuestas:
Fecha y hora de análisis
Para crear un
LocalDateTime
objeto a partir de una cadena, puede usar elLocalDateTime.parse()
método estático . Toma una cadena y unDateTimeFormatter
como parámetro. ElDateTimeFormatter
se utiliza para especificar el patrón de fecha / hora.Formato de fecha y hora
Para crear una cadena formateada de un
LocalDateTime
objeto, puede usar elformat()
métodoTenga en cuenta que hay algunos formatos de fecha / hora de uso común predefinidos como constantes en
DateTimeFormatter
. Por ejemplo: usarDateTimeFormatter.ISO_DATE_TIME
para formatear laLocalDateTime
instancia desde arriba daría como resultado la cadena"1986-04-08T12:30:00"
.Los métodos
parse()
yformat()
están disponibles para todos los objetos relacionados con la fecha / hora (p. Ej.LocalDate
OZonedDateTime
)fuente
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX")
format()
a la clase LocalDateTime en lugar de a la instancia? Al menos, eso es lo que hice: confundíDateTime
condateTime
el ejemplo anterior.También puede usar
LocalDate.parse()
oLocalDateTime.parse()
en unString
sin proporcionarle un patrón, siString
está en formato ISO-8601 .por ejemplo,
Salida ,
y úselo
DateTimeFormatter
solo si tiene que lidiar con otros patrones de fecha.Por ejemplo, en el siguiente ejemplo, dd MMM uuuu representa el día del mes (dos dígitos), tres letras del nombre del mes (enero, febrero, marzo, ...) y un año de cuatro dígitos:
Salida
recuerde también que el
DateTimeFormatter
objeto es bidireccional; puede analizar tanto la entrada como el formato de salida.Salida
(vea la lista completa de patrones para formatear y analizar DateFormatter )
fuente
2018-08-09 12:00:08
pero cuando analizo veo queT
se agrega una que no necesito. Hay una manera de hacerlo ?yyyy-MM-dd hh:mm:ss
para analizar y formatear. La T siempre se mostrará en el formato predeterminado (ISO-8061), pero puede usar sus propios patrones.Ambas respuestas explican muy bien la pregunta sobre los patrones de cuerdas. Sin embargo, en caso de que esté trabajando con ISO 8601 no hay necesidad de aplicar
DateTimeFormatter
ya que LocalDateTime ya está preparado para ello:Convierta LocalDateTime a la zona horaria ISO8601 String
Convierta la cadena ISO8601 de nuevo a LocalDateTime
fuente
Analizar una cadena con fecha y hora en un punto particular en el tiempo (Java lo llama "
Instant
") es bastante complicado. Java ha estado abordando esto en varias iteraciones. El últimojava.time
yjava.time.chrono
cubre casi todas las necesidades (excepto Time Dilation :)).Sin embargo, esa complejidad trae mucha confusión.
La clave para comprender el análisis de fechas es:
¿Por qué Java tiene tantas formas de analizar una fecha?
... y por qué es el
LocalDateTime
,ZonedDateTime
et al. tan complicadoHay zonas horarias . Una zona horaria es básicamente una "franja" * [1] de la superficie de la Tierra cuyas autoridades siguen las mismas reglas de cuándo tiene qué compensación de tiempo. Esto incluye las reglas del horario de verano.
Las zonas horarias cambian con el tiempo para varias áreas, principalmente en función de quién conquista a quién. Y las reglas de una zona horaria también cambian con el tiempo .
Hay compensaciones de tiempo. Eso no es lo mismo que las zonas horarias, porque una zona horaria puede ser, por ejemplo, "Praga", pero tiene un desplazamiento de horario de verano y otro de invierno.
Si obtiene una marca de tiempo con una zona horaria, el desplazamiento puede variar, dependiendo de la parte del año en que se encuentre. Durante la hora bisiesta, la marca de tiempo puede significar 2 tiempos diferentes, por lo que sin información adicional, no puede ser confiable convertido.
Nota: Por marca de tiempo me refiero a "una cadena que contiene una fecha y / o hora, opcionalmente con una zona horaria y / o desplazamiento de hora".
Varias zonas horarias pueden compartir el mismo desplazamiento de tiempo para ciertos períodos. Por ejemplo, la zona horaria GMT / UTC es la misma que la zona horaria "Londres" cuando la compensación de horario de verano no está vigente.
Para hacerlo un poco más complicado (pero eso no es demasiado importante para su caso de uso):
2040-12-31 24:00:00
lo tanto, puede ser una fecha y hora válida). Esto necesita actualizaciones periódicas de los metadatos que los sistemas usan para tener las conversiones de fecha correctas. Por ejemplo, en Linux, obtiene actualizaciones periódicas de los paquetes de Java, incluidos estos nuevos datos.Las actualizaciones no siempre mantienen el comportamiento anterior para las marcas de tiempo históricas y futuras. Por lo tanto, puede ocurrir que el análisis de las dos marcas de tiempo alrededor del cambio de una zona horaria al compararlas pueda dar resultados diferentes cuando se ejecuta en diferentes versiones del software. Eso también se aplica a la comparación entre la zona horaria afectada y otra zona horaria.
Si esto causa un error en su software, considere usar una marca de tiempo que no tenga reglas tan complicadas, como la marca de tiempo UNIX .
Debido a 7, para las fechas futuras, no podemos convertir fechas exactamente con certeza. Entonces, por ejemplo, el análisis actual
8524-02-17 12:00:00
puede estar desactivado unos segundos después del análisis futuro.Las API de JDK para esto evolucionaron con las necesidades contemporáneas
java.util.Date
tenían un enfoque un poco ingenuo, suponiendo que solo hay año, mes, día y hora. Esto rápidamente no fue suficiente.java.sql.Date
se introdujo muy temprano , con sus propias limitaciones.Calendar
se introdujo la API.Cómo lidiar con eso en Java
java.time
Determine a qué tipo analizar una marca de tiempo
Cuando consume una cadena de marca de tiempo, necesita saber qué información contiene. Este es el punto crucial. Si no lo hace bien, terminará con excepciones crípticas como "No se puede crear Instantáneo" o "Falta el desplazamiento de zona" o "ID de zona desconocida", etc.
¿Contiene la fecha y la hora?
¿Tiene un desplazamiento de tiempo?
Un desplazamiento de tiempo es la
+hh:mm
parte. A veces,+00:00
se puede sustituir porZ
"hora Zulú",UTC
como hora universal coordinada oGMT
como hora media de Greenwich. Estos también establecen la zona horaria.Para estas marcas de tiempo, usted usa
OffsetDateTime
.¿Tiene una zona horaria?
Para estas marcas de tiempo, usted usa
ZonedDateTime
.La zona se especifica por
La lista de zonas horarias está compilada por una "base de datos TZ" , respaldada por ICAAN.
Según
ZoneId
el javadoc, los id de zona también se pueden especificarZ
y compensar de alguna manera . No estoy seguro de cómo esto se asigna a zonas reales. Si la marca de tiempo, que solo tiene una TZ, cae en un cambio de compensación de hora bisiesta, entonces es ambigua y la interpretación está sujeta aResolverStyle
, ver más abajo.Si no tiene ninguno , entonces el contexto faltante es asumido o descuidado. Y el consumidor tiene que decidir. Por lo tanto, debe analizarse
LocalDateTime
y convertirse alOffsetDateTime
agregar la información que falta:Duration
), o cuando no sabe y realmente no importa (por ejemplo, el horario del autobús local).Información de tiempo parcial
LocalDate
,LocalTime
,OffsetTime
,MonthDay
,Year
, oYearMonth
fuera de él.Si tiene la información completa, puede obtener un
java.time.Instant
. Esto también se usa internamente para convertir entreOffsetDateTime
yZonedDateTime
.Descubre cómo analizarlo
Existe una extensa documentación sobre la
DateTimeFormatter
cual se puede analizar una cadena de marca de tiempo y formatearla.Los s creados previamente
DateTimeFormatter
deben abarcar más todos los formatos de marca de tiempo estándar. Por ejemplo,ISO_INSTANT
puede analizar2011-12-03T10:15:30.123457Z
.Si tiene algún formato especial, puede crear su propio DateTimeFormatter (que también es un analizador).
Recomiendo mirar el código fuente
DateTimeFormatter
e inspirarse en cómo construir uno usandoDateTimeFormatterBuilder
. Mientras esté allí, también observeResolverStyle
qué controles controla si el analizador es LENIENTE, INTELIGENTE o ESTRICTO para los formatos y la información ambigua.Accesorio temporal
Ahora, el error frecuente es entrar en la complejidad de
TemporalAccessor
. Esto proviene de cómo solían trabajar los desarrolladoresSimpleDateFormatter.parse(String)
. Bien,DateTimeFormatter.parse("...")
te daTemporalAccessor
.Pero, equipado con el conocimiento de la sección anterior, puede analizar convenientemente el tipo que necesita:
En realidad no es necesario
DateTimeFormatter
tampoco. Los tipos que desea analizar tienen losparse(String)
métodos.Al respecto
TemporalAccessor
, puede usarlo si tiene una idea vaga de qué información hay en la cadena y desea decidir en tiempo de ejecución.Espero arrojar algo de luz sobre tu alma :)
Nota: Hay un backport de
java.time
Java 6 y 7: ThreeTen-Backport . Para Android tiene ThreeTenABP .[1] No solo que no son rayas, sino que también hay algunos extremos extraños. Por ejemplo, algunas islas vecinas del Pacífico tienen zonas horarias de +14: 00 y -11: 00. Eso significa que, mientras que en una isla, es el 1 de mayo a las 3 p.m., en otra isla no tan lejos, todavía son 30 de abril a las 12 p.m. (si contaba correctamente :))
fuente
OBTENGA LA HORA ACTUAL UTC EN EL FORMATO REQUERIDO
fuente
Me pareció maravilloso cubrir múltiples variantes de formato de fecha y hora como este:
fuente