pdvm_datetime-1

pdvm_datetime.py - Teil 1

Aus Gründen der Größe der Seiten werden hier alle internen Funktionalitäten der pdvm_datetime dargestellt und beschreiben. Die Pfeile nach Oben gehen auf den Beginn der Originalseite. Von dort sind alle Abschnitte erreichbar. Die Pfeile nach links gehen auf die Basisseite der pdvm_datetime.

__pdvmdatime()

Beschreibung
    # --------------------------------------------------------------------
    # __pdvmdatime(jahr,monat,tag,stunde,minute,sekunde,microsekunde)
    # Eigenschaften der Klasse werden gesetzt, bzw. berechnet
    # --------------------------------------------------------------------
    def __pdvmdatime(self,year=0,month=0,day=0,hour=0,minute=0,second=0,microsecond=0):
        self.year        = year         # Jahr
        self.month       = month        # Monat
        self.day         = day          # Tag im Monat
        self.hour        = hour         # Stunde im Tag
        self.minute      = minute       # Minute in der Stunde
        self.second      = second       # Sekunde in der Minute
        self.microsecond = microsecond  # Microsekunde

        self.pdvmdatetime = self.__convertToPdvmDateTime(year,month,day,hour,minute,second,microsecond)

        self.pdvmtime = float(str(self.pdvmdatetime)[str(self.pdvmdatetime).find("."):])
        self.__svalue()

        return self.pdvmdatetime

__pdvmdatime - Beschreibung

Source
Über die Eingabewerte von Jahr, Monat, Tag, Stunde, Minute, Sekunde, Microsekunde werden die Eigenschaften im Objekt gesetzt. Werden nicht alle Werte mitgegeben, so werden die fehlenden Werte mit 0 angenommen.

Ablauf
  • die Eigenschaften für die einzelnen Datum- und Zeitwerte werden gesetzt.
  • über __convertToTdvmDateTime wird die Eigenschaft pdvmdatetime gesetzt
  • Die Eigenschaft pdvmtime wird einfach durch das Abtrennen des Datums gesetzt
  • interne Eigenschaften werden über __value() gesetzt. eigene Funktion, da diese zwei mal verwendet wird.
  • pdvmdatetime wird zurückgegeben
Es ist die grundlegende Funktion zum Setzen eines Timestamp im Objekt.

__pdvmDateInDateSplit()

Beschreibung
    # --------------------------------------------------------------------
    # PdvmdateTime zerlegen
    # --------------------------------------------------------------------
    def __pdvmDateInDateSplit(self):
        ret = self.__splitPdvmDate(self.pdvmdatetime)
        self.year  = ret[0]
        self.month = ret[1]
        self.day   = ret[2]
        self.pdvmtime = float(str(self.pdvmdatetime)[str(self.pdvmdatetime).find("."):])
        cfntmsec    = int(self.pdvmtime * self._tag)     # Microsekunden des Tages
        xistd       = round(cfntmsec / self._stunde,4)         # Stunden mit Rest
        self.hour   = int(xistd)                      # Stunden des Tages
        reststd     = cfntmsec % self._stunde         # Rest Microsekunden
        ximin       = round(reststd / self._minute,4) # Minuten mit Rest
        self.minute = int(ximin)                      # Minuten der Stunde
        restmin     = reststd % self._minute          # Rest Microsekunden
        xisec       = round(restmin / self._sekunde,4)# Sekunden mit Rest
        self.second = int(xisec)                      # Sekunden der Minute
        if self.second==60:                           # Korrektur Ungenauigkeit
            self.second = 0                           #    bei Ursprungswert 0
        restsec     = restmin % self._sekunde         # Rest Microsekunden
        self.microsecond     = int(restsec)           # Microsekunden der Sekunde
        if self.microsecond > 999000:                 # Korrektur Ungenauigkeit
            self.microsecond = 0                      #    bei Ursprungswert 0
          
        self.__svalue()

        return self.dtt

__pdvmDateInDateSplit() - Beschreibung

Source
Mit dieser Funktionalität wird die Eigenschaft pdvmdatetime in die Einzelteile des Datums und der Zeit zerlegt.

