Pregunta

así que estaba teniendo un problema al analizar una fecha, mediante el IslamicChronology cronología JodaTime Así escribió un pequeño ejemplo para demostrar mi problema.

Aquí está el código:

import org.joda.time.Chronology;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.chrono.IslamicChronology;

import java.util.Date;

/**
 * Test
 */
public class Test
{
    public static void main(String[] args)
    {
        Date now = new Date();

        String format = "dd MMM yyyy";
        Chronology calendarSystem = IslamicChronology.getInstance();
        DateTimeFormatter formatter = DateTimeFormat.forPattern(format).withChronology(calendarSystem);

        String nowAsString = formatter.print(now.getTime());

        System.out.println("nowAsString = " + nowAsString);

        long parsedNowTs = formatter.parseMillis(nowAsString);

        String parsedNowTsAsString = formatter.print(parsedNowTs);
    }
}

Y la salida:

nowAsString = 16 10 1430
Exception in thread "main" java.lang.IllegalArgumentException: Invalid format: "16 10 1430" is malformed at "10 1430"
    at org.joda.time.format.DateTimeFormatter.parseMillis(DateTimeFormatter.java:634)
    at test.Test.main(Test.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    ...

Estoy pensando que el problema es que el nombre del mes es numérico, pero estoy en lo cierto? Alguien tiene alguna sugerencia? Esto no puede ser recreada si la cronología es gregoriano.

Gracias de antemano.

¿Fue útil?

Solución

Si alguien está interesado ... He encontrado un trabajo en torno a:

  • Crea una nueva clase, por ejemplo, IslamicChronologyWithNames que los delegados a una instancia de IslamicChronology en el paquete org.joda.time.DateTimeZone
  • Modificar el método; assemble(Fields fields): llamar al método del delegado y luego establece fields.monthOfYear (y posiblemente díadelasemana) que le propia subclase de BasicMonthOfYearDateTimeField
  • La subclase de BasicMonthOfYearDateTimeField continuación, puede buscar en los archivos de propiedades de nombres (si ... DayOfWeek o el día de) el nombre del mes. Subclase debe estar en el paquete org.joda.time.chrono para poder extender BasicMonthOfYearDateTimeField.

Todavía hay un problema que el tiempo Joda parece validar la fecha en que se está analizando antes de llamar a los métodos de la subclase como getAsText(int fieldValue, Locale locale) y porque no tiene conocimiento de los nombres de los meses que sus declaraciones de clase, no pasa la validación y así nunca se llama a los métodos. Mi solución alternativa era tener un método estático en esta clase que convierte una fecha como una cadena con nombres islámicos mes en una fecha como una cadena con nombres de los meses inglés, gregoriano. Así que antes de llamar parseDateTime(), llame al método estático y luego la cadena de fecha pasa la validación. Entonces, en lugar de procesar nombres islámicos mes en el método convertText(), utilice la aplicación por defecto gregoriano dentro de su subclase:

protected int convertText(String text, Locale locale)
{
    return GJLocaleSymbols.forLocale(locale).monthOfYearTextToValue(text);
}

Eso debería funcionar! La esperanza que tiene sentido para cualquier persona que tiene el mismo problema.

Otros consejos

MMM en la plantilla de formato indica el nombre abreviado del mes. Un índice numérico mes debe indicarse con MM.

Después de leer sus comentarios sobre la respuesta de dtsazza, me di cuenta de su problema real. :)

He echado un vistazo en el código fuente JODA y parece como si el apoyo a la chronlogy islámica es bastante roto. En primer lugar, el formateador no admite nombres de los meses, por lo que los patrones de MMM y MMMM se formatean como el número del mes, aunque de acuerdo con la documentación de DateTimeFormat, el nombre abreviado del mes se debe utilizar para MMM y el nombre completo del mes de MMMM .

Uno de los problemas con su ejemplo de código es que parseMillis siempre está usando la cronología ISO, aunque el formateador se ha configurado con otra cronología. Esto también se menciona en la documentación de la API, aunque no es particularmente intuitiva.

Si sustituyo parseMillis con parseDateTime, lo que habría esperado la cronología que se utilizará para el análisis (al menos la documentación dice algo así), pero parece como si la aplicación ignora la cronología configurado y continúa con la cronología ISO aquí como bien.

Se ha especificado el formato que dd MMM yyyy; según el API que los medios que necesita para abastecer el mes en forma abreviada cuerdas (en este caso, "octubre"). La entrada que se pasa en analizar correctamente si el formato se dd MM yyyy.

Editar: parece que me perdí un poco su punto. Lo que he encontrado es un caso en que un formateador dado,

long input = ...; // whatever
formatter.parseMillis(formatter.print(input));

es lanzar una excepción. Aunque no puedo ver ninguna explícitas garantiza que esto siempre debe trabajar, sin duda me esperaba que para ser el caso - de modo que sí, yo apoyo su afirmación de que este es un error probable en Joda sí mismo.

Por lo menos, si se espera que este comportamiento no debe haber alguna indicación más clara de que puede suceder.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top