2017-04-10 3 views
0

Ich muss ein bestimmtes Array von Daten testen, um sicherzustellen, dass sie im richtigen Format sind, aber ich kann nicht 'parse' verwenden, wenn ich dies tue, sind die Daten falsch aussortiert. Zum Beispiel, wenn ich ein falsches Datum mit einem Monat „13“ haben, fügt er noch ein Jahr und setzt den Monat 1.So testen Sie bestimmte Daten, die nicht analysiert werden können

Mein Code zieht in den Daten aus einer SQL-Abfrage:

table_birth_dates = self.class.connection.execute("SELECT birth_date FROM #{temp_table_name}").values.flatten 

[ 
    [0] "1980-30-54", 
    [1] "1980-30-54", 
    [2] "2020-09-10", 
    [3] "1890-10-30" 
] 
yr = 1900 
year_test = table_birth_dates.select{|d| Date.parse(d).year < yr} 

Diese jetzt gibt mir eine ArgumentError: invalid date.

ich daran gedacht, mit:

splitted_birth_date = table_birth_dates.first.split("-") 
splitted_birth_date.first.to_i > 1900? 

aber wenn ich eine Schleife durch alle meine Daten versuchen, ich bin nicht in der Lage etwas über Spaltung zu manipulieren:

table_birth_dates.each do |birth_date| 
    birth_date.split("-") 
end 

Was kann ich tun mit diesem?

Antwort

0

Ich brauche eine bestimmte Anordnung der Daten zu testen, um sicherzustellen, dass sie in das richtige Format haben ...

Wenn Sie einen Fehler bedeutet dies, dass das Datum falsch ist, könnten Sie retten Dieser Fehler und alles, was Sie wollen mit diesem Datum, um es gültig oder was auch immer.

table_birth_dates.each do |birth_date| 
    begin 
    if Date.parse(d).year < yr 
     # do smth 
    end 
    rescue ArgumentError => e 
    # do smth with `d` 
    end 
end 
+0

„Wenn Sie eine Fehlermeldung erhalten, bedeutet es, dass das Datum falsch ist“. Nicht unbedingt. Es könnte auch bedeuten, dass der Datumsparser das falsche Format gewählt hat. Es gibt viele mehrdeutige Daten, die als das richtige Format erscheinen, aber die Werte passen nicht. Aus diesem Grund verwenden wir 'Parse 'nur, wenn wir sicher sind, dass jedes Datum einen Sinn ergibt. Wenn wir das nicht garantieren können, müssen wir andere Tests verwenden, um zu versuchen, das Format zu bestimmen und irgendwelche Daten abzulehnen, die wir nicht herausfinden können. 'parse' ist praktisch, aber es ist auch langsam und nicht immer richtig, und es ist schwer zu verfolgen, dass es ein ungültiges analysiertes Datum zurückgibt. –

+0

@theTinMan Ich sehe. Wäre es schlauer, jedes Datum gegen die Regexp zu testen und dann zu tun, was immer sie wollen? Zum Beispiel: '(? \ d {4}) - (? \ d {2}) - (? \ d {2})' Oder benutzen Sie einfach '# split' wie sie versucht haben ... – DiodonHystrix

+0

Weder Ansatz ist in der Lage, Ihnen zu sagen, ob ein Feld ein Monat oder ein Tag ist. Sie können ziemlich sicher davon ausgehen, dass ein Datum in Jahr, Monat und Tag formatiert werden kann, aber die Trennzeichen können variieren. Und leider ist das Internet voll von "Programmierern", die die Datumsstandards ignorieren oder ignorieren, also müssen Sie die Quelle defensiv überprüfen. Wenn Sie ihnen vertrauen können, können Sie nachsichtigeren Code schreiben. Wenn Sie dann nicht defensiv sein können, erwarten Sie Fehler in den Fällen, die Sie nicht vorhergesehen haben. Sie könnten die Daten nach Ausreißern suchen, um die richtige Anpassung zu finden ... –

0

Sie könnten kombinieren Ihre select und split nähert sich zusammen:

table_birth_dates.select { |d| d.split('-').first.to_i < 1900 } 
#=> ["1890-10-30"] 
Verwandte Themen