Ablauf
  • Mit __splitPdvmDate() wird das Datum in die Variable ret zerlegt.
  • die Eigenschaften year, month und day werden über ret gesetzt.
  • die Eigenschaft pdvmtime wird über den Nachkommateil von pdvmdatetime gesetzt.
  • die Microsekunden (für den Tag) aus pdvmtime werden errechnet (cfntmsec)
  • die Stunden (mit Rest - gerundet auf 4 Nachkommastellen) werden errechnet (xistd)
  • die Eigenschaft hour wird mit dem Integer aus xistd gesetzt.
  • der Rest Microsekunden (ohne Stunden) wird errechnet (reststd)
  • die Minuten (mit Rest - gerundet auf 4 Nachkommastellen) werden errechnet (ximin)
  • die Eigenschaft minute wird mit dem Integer aus ximin gesetzt.
  • der Rest Microsekunden (ohne Stunden, Minuten ) wird errechnet (restmin)
  • die Sekunden (mit Rest - gerundet auf 4 Nachkommastellen) werden errechnet (xisec)
  • die Eigenschaft second wird mit dem Integer aus xisec gesetzt.
  • Wegen der Ungenauigkeit bei float und vielen Nachkommastellen werden 60 Sekunden auf 0 gesetzt
  • der Rest Microsekunden (ohne Stunden, Minuten, Sekunden ) wird errechnet (restsec)
  • die Eigenschaft microsecond wird mit dem Integer aus restsec gesetzt.
  • Wegen der Ungenauigkeit bei float und vielen Nachkommastellen werden mehr als 999000 Microsekunden auf 0 gesetzt.
  • über __svalue() werden die restlichen Eigenschaften gesetzt
  • die Eigenschaft dtt (Tuple mit Jahr, Monat, Tag, Stunden, Minuten, Sekunden, Microsekunden) wird zurückgegeben.
Es ist die grundlegende Funktion zum Setzen der Eigenschaften im Objekt aus einem pdvmdatetime

__svalue()

Beschreibung
    # --------------------------------------------------------------------
    # Objektwerte
    # --------------------------------------------------------------------
    def __svalue(self):
        # Tuple Datum / Zeiten setzen
        ret = []
        ret.append(self.year)
        ret.append(self.month)
        ret.append(self.day)
        self.dd = tuple(ret)
        ret1 = []
        ret1.append(self.hour)
        ret1.append(self.minute)
        ret1.append(self.second)
        ret1.append(self.microsecond)
        self.dt = tuple(ret1)
        self.dtt = tuple(ret)+tuple(ret1)
        self.period = (self.year * 100) + self.month

        return True

__svalue() - Beschreibung

Source
Die Tuple für Date (Eigenschaft dd), Time (Eigenschaft dt) und DateTime (Eigenschaft dtt) werden gesetzt. Dazu die Eigenschaft period.
Am Ende wird True zurückgegeben.

__lYearFYear()

Beschreibung
    # --------------------------------------------------------------------
    # Schaltjahr ermitteln
    # --------------------------------------------------------------------
    def __lYearFYear(self,year):
        s = 0
        if year != 0:                   # 0 % x immer 0
            r = year % 4                # jedes 4 Jahr --> Schaltjahr
            if r==0:
                r = year % 100          # alle 100 Jahre --> keine Schaltjahr
                if r==0:
                    r = year % 400      # alle 400 Jahre wieder --> Schaltjahr
                    if r==0:
                        s = 1           # Schaltjahr
                    else:
                        s = 0           # kein Schaltjahr
                else:
                    s = 1               # Schaltjahr
            else:
                s = 0                   # kein Schaltjahr

        return  s                       # Rückgabe Ergebnis

__lYearFYear() - Beschreibung

Source
Mit dieser Funktionalität wird ermittelt ob ein Jahr ein Schaltjahr ist oder nicht. Die Entscheidungen hier werden getroffen indem man den Rest aus einer Division ermittelt. Hierbei sind folgende Regeln zu beachten:

  • Jede Jahreszahl die sich durch 4 teilen lässt ist grundsätzlich ein Scchaltjahr
  • dieses trifft jedoch dann nicht zu, wenn sich die Jahrszahl durch 100 teilen lässt.
  • die Ausnahme von der Ausnahme ist dann gegeben, wenn sich die Jahreszahl druch 400 teilen lässt.
Das typische Beispiel aus neuer Zeit ist das Jahr 2000.
  • 2000 ist durch 4 teilbar --> Schaltjahr
  • 2000 ist durch 100 teilbar --> doch kein Schaltjahr
  • 2000 ist durch 400 teilbar --> also Ausnahme von der Ausnahme 2000 ist ein Schaltjahr.
Der Rückgabewert der Funktionalität ist 0 --> kein Schaltjahr und 1 --> Schaltjahr

