ParseException beim Datum parsen

  • Antworten:7
  • Bentwortet
Jamarilo
  • Forum-Beiträge: 9

01.08.2012, 15:04:22 via Website

Hallo Zusammen

Ich habe ein kleines Problem, beim parsen eines Datums von String in ein Datum..... kurze erleuterung des Problems:

- Ich übergebe der Methode ParseDatafield(String Datum) ein String der er mir dann in ein Datum und danach in Milisekunden umwandeln soll.
- an und für sich kein Problem habe das vorher mit dem exakten Code bereits gemacht und er gibt mir auch die korrekten Werte zurück, leider habe ich dies in einem Java Projekt gemacht un dachte mir ich kann das 1 zu1 auch in Android einsetzen.

- der Compiler gibt mir zeigt mir keinen Fehler, da diese Klasse im Android Projekt noch nicht nutzen kann da die Entwicklung der ganzen App noch nicht so weit ist habe ich mir gedacht isch schreibe eine Android JUnit Test Projekt das auch tadelos funktioniert.

- So nun habe ich die dazugehörigen Assert Tests dazu geschrieben und laufen lassen leider bekomme ich eine ungewöhnliche Fehlermeldung von dem Test Ergebnis: java.text.ParseException: Unparseable date: "08/05/2012 5:00PM" (at offset 15)
at java.text.DateFormat.parse(DateFormat.java:626)

Ich dachte mir ok, da habe ich was falsches implementiert..... aber leider komme ich nicht darauf was es sein könnte da es im Java Projekt 1 zu 1 genau so läuft da bekommen ich kein ParseException.

Hier noch ein wenig Code damit ihr wisst von was ich spreche:

Klasse ParsingString:

1package ch.zbwstundenplan.parsingService;
2
3import java.text.DateFormat;
4import java.text.ParseException;
5import java.text.SimpleDateFormat;
6import java.util.Date;
7
8/**
9 * @author Emanuel
10 *
11 *Diese Klasse wir benötigt um das Datenbank feld start und Ende zu parsen und in milisekunden
12 *umzuwandeln damit dieser Wert in die Android SQL geschrieben wird um damit zu arbeiten
13 */
14
15public class ParsingString implements ParseService {
16
17 //Attribute für das Parsen
18 private DateFormat dateFormat;
19 private String[] parseResult;
20
21 public ParsingString(){
22
23 dateFormat = new SimpleDateFormat("dd/MM/yyyy h:mma");
24 }
25
26
27
28 /**
29 * Die Methode parst das Datum und Zeitformat der von der
30 * Online Datenbank gegeben wird und gibt das Datum und die
31 * genaue Uhrzeit als Milisekunden seit dem 01.01.1970 zurück
32 *
33 * @param date
34 * @return long
35 * @throws ParseException
36 */
37
38 public long ParseDatafield(String date) throws ParseException {
39
40 long timestamp = 0;
41
42 parseResult = date.split(" ");
43 String s = parseResult[0]+"/"+parseResult[1]+"/"+parseResult[2]+" "+parseResult[4];
44
45 Date datum = dateFormat.parse(s);
46 timestamp = datum.getTime();
47
48 return timestamp;
49 }
50
51}

Klasse ParseStringTest: Die Methode testStringParsing()

1package ch.zbwstundenplan.activities.test;
2
3import ch.zbwstundenplan.parsingService.*;
4
5import junit.framework.Assert;
6import android.test.AndroidTestCase;
7
8public class ParseStringTest extends AndroidTestCase {
9
10 private long timestamp;
11 private String data;
12 private ParsingString sp = new ParsingString();
13
14 public void testStringParsing()throws Throwable {
15
16 timestamp = 1336489200000L;
17 data = "08 05 2012 5:00PM";
18
19 Assert.assertEquals(Long.valueOf(timestamp), Long.valueOf(sp.ParseDatafield("08 05 2012 5:00PM")));
20 }
21
22 public void testGetDateFromMili()throws Throwable {
23
24 timestamp = 1336489200000L;
25
26 Assert.assertEquals("Mai 08,2012 17:00", sp.GetDateFromMilisec(timestamp));
27
28 }
29}

Antworten
Markus B.
  • Forum-Beiträge: 636

01.08.2012, 16:02:03 via Website

