semana primer online java parsing time jodatime intervals

primer - Análisis de intervalo de tiempo ISO 8601 en Java



iso 8601 pt (4)

Supongo que ya has probado Joda-Time. Al alimentar las cadenas de ejemplo de su pregunta a través de Interval.parse(Object) revela que puede manejar "inicio y fin", "inicio y duración" y "duración y finalización", pero no campos implícitos ni repetición.

2007-03-01T13:00:00Z/2008-05-11T15:30:00Z => from 2007-03-01T13:00:00.000Z to 2008-05-11T15:30:00.000Z 2007-03-01T13:00:00Z/P1Y2M10DT2H30M => from 2007-03-01T13:00:00.000Z to 2008-05-11T15:30:00.000Z P1Y2M10DT2H30M/2008-05-11T15:30:00Z => from 2007-03-01T13:00:00.000Z to 2008-05-11T15:30:00.000Z 2007-12-14T13:30/15:30 => java.lang.IllegalArgumentException: Invalid format: "15:30" is malformed at ":30" R5/2008-03-01T13:00:00Z/P1Y2M10DT2H30M => java.lang.IllegalArgumentException: Invalid format: "R5"

La única otra completa biblioteca de fecha / hora que conozco es JSR-310 , que no parece manejar intervalos como estos.

En este punto, construir tus propias mejoras además de Joda-Time es probablemente tu mejor opción, lo siento. ¿Hay algún formato de intervalo ISO específico que deba manejar más allá de los que ya admite Joda-Time?

ISO 8601 define una sintaxis para representar un intervalo de tiempo.

Hay cuatro formas de expresar un intervalo de tiempo:

  • Principio y fin, como "2007-03-01T13: 00: 00Z / 2008-05-11T15: 30: 00Z"
  • Inicio y duración, como "2007-03-01T13: 00: 00Z / P1Y2M10DT2H30M"
  • Duración y finalización, como "P1Y2M10DT2H30M / 2008-05-11T15: 30: 00Z"
  • Duración solamente, como "P1Y2M10DT2H30M", con información de contexto adicional

Si falta algún elemento del valor final, se supone que es el mismo que para el valor inicial, incluida la zona horaria. Esta característica del estándar permite representaciones concisas de intervalos de tiempo. Por ejemplo, la fecha de una reunión de dos horas que incluye las horas de inicio y finalización podría simplemente mostrarse como "2007-12-14T13: 30/15: 30", donde "/ 15: 30" implica "/ 2007-12- 14T15: 30 "(la misma fecha que el inicio), o las fechas de inicio y finalización de un período de facturación mensual como" 2008-02-15 / 03-14 ", donde" / 03-14 "implica" / 2008-03 -14 "(el mismo año que el comienzo).

Además, los intervalos de repetición se forman al agregar "R [n] /" al comienzo de una expresión de intervalo, donde R se usa como la letra misma y [n] se reemplaza por el número de repeticiones. Dejar el valor de [n] significa un número ilimitado de repeticiones. Por lo tanto, para repetir el intervalo de "P1Y2M10DT2H30M" cinco veces a partir de "2008-03-01T13: 00: 00Z", utilice "R5 / 2008-03-01T13: 00: 00Z / P1Y2M10DT2H30M".

Estoy buscando un buen analizador de Java (si es posible compatible con la biblioteca Joda-Time) para analizar esta sintaxis. ¿Alguna sugerencia para una buena biblioteca?


java.time

El marco java.time integrado en Java 8 y posterior tiene un método Duration.parse para analizar una duración formateada ISO 8601 :

java.time.Duration d = java.time.Duration.parse("PT1H2M34S"); System.out.println("Duration in seconds: " + d.get(java.time.temporal.ChronoUnit.SECONDS));

Imprime la Duration in seconds: 3754