__checkDate()

Beschreibung
    # -------------------------------------------------------------------------------------
    # Datum prüfen
        # ---------------------------------------------------------------------------------
        # Hinweis: Alle Jahre, auch die vor Chr. (negatives Datum) werden nach den Regeln des
        # -------- gregorianischen Kalenders verarbeitet. Daher macht eine Prüfung auf das
        #          Jahr keinen Sinn und wurde weggelassen.
        # ---------------------------------------------------------------------------------
    # -------------------------------------------------------------------------------------
    def __checkDate(self,year,month,day):
        ok = False

        # Check Month
        if int(month) > 0 and int(month) < 13:
            ok = True
        else:
            printMessage("error",pdvmObjekt,"PDT_010",["def: __checkDate","Monat: " + str(month)], self.language)
     
        # Check Day
        # Der Tag wird genau geprüft, dies bedeutet, dass beim Februar das Schaltjahr
        # geprüft werden muss.
        if ok:
            md = monthdays[int(month)+1][int(self.__lYearFYear(int(year)))]-monthdays[int(month)][int(self.__lYearFYear(int(year)))]
            if int(day)>0 and int(day)<md+1:
                ok = True
            else:
                ok = False
                printMessage("error",pdvmObjekt,"PDT_011",["def: __checkDate", "Tag: " + str(day),"Monat: " + str(month),"Jahr: " + str(year)], self.language)

        return ok

__checkDate - Beschreibung

Source
Mit dieser Funktionalität werden die Tage und Monate zum angegebenen Jahr geprüft. Da wir hier alle Jahre nach den Regeln des gregorianischen Kalenders verarbeiten sind alle Jahre zugelassen. Eine Prüfung des Jahres findet hier daher nicht statt.

Ablauf
  • Der Monat muss größer 0 und kleiner 13 sein. Ist dieses nicht der Fall wird die Fehlermeldung PTD_010 ausgegeben.
  • Beim Tag wird mit Hilfe des Inhalts von monthdays (Initalisierung vor der Klasse) die maximal zulässige Tageszahl zum Monat ermittelt. Der Tag muss kleiner/gleich dieser Tageszahl sein und mindestens die Größe von 1. Anderenfalls wird die Fehlermeldung PTD_011 ausgegeben.
Zurückgegeben wird hier True und False.

__calcDateToForm()

Beschreibung
    # --------------------------------------------------------------------
    # Date (ohne Trenner) nach Spezifikation in Jahr / Monat / Tag konvertieren
    # --------------------------------------------------------------------
    def __calcDateToForm(self, datein, dlen):
        year  = 0
        month = 0
        day   = 0

        # Jahr ermitteln
        ayear2 = self.GetAYear2
        ajh2   = self.GetAYearH2
        if dlen == 8:
            year = datein[posYear[dlen][self.dateYearPos][0]:posYear[dlen][self.dateYearPos][1]]
        elif dlen == 6:
            year = datein[posYear[dlen][self.dateYearPos][0]:posYear[dlen][self.dateYearPos][1]]
            if (int(ayear2)+5) < int(year):
                year = str(((int(ajh2) - 1)*100)+int(year))
            else:
                year = str((int(ajh2)*100)+int(year))
        elif dlen == 4:
            year = self.GetAYear
        else:
            # darf hier nie ankommen / Sicherheit
            printMessage("error",pdvmObjekt,"PDT_012",["def: __calcDateToForm","Länge: " + str(dlen)], self.language)

        # Monat ermitteln
        month = datein[posMonth[dlen][self.dateMonthPos][0]:posMonth[dlen][self.dateMonthPos][1]]

        # Tag ermitteln
        day = datein[posDay[dlen][self.dateMonthPos][0]:posDay[dlen][self.dateMonthPos][1]]

        return year, month, day

__calcDateToForm - Beschreibung

Source
Hier wird ein Datumstring aus der Eingabe bzw. Analyse übergeben, dazu aus Gründen der Sicherheit auch die Länge mit der gearbeitet wird. Der String darf auch keine Trennzeichen enthalten.

Ablauf:
  • Die Ausgabevariablen year, month, day werden initalisiert.
  • Das aktuelle Jahr(2 Stellen) und Jahrhundert(2 Stellen) werden ermittelt.
  • Mit Hilfe von posYear und self.dateYearPos wird das Jahr(year) aus dem String ermittelt.
  • Hat das Jahr nur zwei Stellen wird für die nächsten 5 Jahre, das aktuelle Jahrundert und sonst das vorherige Jahrhundert hinzugefügt.
  • Mit Hilfe von posMonth und self.dateMonthPos wird der Monat(month) aus dem String ermittelt.
  • Mit Hilfe von posDay und self.dateDayPos wird der Tag(day) aus dem String ermittelt.
