DateFormatter kann plötzlich keine 24h Uhr mehr konvertieren?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • DateFormatter kann plötzlich keine 24h Uhr mehr konvertieren?

    Hallo,

    ich schreibe gerade eine App in Swift neu, die ich schon in ObjC am laufen hatte. Ich bekomme in der App aus einer SQLite Datenbank ein Datum als String, welches ich in das Date() Format konvertieren möchte. Hier ist die Funktion die das macht:

    Quellcode

    1. func sqliteDateTimeStringToDate(_ string:String)->Date {
    2. let dateFormatter = DateFormatter()
    3. dateFormatter.dateFormat = "yyyy-MM-dd'T'hh:mm:ss a"
    4. let date = dateFormatter.date(from: string)
    5. return date
    6. }
    Nach einigen Test habe ich folgendes Festgestellt:

    Wenn ich dieser Funktion den Wert: "2018-07-16T12:59:59" übergebe funktioniert sie noch, übergebe ich aber den Wert "2018-07-16T13:00:00" stürzt die App ab. In ObjC funktionierte das meines Erachtens noch alles einwandfrei.
    Was mache ich hier nur falsch?

    Danke im voraus.

    Dirk
  • Mac & i Test Abo
  • Ich habe nun meine Funktion erweitert um locale:

    Quellcode

    1. func sqliteDateTimeStringToDate(_ string:String)->Date {
    2. let dateFormatter = DateFormatter()
    3. dateFormatter.dateFormat = "yyyy-MM-dd'T'hh:mm:ss"
    4. dateFormatter.locale = Locale(identifier: "de_DE")
    5. let date = dateFormatter.date(from: string)
    6. return date!
    7. }
    hat leider nicht geholfen.
  • matz schrieb:

    MCDan schrieb:

    Wahrscheinlich hast Du bei dem DateFormatter locale nicht gesetzt. ;)

    Interessant ist allerdings, warum die App abstürzt? ?(

    Eigentlich sollte date(from:) nil zurück liefern, wenn der String nicht in ein Datum konvertiert werden kann.

    Wie sieht denn die Ausgabe beim Crash aus?
    Natürlich knallt es durch das Force Unwrap und nil ;)
    Was ist ein Force Unwrap ?( und wieso crasht dann die App?
  • MCDan schrieb:

    Was ist ein Force Unwrap ?( und wieso crasht dann die App?
    Ein Force Unwrap hast du, wenn dein Datentyp ein Optional ist (somit kann was drin stehen muss aber nicht) du aber mit ! explizit einen Wert haben willst. Wenn die Variable jetzt aber Nil ist, dann gibt es keinen Wert und die App raucht dir ab. Weil das ist dann halt kein Optional mehr und somit darf auch kein Nil mehr vorkommen.
  • Hm, im 1. Source Code sehe ich kein "!", also kein Force Unwrap. Entweder hat Qvex23 dies beim Kopieren des Source Codes in den Thread gelöscht, oder es war im 1. Source Code noch nicht drin. Im 2. Source Code ist es dann allerdings drin.

    Wenn es im 1. Source Code also noch nicht drin war, gab es kein Force Unwrap und die Frage bleibt, warum die App abgestürzt ist.

    Laut Aussage der Entwickler soll Swift ja "safe by design" sein. Wie passt dann bitte ein Crash zur Laufzeit wenn ein Force Unwrap nicht klappt? So etwas würde ich ja eher als Designfehler und nicht als "safe by design" bezeichnen.

    Ich bin ja immer noch daran interessiert die Vorteile von Swift zu erkennen. Ein Crash zur Laufzeit wenn ein Force Unwrap nicht klappt sehe ich jetzt nicht unbedingt als Vorteil einer Programmiersprache, Crashes sollte ja eher verhindert werden, oder? Die Verwendung von Force Unwrap macht für mich somit erst mal keinen Sinn, da mir das Risiko eines Crashes der App zu groß wäre. Vielleicht sehe ich auch das große Ganze noch nicht und es ist bei Swift besser eine App zu beenden, als mit "falschen" Werten zu arbeiten. Die ggf. vorhandene Phi­lo­so­phie kann ich aber auch nicht so recht teilen.
  • MCDan schrieb:

    Wenn es im 1. Source Code also noch nicht drin war, gab es kein Force Unwrap und die Frage bleibt, warum die App abgestürzt ist.
    Der erste Code wird so sicherlich nicht funktioniert haben.

    developer.apple.com/documentat…ateformatter/1409994-date

    Da kommt ein Optional zurück, seine Funktion hat aber kein Optional geliefert, das

    Quellcode

    1. !

    hat er also vergessen zu erwähnen bzw. zu schreiben.

    MCDan schrieb:

    Laut Aussage der Entwickler soll Swift ja "safe by design" sein. Wie passt dann bitte ein Crash zur Laufzeit wenn ein Force Unwrap nicht klappt? So etwas würde ich ja eher als Designfehler und nicht als "safe by design" bezeichnen.
    Dafür gibt es ja if let und guard let, damit so etwas nicht passiert.

    Ja ich weiß, Apple nutzt selbst bei Outlets als Standard Force Unwrap und auch da knallt es dann wunderbar wenn das Outlet nicht verbunden ist.

    Ich finde die Konzepte an sich nicht schlecht.
  • matz schrieb:

    Ja ich weiß, Apple nutzt selbst bei Outlets als Standard Force Unwrap und auch da knallt es dann wunderbar wenn das Outlet nicht verbunden ist.
    Und das ist auch gut so, denn das Programm wird ohne verbundenes Outlet in der Regel auch relativ nutzlos sein.

    MCDan schrieb:

    Ich bin ja immer noch daran interessiert die Vorteile von Swift zu erkennen.
    Dabei könnte helfen, sich auch mal mit Swift näher zu beschäftigen, also auch mal damit was zu machen und nicht nur die Keynote-Sprüche von damals immer wieder zu wiederholen. Klar ist nicht alles toll an Swift, aber eben auch nicht alles schlecht.

    MCDan schrieb:

    Ein Crash zur Laufzeit wenn ein Force Unwrap nicht klappt sehe ich jetzt nicht unbedingt als Vorteil einer Programmiersprache, Crashes sollte ja eher verhindert werden, oder?
    Auch Swift kann nicht alle Programmierfehler dieser Welt verhindern. Und wer davon ausgeht, dass eine Funktion immer einen gültigen Wert zurückgibt, obwohl in der Dokumentation steht, dass es auch schief gehen kann, der hat den Crash auch verdient. ;)
    So mancher Programmierfehler fällt auch eher auf, wenn das Programm schon während der Entwicklung abschmiert, statt vielleicht nur eine unvollständige Anzeige zu machen, die dann möglicherweise erst dem Endanwender auffällt. Crashs sind nicht immer schlecht.
  • Wow, was ging denn hier ab? Irgendwie kamen keine Emailbenachrichtigungen zu dem Thread.

    Ich muss ganz ehrlich zugeben, ich mache immer dann ein force Unwrap wenn XCode das Anmeckert :whistling:
    Ich glaube mir fehlen da noch einige Grundlagen, aber kann man ja alles irgendwie lernen.

    Ich mag Swift alleine schon wegen der Syntax gerne. Derzeit schreibe ich die App an der ich arbeite um von ObjC zu Swift, so zum lernen quasi. Und immer wenn ich in ObjC rein schaue, sehe ich nur einen Klammer Wald.
  • MCDan schrieb:

    Die locale beim DateFormatter wird sowohl für die Umwandlung von Date zu String, als auch von String zu Date verwendet.

    Von daher sollte man sie immer passend setzen, auch wenn man nur Stings in Daten umwandelt.

    Ggf, solltest Du im DateFormatter auch die timeZone setzen, damit es keine Probleme bei den Uhrzeiten gibt. ;)
    Also hier brauche ich mehr Infos. Das iDevice kann ja in irgendeiner Zeitzone sein und weiß der Geier was für eine Uhrzeit haben. Wie bekomme ich es hin, das ein Anwender seine Zeitzone und seine Uhrzeit eingetragen bekommt? Das statische setzen einer Zeitzone ist doch sicher keine Lösung dafür, oder?

    MCDan schrieb:

    Hm, im 1. Source Code sehe ich kein "!", also kein Force Unwrap. Entweder hat Qvex23 dies beim Kopieren des Source Codes in den Thread gelöscht, oder es war im 1. Source Code noch nicht drin. Im 2. Source Code ist es dann allerdings drin.

    Wenn es im 1. Source Code also noch nicht drin war, gab es kein Force Unwrap und die Frage bleibt, warum die App abgestürzt ist.

    Laut Aussage der Entwickler soll Swift ja "safe by design" sein. Wie passt dann bitte ein Crash zur Laufzeit wenn ein Force Unwrap nicht klappt? So etwas würde ich ja eher als Designfehler und nicht als "safe by design" bezeichnen.

    Ich bin ja immer noch daran interessiert die Vorteile von Swift zu erkennen. Ein Crash zur Laufzeit wenn ein Force Unwrap nicht klappt sehe ich jetzt nicht unbedingt als Vorteil einer Programmiersprache, Crashes sollte ja eher verhindert werden, oder? Die Verwendung von Force Unwrap macht für mich somit erst mal keinen Sinn, da mir das Risiko eines Crashes der App zu groß wäre. Vielleicht sehe ich auch das große Ganze noch nicht und es ist bei Swift besser eine App zu beenden, als mit "falschen" Werten zu arbeiten. Die ggf. vorhandene Phi­lo­so­phie kann ich aber auch nicht so recht teilen.
    Tatsächlich, im ersten Quellcode ist ein ! am Return, im zweiten nicht..... seltsam. Ist wohl beim Pasten aus der Zwischenablage gefallen :P . Im derzeitigen Quellcode ist der Wert aber force unwrappred, weil ich sonst anstelle
    von "01.01.2001 18:59" ein "Optional("01.01.2001 18:59")" als String bekommen. Wer auch immer sowas braucht, für mich macht es gerade irgendwie keinen sinn solch einen String zu erhalten.

    Danke für alle Hilfe

    Gruß

    Dirk
  • Qvex23 schrieb:

    MCDan schrieb:

    Die locale beim DateFormatter wird sowohl für die Umwandlung von Date zu String, als auch von String zu Date verwendet.

    Von daher sollte man sie immer passend setzen, auch wenn man nur Stings in Daten umwandelt.

    Ggf, solltest Du im DateFormatter auch die timeZone setzen, damit es keine Probleme bei den Uhrzeiten gibt. ;)
    Also hier brauche ich mehr Infos. Das iDevice kann ja in irgendeiner Zeitzone sein und weiß der Geier was für eine Uhrzeit haben. Wie bekomme ich es hin, das ein Anwender seine Zeitzone und seine Uhrzeit eingetragen bekommt? Das statische setzen einer Zeitzone ist doch sicher keine Lösung dafür, oder?
    Du muss die Zeitzone passend zu der Zeitzone einstelle, die bei der Erstellung des Datum Stings verwendet wurde.

    Ich tippe jetzt einfach mal, dass bei dem Datum String die Zeit in UTC ist. Somit musst Du für die Umwandlung dieses Datum String in ein Date natürlich auch UTC als timeZone verwenden.

    Probiere einfach mal verschiedene Einstellungen für die timeZone aus und lasse Dir das ermittelte Datum in der Console ausgeben. Da solltest Du schön erkennen, wie sich die eingestellte timeZone auf das Datum auswirkt.