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 LocalDateTimeinstancia de la cadena dada?
Después de que termine de trabajar con el LocalDateTimeobjeto: ¿Cómo puedo convertir la LocalDateTimeinstancia a una cadena con el mismo formato que se muestra arriba?

ZonedDateTimelugar de unLocalDateTime. El nombre es contra-intuitivo; EstoLocalsignifica cualquier localidad en general en lugar de una zona horaria específica. Como tal, unLocalDateTimeobjeto 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.LocalDateTimevs.ZonedDateTimevs.OffsetDateTimevs.Instantvs.LocalDatevs.LocalTime, cómo mantener la calma sobre por qué es tan complicado y cómo hacerlo bien en el primer disparo.LocalDateTimeprobablemente habría sido nombradoZonelessOffsetlessDateTime.Respuestas:
Fecha y hora de análisis
Para crear un
LocalDateTimeobjeto a partir de una cadena, puede usar elLocalDateTime.parse()método estático . Toma una cadena y unDateTimeFormattercomo parámetro. ElDateTimeFormatterse utiliza para especificar el patrón de fecha / hora.Formato de fecha y hora
Para crear una cadena formateada de un
LocalDateTimeobjeto, 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_TIMEpara formatear laLocalDateTimeinstancia 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.LocalDateOZonedDateTime)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íDateTimecondateTimeel ejemplo anterior.También puede usar
LocalDate.parse()oLocalDateTime.parse()en unStringsin proporcionarle un patrón, siStringestá en formato ISO-8601 .por ejemplo,
Salida ,
y úselo
DateTimeFormattersolo 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
DateTimeFormatterobjeto 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:08pero cuando analizo veo queTse agrega una que no necesito. Hay una manera de hacerlo ?yyyy-MM-dd hh:mm:sspara 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
DateTimeFormatterya 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.timeyjava.time.chronocubre 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,ZonedDateTimeet 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:00lo 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:00puede estar desactivado unos segundos después del análisis futuro.Las API de JDK para esto evolucionaron con las necesidades contemporáneas
java.util.Datetení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.Datese introdujo muy temprano , con sus propias limitaciones.Calendarse introdujo la API.Cómo lidiar con eso en Java
java.timeDetermine 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:mmparte. A veces,+00:00se puede sustituir porZ"hora Zulú",UTCcomo hora universal coordinada oGMTcomo 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
ZoneIdel javadoc, los id de zona también se pueden especificarZy 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
LocalDateTimey convertirse alOffsetDateTimeagregar 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, oYearMonthfuera de él.Si tiene la información completa, puede obtener un
java.time.Instant. Esto también se usa internamente para convertir entreOffsetDateTimeyZonedDateTime.Descubre cómo analizarlo
Existe una extensa documentación sobre la
DateTimeFormattercual se puede analizar una cadena de marca de tiempo y formatearla.Los s creados previamente
DateTimeFormatterdeben abarcar más todos los formatos de marca de tiempo estándar. Por ejemplo,ISO_INSTANTpuede 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
DateTimeFormattere inspirarse en cómo construir uno usandoDateTimeFormatterBuilder. Mientras esté allí, también observeResolverStylequé 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
DateTimeFormattertampoco. 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.timeJava 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