Problem mit Übergabe Datumsfunktion

    • Offizieller Beitrag

    Im Modul times sind alle notwendigen Funktionen für Datumsoperationen enthalten. Ich habe mir nun eine Prozedur erstellt, mit der ich variabel die Funktion für die Datumsoperation übergeben kann ('years', 'months', 'weeks', 'days') und Integer als Werte für Monat und Tag übergeben kann. Das ist deshalb sinnvoll, damit ich mit der Vorbelegung '-1' den aktuellen Datumswert übernehmen kann. -1 ist aber kein gültiger Wert für die Datentypen 'Month' und 'MonthdayRange'.


    Das funktioniert soweit zufriedenstellend, nur werden die Funktionen 'weeks' und 'days' als Parameter nicht erkannt. Da habe ich keine Erklärung für.

    • Offizieller Beitrag

    Das funktioniert soweit zufriedenstellend, nur werden die Funktionen 'weeks' und 'days' als Parameter nicht erkannt. Da habe ich keine Erklärung für.

    Das liegt daran, dass die beiden Funktionen zwei Mal vorhanden sind (einmal mit TimeInterval und einmal mit Duration).

    Du musst den Aufruf quasi zu dem TimeInterval zwingen:

    • Offizieller Beitrag

    Du musst den Aufruf quasi zu dem TimeInterval zwingen:

    :thumbup: Danke, das war des Pudels Kern.



    Mal noch ein weiteres Problem. Ich wollte die Funktion jetzt absichern, um nicht valide Datumseingaben abzufangen.

    Laut Typbeschreibung von MonthdayRange ist 0 als Wert valide und repräsentiert ein ungültiges Datum


    0 represents an invalid day of the month


    initDateTime mit ungültigem Datumswert (z.B. "29.02.2019") führt zu einem "AssertionError". Somit war meine Überlegung, dass ich bei Auftreten dieses Fehlers ein DateTime erstelle mit 0 als Wert für den Tag, um daran den Fehler zu erkennen. Jedoch werden bei dem falschen Datum Tag und Monat ignoriert und durch 31.01. ersetzt, nur das Jahr wird akzeptiert. Daraufhin habe ich für das Jahr einfach 0 in der Fehlerroutine genutzt und bekomme zumindest ein ordentlich falsches ^^ Ergebnis, dass sich auswerten läßt. Aber ob das so soll? :whistling:


    Errorhandling ist tatsächlich etwas, wo man durch AutoIt verwöhnt ist. Es gibt kein Errormakro und somit ist das Signalisieren von Fehlern recht umständlich. Aber: Man kann nicht alles haben.

    • Offizieller Beitrag

    Errorhandling ist tatsächlich etwas, wo man durch AutoIt verwöhnt ist. Es gibt kein Errormakro und somit ist das Signalisieren von Fehlern recht umständlich. Aber: Man kann nicht alles haben.

    Du könntest das Datum doch auch in einer eigenen Funktion überprüfen:

    Code
    import times
    
    proc dateIsValid(y, m, d: int): bool =
      const aDays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
      if not (y in 1000..2999): return false
      if not (m in 1..12): return false
      if not (d in 1..aDays[m] + (if m == 2 and isLeapYear(y): 1 else: 0)): return false
      return true
    
    echo "Date is valid: ", dateIsValid(2021, 2, 29)

    Edit: Da war noch ein kleiner Fehler drin. Ich hatte das "+1" mit im Array-Index. Behoben!

    • Offizieller Beitrag

    Du könntest das Datum doch auch in einer eigenen Funktion überprüfen:

    Ja klar (geht übrigens kürzer ;) )

    Code
    import times
    
    proc dateIsValid(year, mon, day: int): bool =
      if day > 0 and day <= getDaysInMonth(cast[Month](mon), year): return true
      else: return false

    Aber mir ging es darum, dass ich von meiner dateAdd-Funktion den Rückgabetyp DateTime bekomme. Da kann ich bei interner Prüfung nicht plötzlich "false" zurückgeben. Ich muss die Fehlermeldung also im erwarteten Datentyp unterbringen. Mit Jahr=0 setzen habe ich eine sichere Fehlerabfragemöglichkeit, aber ein SetError/If @error, wie in AutoIt wäre halt "schöner".

    Vielleicht bastele ich mir auch meine eigene Fehlervariable. Hätte auch den Vorteil, dass ich beim Setzen der Variablen kpl. Fehlertexte hinterlegen könnte.

    • Offizieller Beitrag

    Ja klar (geht übrigens kürzer ;) )

    Naja, Du testest ja auch nur den Tag, aber mit getDaysInMonth geht's wirklich kürzer:

    Code
    import times
    
    proc dateIsValid(y, m, d: int): bool =
      result = if (y in 1000..2999) and (m in 1..12) and
        (d in 1..getDaysInMonth(cast[Month](m), y)): true else: false
    
    echo "Date is valid: ", dateIsValid(2020, 2, 29)
    • Offizieller Beitrag

    Aber mir ging es darum, dass ich von meiner dateAdd-Funktion den Rückgabetyp DateTime bekomme. Da kann ich bei interner Prüfung nicht plötzlich "false" zurückgeben. Ich muss die Fehlermeldung also im erwarteten Datentyp unterbringen.

    Ich dachte an ein "Fehler-Datum" (z.B. 01.01.0001):

    • Offizieller Beitrag

    Naja, Du testest ja auch nur den Tag, aber mit getDaysInMonth geht's wirklich kürzer

    Obs ein Schaltjahr ist, prüft getDaysInMonth bereits. Und alle anderen Prüfungen der Jahreszahlen sind m. M. nach Humbug. In der Historie ist nicht wirklich bekannt wer wann und wo welchen Kalender genutzt hat und wann "die Zeit des Jahreszählens" begann. Wer weiß, vielleicht hatte ja einer meiner Ur-Ur-Ahnen eines Tages den Gedanken und sagte: "He Leute, ich hab eine brilliante Idee - wir zählen ab heute die Zeit und jetzt ist das Jahr Nummer 1.":rofl:

    Und für die ferne Zukunft ist es auch völlig schnuppe, ob es vielleicht in 3000 Jahren zu einer Schaltjahresverschiebung kommt oder nicht.

    Insofern kann jede Jahreszahl als valide angenommen werden. Tut keinem weh. :D

    • Offizieller Beitrag

    Insofern kann jede Jahreszahl als valide angenommen werden. Tut keinem weh.

    Ja, ok! Das Jahr könnte man weglassen (wobei die Jahre ab 1000 wohl als "gesichert" gelten, davor gab es ja einige "Meinungsverschiedenheiten" bei den Päpsten).

    Aber den Monat solltest Du schon testen, denn getDaysInMonth prüft den nicht.

    Code
    import times
    
    proc dateIsValid(y, m, d: int): bool =
      result = if (m in 1..12) and
        (d in 1..getDaysInMonth(cast[Month](m), y)): true else: false
    
    echo dateIsValid(2020, 2, 29)