Rückgabe: (Jahr, Monat, Tag)

__upDown()

Beschreibung
    # --------------------------------------------------------------------
    # __upDown   --- Para 1 --> auf Max // Para 2 --> Überlauf // Max
    # --------------------------------------------------------------------
    def __upDown(self,s,z,m):
        while s > m:
            s -= m
            z  += 1
        while s < 1:
            s += m
            z  -= 1
        return (s,z)

__upDown() - Beschreibung

Source
Hiermit wird ein Überlauf bestimmt. Als Parameter werden übergeben (Zahl, Eingabewert, Maximal). Zurück gegeben werden die korrigierte Zahl und Eingabewert.

Beispiel bei Überlauf von Monaten:

__upDown(2019, 16, 12) --> also der Monat 16 im Jahr 2019 (ein Jahr hat aber max. 12 Monate.
Rüclgabe (2020,4)

umgekehrt:
__upDown(2019, -2, 12) -- also der Monat -2 im Jahr 2019
Rückgabe (2018,10)

__splitPdvmDate()

Beschreibung
    # --------------------------------------------------------------------
    # __splitPdvmDate   PdvmDate wird in year,month,day zerlegt
    # --------------------------------------------------------------------
    def __splitPdvmDate(self,pdvmdate):
        if pdvmdate > 1000:
            yday = int(pdvmdate % 1000)               # Tage im Jahr
            year = int((pdvmdate - yday) / 1000)      # Jahr
            s = self.__lYearFYear(year)               # Schaltjahr
            ret = 0
            for i in range(13,-1,-1):
                if int(yday) < monthdays[i][s]+1:
                    pass
                else:
                    if ret==0:
                        ret = i
                        mfndays_e = monthdays[i][s]
                        break
            month  = ret                           # Monat
            day    = int(yday - mfndays_e)         # Tag
        else:
            year  = 0
            month = 0
            day   = 0
        return (year,month,day)

__splitPdvmDate - Beschreibung

Source
Das PdvmDate wird in Jahr, Monat, Tag zerlegt.

Ablauf:
  • Der Rest aus dem Teiler von 1000 ergeben die Tage im Jahr
  • Datum - den Tagen geteilt durch 1000 ergibt das Jahr
  • aus dem Jahr wird das Schaltjahr bestimmt
  • über monthdays wird in einer Schleife der Monat ermittelt
  • Damit kann auch der Tag des Monats errechnet werden
Rückgabe: (Jahr, Monat, Tag)

__splitPdvmDateTime()

Beschreibung
    # --------------------------------------------------------------------
    # __splitPdvmDateTime  PdvmdateTime (Differenz) wird in alle Teile zerlegen
    # --------------------------------------------------------------------
    def __splitPdvmDateTime(self, pdvmdatetime):
        ret = self.__splitPdvmDate(pdvmdatetime)
        year  = ret[0]
        month = ret[1]
        day   = ret[2]
        pdvmtime  = float(str(pdvmdatetime)[str(pdvmdatetime).find("."):])
        cfntmsec  = int(pdvmtime * self._tag)        # Microsekunden des Tages
        xistd     = round(cfntmsec / self._stunde,4) # Stunden mit Rest
        hour      = int(xistd)                       # Stunden des Tages
        reststd   = cfntmsec % self._stunde          # Rest Microsekunden
        ximin     = round(reststd / self._minute,4)  # Minuten mit Rest
        minute    = int(ximin)                       # Minuten der Stunde
        restmin   = reststd % self._minute           # Rest Microsekunden
        xisec     = round(restmin / self._sekunde,4) # Sekunden mit Rest
        second    = int(xisec)                       # Sekunden der Minute
        if self.second==60:                          # Korrektur Ungenauigkeit
            self.second = 0                          #    bei Ursprungswert 0
        restsec   = restmin % self._sekunde          # Rest Microsekunden
        microsecond  = int(restsec)                  # Microsekunden der Sekunde
        if microsecond > 999000:                     # Korrektur Ungenauigkeit
            microsecond = 0                          #    bei Ursprungswert 0
         
        return (year,month,day,hour,minute,second)

__splitPdvmDateTime() - Beschreibung

Source
Diese Funktionalität ist fast identisch mit "__pdvmDateInDateSplit()" mit dem einen Unterschied, dass hier nicht die Werte im Objekt gesetzt werden sondern eine Rückgabe in der Form von (year,month,day,hour,minute,second) erfolgt. Die Werte des Objekts werden damit nicht verändert. Erforderlich ist diese, da ich Differenzen innerhalb des Objekts bestimme, also den Differenzwert separat splitte. Ein eigenes Objekt dafür ging natürlich auch. Ich habe es halt mal so gelöst.

Ablauf

  • Mit __splitPdvmDate() wird das Datum in die Variable ret zerlegt.
  • die Eigenschaften year, month und day werden über ret gesetzt.
  • die Eigenschaft pdvmtime wird über den Nachkommateil von pdvmdatetime gesetzt.
  • die Microsekunden (für den Tag) aus pdvmtime werden errechnet (cfntmsec)
  • die Stunden (mit Rest - gerundet auf 4 Nachkommastellen) werden errechnet (xistd)
  • die Eigenschaft hour wird mit dem Integer aus xistd gesetzt.
  • der Rest Microsekunden (ohne Stunden) wird errechnet (reststd)
  • die Minuten (mit Rest - gerundet auf 4 Nachkommastellen) werden errechnet (ximin)
  • die Eigenschaft minute wird mit dem Integer aus ximin gesetzt.
  • der Rest Microsekunden (ohne Stunden, Minuten ) wird errechnet (restmin)
  • die Sekunden (mit Rest - gerundet auf 4 Nachkommastellen) werden errechnet (xisec)
  • die Eigenschaft second wird mit dem Integer aus xisec gesetzt.
  • Wegen der Ungenauigkeit bei float und vielen Nachkommastellen werden 60 Sekunden auf 0 gesetzt
  • der Rest Microsekunden (ohne Stunden, Minuten, Sekunden ) wird errechnet (restsec)
  • die Eigenschaft microsecond wird mit dem Integer aus restsec gesetzt.
  • Wegen der Ungenauigkeit bei float und vielen Nachkommastellen werden mehr als 999000 Microsekunden auf 0 gesetzt.
  • über __svalue() werden die restlichen Eigenschaften gesetzt
  • die Eigenschaft dtt (Tuple mit Jahr, Monat, Tag, Stunden, Minuten, Sekunden, Microsekunden) wird zurückgegeben.
Rückgabe: (Jahr, Monat, Tag, Stunde, Minute, Sekunde)

__convertToPdvmDateTime()

Beschreibung
    # --------------------------------------------------------------------
    # __convertToPdvmDateTime   --- Einzelzeiten geben PdvmDateTime zurück
    # --------------------------------------------------------------------
    def __convertToPdvmDateTime(self,year,month,day,hour,minute,second,microsecond):
        # calc Tag im Jahr
        self.yday = self.__calcToDayInYear(year, month, day)

        # PdvmDate setzen
        self.pdvmdate = (year * 1000) + self.yday

        # PdvmDateTime setzen
        # gesamter Zeitwert als Microsekunde
        zeitwert = ((hour * self._stunde) + (minute * self._minute) +
                    (second * self._sekunde) + microsecond)
        # Microsekundenwert auf Tage
        timevalue = zeitwert / self._tag
   
        pdvmdatetime = timevalue + self.pdvmdate

        return pdvmdatetime

__convertToPdvmDateTime - Beschreibung

Source
Aus den Einzelwerte wie Jahr, Monat, Tag, Stunde, Minute, Sekunde, Microsekunden wird hier ein PdvmDateTime gebildet. Dieses ist dann auch der Rückgabewert.

Ablauf:
  • aus Jahr, Monat und Tag wird mit __calcToDayInYear() der Tag im Jahr errechnet
  • mit Jahr und Tag im Jahr wird dann das pdvmdate gebildet
  • über die fixen Faktoren für Stunden, Minuten, Sekunden und dazu den Mikrosekunden wird der Zeitwert gebildet.
  • der Zeitwert wird durch den Faktor für den Tag geteit (die angegebenen Größen können ja das vielfache eines Tages sein)
  • Jahreswechsel??  -- derzeit noch ein Bug, wenn zuviele Tage entstehen... Logik muss geändert werden.
  • Zeitwert + Datum ergeben den PdvmDateTime
Rückgabe: PdvmDateTime
Share by: