Domanda

così ho avuto un problema l'analisi di una data, utilizzando la cronologia IslamicChronology JodaTime così ha scritto un piccolo esempio per dimostrare il mio problema.

Ecco il codice:

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);
    }
}

E l'uscita:

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)
    ...

sto pensando il problema è che il nome del mese è numerico ma ho ragione? Chiunque ha qualche suggerimento? Questo non può essere ricreata se la cronologia è gregoriano.

Grazie in anticipo.

È stato utile?

Soluzione

Se qualcuno è interessato ... Ho trovato un modo per aggirare:

  • Creare una nuova classe per esempio IslamicChronologyWithNames che delega a un'istanza di IslamicChronology nel pacchetto org.joda.time.DateTimeZone
  • Modificare il un metodo; assemble(Fields fields): chiamare il metodo del delegato e quindi impostare fields.monthOfYear (e possibilmente dayOfWeek) a voi propria sottoclasse di BasicMonthOfYearDateTimeField
  • La sottoclasse di BasicMonthOfYearDateTimeField può quindi ricerca nel file di proprietà nomi per (se DayOfWeek ... o il giorno del) il nome del mese. Sottoclasse deve essere nel pacchetto org.joda.time.chrono per essere in grado di estendere BasicMonthOfYearDateTimeField.

C'è ancora un problema che il tempo Joda sembra convalidare la data che si sta analizzando prima di chiamare i metodi di sottoclasse come getAsText(int fieldValue, Locale locale) e perché non è a conoscenza dei nomi dei mesi che le vostre dichiarazioni di classe, non supera la convalida e così non chiama i metodi. Il mio lavoro-around era di avere un metodo statico in questa classe che converte una data come una stringa con nomi islamici mese in una data come una stringa con i nomi dei mesi in inglese gregoriano. Quindi, prima di chiamare parseDateTime(), chiamare il metodo statico e quindi la stringa di data passa la convalida. Poi, invece di elaborazione nomi islamici mese nel metodo convertText(), utilizzare l'implementazione gregoriano predefinita all'interno della vostra sottoclasse:

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

Che dovrebbe funzionare! La speranza ha un senso per chi ha lo stesso problema.

Altri suggerimenti

MMM nel modello formato indica il nome del mese abbreviato. Un indice numerico mese dovrebbe essere indicato con MM.

Dopo aver letto il tuo commento sulla risposta di dtsazza, ho capito il problema reale. :)

Ho preso uno sguardo al codice sorgente JODA e sembra come se il supporto per il chronlogy islamica è piuttosto rotto. Prima di tutto, il formattatore non supporta i nomi dei mesi, in modo che i modelli MMM e MMMM sono formattati come il numero del mese, anche se secondo la documentazione del DateTimeFormat, il nome del mese abbreviato deve essere utilizzato per MMM e il nome completo mese per MMMM .

Un problema con il tuo esempio di codice è che parseMillis è sempre usando la cronologia ISO, anche se il formattatore è stato configurato con un altro cronologia. Questo è anche menzionato nella documentazione API, sebbene non particolarmente intuitivo.

Se sostituisco parseMillis con parseDateTime, mi sarei aspettato la cronologia da utilizzare per l'analisi (almeno la documentazione dice così), ma sembra come se l'applicazione ignora la cronologia configurato e prosegue con la cronologia ISO qui bene.

Hai specificato il formato dd MMM yyyy; come da API che mezzi è necessario fornire il mese in forma abbreviata-string (in questo caso, "Ottobre"). L'ingresso si passò sarebbe analizzare correttamente se il formato fosse dd MM yyyy.

Edit: sembra che ho perso un po 'il vostro punto. Quello che ho trovato è un caso in cui per un dato formattatore,

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

è un'eccezione. Anche se non riesco a vedere alcun espliciti le garanzie che questo dovrebbe funzionare sempre, mi piacerebbe sicuramente aspetto che sia il caso - quindi sì, mi piacerebbe sostenere la tua affermazione che si tratta di una probabile bug in Joda stesso.

Per lo meno, se questo è il comportamento previsto non ci dovrebbe essere qualche indicazione molto più chiaro che può succedere.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top