Para cualquier persona en un proyecto que podría estar restringido al uso de bibliotecas de terceros (razones de licencia, o lo que sea), Java proporciona al menos una parte de esta capacidad, desde Java 1.6 (¿o anterior?), Utilizando javax.xml.datatype. Método DatatypeFactory.newDuration (String) y clase de duración . El método DatatypeFactory.newDuration (String) analizará una cadena en formato "PnYnMnDTnHnMnS". Estas clases están destinadas a la manipulación de XML, pero dado que XML utiliza la notación de tiempo ISO 8601, también sirven como convenientes utilidades de análisis de duración.

Ejemplo:

import javax.xml.datatype.*; Duration dur = DatatypeFactory.newInstance().newDuration("PT5H12M36S"); int hours = dur.getHours(); // Should return 5

Personalmente, no he utilizado ningún formato de duración, excepto el 4º que me aparece, por lo que no puedo garantizar si los analiza correctamente o no.


La única biblioteca que es capaz de modelar todas las características del análisis de intervalo que desea es en realidad mi biblioteca Time4J (range-module). Ejemplos:

// case 1 (start/end) System.out.println(MomentInterval.parseISO("2012-01-01T14:15Z/2014-06-20T16:00Z")); // output: [2012-01-01T14:15:00Z/2014-06-20T16:00:00Z) // case 1 (with some elements missing at end component and different offset) System.out.println(MomentInterval.parseISO("2012-01-01T14:15Z/08-11T16:00+00:01")); // output: [2012-01-01T14:15:00Z/2012-08-11T15:59:00Z) // case 1 (with missing date and offset at end component) System.out.println(MomentInterval.parseISO("2012-01-01T14:15Z/16:00")); // output: [2012-01-01T14:15:00Z/2012-01-01T16:00:00Z) // case 2 (start/duration) System.out.println(MomentInterval.parseISO("2012-01-01T14:15Z/P2DT1H45M")); // output: [2012-01-01T14:15:00Z/2012-01-03T16:00:00Z) // case 3 (duration/end) System.out.println(MomentInterval.parseISO("P2DT1H45M/2012-01-01T14:15Z")); // output: [2011-12-30T12:30:00Z/2012-01-01T14:15:00Z) // case 4 (duration only, in standard ISO-format) Duration<IsoUnit> isoDuration = Duration.parsePeriod("P2DT1H45M"); // case 4 (duration only, in alternative representation) Duration<IsoUnit> isoDuration = Duration.parsePeriod("P0000-01-01T15:00"); System.out.println(isoDuration); // output: P1M1DT15H

Algunas observaciones:

  • Existen otras clases de intervalo con capacidades de análisis similares, por ejemplo, DateInterval o TimestampInterval en el paquete net.time4j.range .

  • Para manejar duraciones solamente (que también pueden abarcar tanto unidades de calendario como de reloj), consulte también el javadoc . También hay características de formateo, vea la clase anidada Duration.Formatter o la versión localizada net.time4j.PrettyTime (actualmente en 86 idiomas).

  • La interoperabilidad se ofrece con Java-8 ( java.time ) pero no con Joda-Time. Por ejemplo: getStartAsInstant() o getEndAsInstant() pueden consultar fácilmente el componente inicial o final de MomentInterval .

La clase IsoRecurrence admite intervalos de repetición. Ejemplo:

IsoRecurrence<MomentInterval> ir = IsoRecurrence.parseMomentIntervals("R5/2008-03-01T13:00:00Z/P1Y2M10DT2H30M"); ir.intervalStream().forEach(System.out::println);

Salida:

[2008-03-01T13:00:00Z/2009-05-11T15:30:00Z) [2009-05-11T15:30:00Z/2010-07-21T18:00:00Z) [2010-07-21T18:00:00Z/2011-10-01T20:30:00Z) [2011-10-01T20:30:00Z/2012-12-11T23:00:00Z) [2012-12-11T23:00:00Z/2014-02-22T01:30:00Z)