2016-10-13 3 views
1

Ich habe ein Problem mit SimpleDateFormat.java.text.ParseException: Nicht übertragbares Datum: java.text.DateFormat.parse (DateFormat.java:579)

SimpleDateFormat dtfmt=new SimpleDateFormat("dd MMM yyyy hh:mm a", Locale.getDefault()); 
Date dt=dtfmt.parse(deptdt); 

In Android Emulator funktioniert gut, aber in Telefon habe ich diesen Fehler:

W/System.err: java.text.ParseException: Unparseable date: "24 Oct 2016 7:31 pm" (at offset 3) W/System.err: at java.text.DateFormat.parse(DateFormat.java:579)

eine Lösung?

Antwort

1

Ihre deptdt enthält Oct, die wie ein englischer Monatsname aussieht. Aber Ihre Locale.getDefault() gibt wahrscheinlich ein nicht-Englisch Gebietsschema. Ersetzen es durch Locale.ENGLISH oder Locale.US:

SimpleDateFormat dtfmt=new SimpleDateFormat("dd MMM yyyy hh:mm a", Locale.ENGLISH); 
Date dt=dtfmt.parse(deptdt); 
0

kommt es vor, wahrscheinlich, weil das Standardgebietsschema des Telefons nicht Englisch ist, und der Name des Monats in Ihrem Eingang (Oct).

Die Lösung ist explicity das englische Gebietsschema zu verwenden:

SimpleDateFormat dtfmt = new SimpleDateFormat("dd MMM yyyy hh:mm a", Locale.ENGLISH); 
Date dt = dtfmt.parse("24 Oct 2016 7:31 pm"); 

Statt direkt mit SimpleDateFormat arbeiten (wie diese alten API lots of problems und design issues hat), können Sie die ThreeTen Backport verwenden, ein großer Backport für die neuen Datum/Uhrzeit-Klassen von Java 8. Um es in Android zu verwenden, benötigen Sie auch die ThreeTenABP (mehr darüber, wie man es verwendet here).

Die Hauptklassen, die verwendet werden sollen, sind org.threeten.bp.LocalDateTime (es scheint die beste Wahl zu sein, da Sie Datums- und Zeitfelder in Ihrer Eingabe haben) und org.threeten.bp.format.DateTimeFormatter (um die Eingabe zu parsen). Ich benutze auch java.util.Locale Klasse um sicherzustellen, dass es die Monatsnamen in Englisch analysieren und die org.threeten.bp.format.DateTimeFormatterBuilder um sicherzustellen, dass es parst pm (es Groß- und Kleinschreibung machen, als die Standard-PM ist):

DateTimeFormatter fmt = new DateTimeFormatterBuilder() 
    // case insensitive to parse "pm" 
    .parseCaseInsensitive() 
    // pattern 
    .appendPattern("dd MMM yyyy h:mm a") 
    // use English locale to parse month name (Oct) 
    .toFormatter(Locale.ENGLISH); 
// parse input 
LocalDateTime dt = LocalDateTime.parse("24 Oct 2016 7:31 pm", fmt); 
System.out.println(dt); // 2016-10-24T19:31 

Der Ausgang wird sein:

2016-10-24T19:31

Wenn Sie diese java.util.Date zu einer Notwendigkeit zu konvertieren, können Sie die org.threeten.bp.DateTimeUtils Klasse. Aber Sie müssen auch wissen, welche Zeitzone verwendet wird, um dies zu konvertieren. Im Beispiel unten, ich bin mit "UTC":

Date date = DateTimeUtils.toDate(dt.atZone(ZoneOffset.UTC).toInstant()); 

in eine andere Zone zu ändern, können Sie tun:

Date date = DateTimeUtils.toDate(dt.atZone(ZoneId.of("Europe/London")).toInstant()); 

Beachten Sie, dass die API IANA timezones names (immer im Format verwendet Continent/City , wie America/Sao_Paulo oder Europe/Berlin). Vermeiden Sie die 3-Buchstaben-Abkürzungen (wie CST oder), weil sie ambiguous and not standard sind. Verwenden Sie die ZoneId.getAvailableZoneIds()-Methode, um die Zeitzone zu finden, die besser zu jeder Region passt, und überprüfen Sie, welche für Ihre Anwendungsfälle am besten geeignet ist.

PS: das letzte Beispiel oben (dt.atZone(ZoneId.of("Europe/London"))) wird das Datum/Zeit 2016-10-24T19:31 in London Zeitzone erstellen. Aber wenn was Sie wollen, ist 2016-10-24T19:31 in UTC, dann konvertieren Sie es in eine andere Zeitzone, dann sollten Sie tun:

Date date = DateTimeUtils.toDate(dt 
    // first convert it to UTC 
    .toInstant(ZoneOffset.UTC) 
    // then convert to LondonTimezone 
    .atZone(ZoneId.of("Europe/London")).toInstant()); 
Verwandte Themen