Hi,
das machst du aber ganz schön kompliziert ...
Fangen wir mal vorne an:
Warum kommt ein String wie "08 05 2012 5:00PM" aus deiner Datenbank ?!
Desweiteren, schreib dir doch ein DateFormatPattern für "08 05 2012 5:00PM" dann musst du diese split Geschichte nicht machen (dd MM yyyy hh:mma) ... Kannst du hier auch nochmal im Detail nachlesen (http://developer.android.com/reference/java/text/SimpleDateFormat.html)
Dann greifst du mit parseResult[4] auf den Index 4 zu und bei deinen Tests gehts aber nur bis 3.
Das ich alles ziemlich komisch und viel zu aufwendig umgesetzt. Da solltest du noch mal ein bissel drüber nachdenken.

Gruß,
Markus

— geändert am 01.08.2012, 17:57:40

Antworten
Wolfgang S.
  • Forum-Beiträge: 32

01.08.2012, 16:15:07 via Website

Ich würde ebenfalls empfehlen, das Datum als Millisekunden in einer INTEGER-Spalte in der Datenbank zu speichern. Dadurch musst du eigentlich nur mehr bei der Darstellung des Datums von Millisekunden nach String umwandeln.

Ein Fehler der mir sofort aufgefallen ist: "dd/MM/yyyy h:mma" berücksichtigt 12:00PM (Mittag) nicht.

Antworten
Jamarilo
  • Forum-Beiträge: 9

01.08.2012, 21:32:31 via Website

Also dann fange ich auch von vorne an:
Ich werde sicher nicht ein solches Datum und Zeit Konstrukt in meiner Datenbank speichern, ich werde Milisekunden als INTEGER in meiner Datenbank speichern. Das Problem an dem ganzen ist das ich "08 05 2012 5:00PM" als String bekomme und ich das mir leider nicht aussuchen kann aus diesem Grund habe ich ein solches Datum Konstrukt.

Du hast absolut recht Markus, ich muss das eigentlich nicht parsen da ich ein SimpleDateFormat selber zusammenstellen kann und genau in diesem Format wie ich es bekomme...
Leider habe ich das mit dem SimpleDateFormat immer in der Java API nachgeschaut, ich habe immer vergessen das ich eigentlich in der Android API nachlesen solte.

Ich habe die klasse jetzt angepasst, habe das DatePattern so gewählt da es auf meinen String passt damit ich diesen String nicht per parsen muss. Leider habe ich noch immer den gleichen Fehler und ich verstehe nicht wieso, anscheinend übersehe ich was massgebendes.....

hier noch die angepasste Klasse:

1package ch.zbwstundenplan.parsingService;
2
3import java.text.DateFormat;
4import java.text.ParseException;
5import java.text.SimpleDateFormat;
6import java.util.Date;
7
8/**
9 * @author Emanuel
10 *
11 *Diese Klasse wir benötigt um das Datenbank feld start und Ende zu parsen und in milisekunden
12 *umzuwandeln damit dieser Wert in die Android SQL geschrieben wird um damit zu arbeiten
13 */
14
15public class ParsingString implements ParseService {
16
17 //Attribute für das Parsen
18 private DateFormat dateFormat;
19 private String[] parseResult;
20
21 public ParsingString(){
22
23 dateFormat = new SimpleDateFormat("dd MM yyyy h:mma");
24 }
25
26
27
28 /**
29 * Die Methode parst das Datum und Zeitformat der von der
30 * Online Datenbank gegeben wird und gibt das Datum und die
31 * genaue Uhrzeit als Milisekunden seit dem 01.01.1970 zurück
32 *
33 * @param date
34 * @return long
35 * @throws ParseException
36 */
37
38 public long ParseDatafield(String date) throws ParseException {
39
40 long timestamp = 0;
41
42 Date datum = dateFormat.parse(date);
43 timestamp = datum.getTime();
44
45 return timestamp;
46 }

1public class ParseStringTest extends AndroidTestCase {
2
3 private long timestamp;
4 private String data;
5 private ParsingString sp = new ParsingString();
6
7 public void testStringParsing()throws Throwable {
8
9 timestamp = 1336489200000L;
10 data = "08 05 2012 5:00PM";
11
12 Assert.assertEquals(Long.valueOf(timestamp), Long.valueOf(sp.ParseDatafield(data)));
13 }

Immer noch der gleiche Fehler.... java.text.ParseException:

Unparseable date: "08 05 2012 5:00PM" (at offset 16)
at java.text.DateFormat.parse(DateFormat.java:626)
at ch.zbwstundenplan.parsingService.ParsingString.ParseDatafield(ParsingString.java:45)
at ch.zbwstundenplan.activities.test.ParseStringTest.testStringParsing(ParseStringTest.java:19)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:545)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1551)

Ich bin euch für jede Hilfe dankbar... :(

Antworten
Markus B.
  • Forum-Beiträge: 636

01.08.2012, 23:52:03 via Website

Hi,
du kannst folgenden Code verwenden:

1final SimpleDateFormat dateFormat = new SimpleDateFormat("dd MM yyyy h:m a", Locale.US);
2...
3 public long parseDatafield(String date) throws ParseException
4 {
5 date = date.replaceAll(" *(PM|AM)", " $1");
6 return dateFormat.parse(date).getTime();
7 }

Nun ein bissel Erklärung:
Methodennamen werden in Java klein geschrieben.
Die Local.US ist auf alle Android-Geräten vorhanden (http://developer.android.com/reference/java/util/Locale.html#default_locale). Sonst gehen dir z.B. in unsere Zeitzone die PM / AM Informationen verloren.
Da dein Datumsformat eine Eigenkreation ist und keine ISO- / RFC-Norm entspricht, muss dieses noch leicht modifiziert werden, damit SimpleDateFormat damit umgehen kann. Das erledigt die erste Zeile in der Methode für dich.
Dann kannst du die die Variable in der Methode "timestamp" sparen, da die parsen funktioniert oder eben nicht.

Gruß,
Markus

— geändert am 02.08.2012, 23:23:55

Antworten
Jamarilo
  • Forum-Beiträge: 9

02.08.2012, 22:27:49 via Website

Ich danke dir Markus werde es gleich Morgen ausprobieren heute steht leider noch ein anderes Java Projekt an :-), das mit den Methoden Namen weiss ist mir leider untergegangen.

Antworten
Jamarilo
  • Forum-Beiträge: 9

04.08.2012, 16:05:23 via Website

Hi Markus,

habs hingekriegt, klappt alles wunderbar ich danke dir viel Mals für deine Hilfe.... :grin:

Antworten