Source_pdvm_datetime.py

pdvm_datetime.py (Source)

Einstellungen

Beschreibung
# pdvm_datetime.py
""" Klasse für das Zeitformat pdvmdatetime. Das Datum und die Zeit werden hier
    verwaltet. Das Datum ist eine 7-stelliger Integer (YYYYDDD), die Zeit ist
    der Prozentfaktor eines Tages hinter dem Komma. Zum Beispiel 0,5 sind
    12 Stunden bzw. 12 Uhr

    Es sind weiterhin Kalenderfunktionen bzw. Kalenderwerte in der Klasse
    verfügbar.

    Neu zusammengestellt:
    01.08.2019 Norbert Peters
    07.10.2019 überarbeitet
"""
# -----------------------------------------------------------------------
from numbers import Number                             # Wird zur Prüfung numerischer Werte verwendet
from pdvm_util import printMessage
from pdvm_langtext import transkateone, transkate      # Für Übersetzung Texte
from django.conf import settings                       # Standardeinstellungen immer aus den Settings
import time                                            # Wird benutzt um die aktuelle Zeit zu ermitteln

# E i n s t e l l u n g e n
# ================================================================================
pdvmObjekt = "Pdvm_DateTime"                # Objektnamen in pdvm_system
try:
    st_language = settings.LANGUAGE_CODE    # verwendete Standardsprache
except:
    st_language = 'de-de'
try:
    st_time = settings.TIME_CODE             # verwendeter Ländercode
except:
    st_time = 'DIN'

# Anzahl der Tage einzelner Monate
monthdays = [[0,0],[0,0],[31,31],[59,60],[90,91],[120,121],[151,152],[181,182],
         [212,213],[243,244],[273,274],[304,305],[334,335],[365,366]]

# Position der Ausgabe des Datums in verschiedenen Formaten
outpos = {     
    0:{           
        1:(0,1,2),              # 0 -> Jahr // 1 -> Monat  // 2 -> Tag
        2:(0,1,2)               # Position im Datum
    },          
    2:{
        0:(1,2,0),
        1:(2,1,0),
        2:(1,2,0)
    }
}

# Position des Jahres für Splitting Eingabe
posYear = {
    8: {
        0:(0,4),2:(4,8)
    },
    6: {
        0:(0,2),2:(4,6,)
    }
}

# Position des Monats für Splitting Eingabe
posMonth = {
    8: {
        0:(0,2),1:(2,4),2:(4,6)
    },
    6: {
        0:(0,2),1:(2,4),2:(2,4)
    },
    4: {
        0:(0,2),1:(2,4),2:(0,2)
    }
}

# Position des Tages für Splitting Eingabe
posDay = {
    8: {
        0:(2,4),1:(0,2),2:(6,8)
    },
    6: {
        0:(2,4),1:(0,2),2:(4,6)
    },
    4: {
        0:(2,4),1:(0,2),2:(2,4)
    }
}
# -----------------------------------------------------------------------

Einstellungen - Beschreibung

Source
Am Anfang stehen die verwendeten Imports und sind entsprechend kommentiert.

st_language
Für die Ausgabe der Texte wie Tage, Monate und Fehlermeldungen wird zu Beginn die Sprache in die Variable st_language initalisiert. In der Anwendung unter django kommt diese dann aus den Settings. Hier ist zu beachten, dass derzeit nur die Sprachen de-de und en-us verfügbar sind. Tritt hier ein Fehler auf wird die hier eingetragene Standardsprache (de-de) verwendet. Dieses ist zum Beispiel bei der direkten Ausführung der pdvm_datetime.py (für die integrierten Tests)  der Fall. Zu Testzwecken kann diese Sprache auch auf en-us gesetzt weden.

st_time
Für die Ein- und Ausgabe des Datum-/Zeitformates wird ein landesspezifischen Code bzw. DIN (für das DIN Format) benötigt. Dieser wird über die Variable st_time initalisiert. In der Anwendung unter django kommt diese dann aus den Settings. Hier ist zu beachten, dass nur die Formate
DIN --> für das DIN - Format  JJJJ-MM-TT
DEU --> für das deutsche Format TT.MM.JJJJ (ist neben dem DIN Format wieder zugelassen)
ENG --> für das englische Format TT/MM/JJJJ
USA --> für das amerikanische Format MM/TT/JJJJ
zugelassen, bzw. derzeit verfügbar sind.

month_days
Hier werden in einer zweidimensionalen Tabelle die Anzahl der Tage bis zum Ende des jeweiligen Monats angegeben. Der Monat entspricht der Position, der Wert zum Beginn des Monats. Folglich steht die Gesamttageszahl im Monat '13'.
In der zweiten Ausprägung stehen in [0] die Tage im normalen Jahr und in [1] die Tage bei einem Schaltjahr.
Hinweis: Die Eigenschaft Schaltjahr(LYear) gibt  0 --> kein Schaltjahr und  1 --> Schaltjahr zurück.

outpos
Dieses Wörterbuch enthält die Dimension der Ausgabe eines Datums in verschiedenen Formaten. Hierbei ist es so, dass 0 die Position des Jahres, 1 diejenige des Monats und 2 der Tag darstellt.

Die Positionen richten sich nach der eingestellten Folge des Jahres. Steht das Jahr an Position 0, dann ist auch der Key 0 und steht das Jahr an Position 2, dann ist auch der Key 2. Eine Position 1 beim Jahr gibt es bis heute nicht. Der zweite Key bezeichnet das Was gerade zugeordnet wird  (0 -> Jahr // 1 -> Monat  // 2 -> Tag).  - siehe dazu die Eigenschaft Date. ##############

posyear
Es sind Funktionalitäten enthalten (Eigenschaft Date) mit denen man ein Datum einfach als 6- oder 8-stelligen String eingeben kann. Damit dieser String entsprechend der angewendeten Form eingegeben werden kann werden hier die Längen des entsprechenden Strings hinterlegt.

Der 1. Key ist die Länge des gesamten Strings und der 2. Key die Position des Jahres.

posMonth
Der Monat kann in einem String mit den Längen 8, 6 und 4 angegeben werden. Bei der Länge 4 wird das aktuelle Jahr genommen.

Der 1. Key ist die Länge des Strings und der 2. Key die Position des Monats.

posDay
Der Tag kann in einem String mit den Längen 8, 6 und 4 angegeben werden. Bei der Länge 4 wird das aktuelle Jahr genommen.

Der 1. Key ist die Länge des Strings und der 2. Key die Position des Tages.
Neuer Text

Klasse und Initalisierung

Beschreibung
class Pdvm_DateTime(object):

    def __init__(self,fCountry=st_time):
        # konstante Faktoren
        self._tag     = 86400000000      # Microsekunden eines Tages
        self._stunde  = 3600000000       # Microsekunden einer Stunde
        self._minute  = 60000000         # Microsekunden einer Minute
        self._sekunde = 1000000          # Microsekunden einer Sekunde
        # Aufbau Objekt mit Eigenschaften
        self.vChr          = False
        self.pdvmdatetime  = 0
        self.pdvmdate      = 0
        self.pdvmtime      = 0
        self.dd            = []
        self.dt            = []
        self.dtt           = [0,0,0]
        self.PdvmDateTimeT = [0,0,0,0,0,0,0]
        self.PdvmDateT     = [0,0,0]
        self.PdvmTimeT     = [0,0,0,0]
        self.yday          = 0
        self.period        = 0
        self.year          = 0
        self.month         = 0
        self.day           = 0
        self.hour          = 0
        self.minute        = 0
        self.second        = 0
        # Parameter auf Basis von fCountry setzen
        # Form Land vom Datum - werden als Parameter gesetzt
        self.__setFormCountry(fCountry)                      # Die Länderformen DEU / ENG / USA sind vorhanden
        self.proptext = transkate('proptext', self.language) # Übersetzungen der Eigenschaften
                                                             # werden als Wörterbuch eingelesen

Klasse und Initalisierung - Beschreibung

Source
Alle Eigenschaften die hier bereitgestellt werden erfolgen über die Klasse Pdvm_DateTime(). Dieser kann der Ländercode für die Eingabe und Darstellung des Datums mitgegeben werden. Wird kein Code mitgegeben wird in der django App der Wert aus den Settings bezogen. Ist dieser dann auch nicht verfügbar, wird hier 'DIN' genommen.

Anfangs werden dann die einzelnen Einheiten mit Microsekunden versehen. Diese sind dann als Umrechnungswerte direkt vorhanden. Es ist einfacher, als diese jedesmal zu berechnen.

Am Ende der Initlisierung wird dann die Parameter aus dem angegebenen FormCountry mit __setFormCountry() gesetzt. Damit steht dann ein Objekt mit dem Datum und Zeit von 0 zur Verfügung. In der Praxis mussen dann diesem Objekt die entsprechenden Werte gesetzt werden. In welchen Formen und Arten es geschehen kann wird dann im weiteren beschrieben.

FormCountry (Property)

Beschreibung
    # --------------------------------------------------------------------
    # FormCountry
    # --------------------------------------------------------------------
    def __setFormCountry(self, fCountry):
        ckval = ['DIN', 'DEU', 'ENG', 'USA']    # weitere Formate müssen hier
                                                # hinzugefügt werden
        dateSplitter = {'DIN': '-', 'DEU': '.', 'ENG': '/', 'USA': '/'}
        dateYearPos  = {'DIN': 0,   'DEU': 2,   'ENG': 2,   'USA': 2  }
        dateMonthPos = {'DIN': 2,   'DEU': 1,   'ENG': 1,   'USA': 0  }
        monthDayLen  = {'DIN': 2,   'DEU': 2,   'ENG': 2,   'USA': 1  }
        language_in  = {'DIN': 'st-st',   'DEU': 'de-de',   'ENG': 'en-us',   'USA': 'en-us'  }

        ok = False
        fC = fCountry.upper().strip()
        for ck in ckval:
            if ck == fC:
                ok = True
                break
            else:
                ok = False
        if ok:
            self.formCountry=fC
            self.dateSplitter  = dateSplitter[fC]
            self.dateYearPos   = dateYearPos[fC]
            self.dateMonthPos  = dateMonthPos[fC]
            self.monthDayLen   = monthDayLen[fC]
            if language_in[fC] == 'st-st':
                self.language      = st_language
            else:
                self.language      = language_in[fC]
        else:
            self.formCountry   ='DIN'      # Standardwert
            self.language      = st_language
            printMessage("error",pdvmObjekt,"PDT_013",["def: __setFormCountry","Eingabe: " + fCountry])
            self.dateSplitter  = dateSplitter['DIN']
            self.dateYearPos   = dateYearPos['DIN']
            self.dateMonthPos  = dateMonthPos['DIN']
            self.monthDayLen   = monthDayLen['DIN']

    def __getFormCountry(self):
        return self.formCountry

    FormCountry = property(__getFormCountry,__setFormCountry)

FormCountry (Property) - Beschreibung

Source
Zu dem entsprechenden FormCountry werden die Parameter für die Darstellung und auch Zerlegung gesetzt und als Eigenschaften im Objekt festgehalten.

ckval
In dieser Variablen werden die zugelassenen FormCountrys festgehalten. Kommt dann bei einer späteren Prüfung ein nicht vorhandener FormCountry auf, so wird im Log eine Fehlermeldung ausgegeben und die Parameter von DIN verwendet.

dateSplitter
Für jeden FormCountry sind hier die Trenner in einem Wörterbuch beschreiben. Diese werden für die Ausgabe verwendet. Bei der Eingabe kann in jedem FormCountry alle hier vorhandenen Trenner verwendet werden.

dateYearPos
Für jeden FormCountry wird hier die Position des Jahres festgelegt.

dateMonthPos
Für jeden FormCountry wird hier die Position des Monats festgelegt. Hierbei geht die Position in zweier Schritten. Da bei DIN die vierstellige Jahreszahl am Anfang steht ist der Monat auf Position 2.

monthDayLen
Hier wird die Länge von Monat und Tag festgelegt. Dieses muss festgelget sein, da das amerikanische Format auch einstellige Tage und Monate zulassen.

language_in
Hier wird für jeden FormCountry die verwendete Sprache festgelegt, damit alles korrekt übersetzt werden kann. Die hier bei DIN verwendete Sprache st-st steht für den Standard. Hier wird die Standardsprache verwendet. In der Dango App, die in den Settings eingestellt wurde.

Ablauf
  • FormCountry wird immer in Großbuchstaben verwendet. Andere Eingaben werden umgesetzt.
  • Zugelassene FormCountry wird geprüft
  • Ja - zugelassen --> die entsprechenden Eigenschaften werden gesetzt
  • Nein - nicht zugelassen --> die entsprechenden Eigenschaften von DIN werden gesetzt und eine Fehlermeldung im Log ausgegeben (mit printMessage)
Die Property FormCountry kann als set und get verwendet werden.

PdvmDateTime (Property)

Beschreibung
    # --------------------------------------------------------------------
    # PdvmDateTime
    # --------------------------------------------------------------------
    def __setPdvmDateTime(self,pdvmddate):
        try:
            self.pdvmdatetime = float(pdvmddate)
            self.__pdvmDateInDateSplit()
            self.__pdvmdatime(self.year,self.month,self.day,
                            self.hour,self.minute,self.second,self.microsecond)
        except:
            printMessage("error",pdvmObjekt,"PDT_001",["def: setPdvmDateTime", "Eingabe: " + str(pdvmddate)], self.language)

    def __getPdvmDateTime(self):
        if self.vChr:
            return self.pdvmdatetime * -1
        else:
            return self.pdvmdatetime

    PdvmDateTime = property(__getPdvmDateTime,__setPdvmDateTime)
 

PdvmDateTime - Beschreibung

Source
Über diese Eigenschaft kann das Datum und die Zeit über das PDVM-Format gesetzt werden. Misslingt der Vorgang aus irgendwelchen Gründen wird im Log eine Fehlermeldung ausgegeben, die unter andereem den Wert anzeigt, der gesetzt werden soll.

Ablauf
  • Eigenschaft pdvmdatetime wird mit dem Eingabewert gesetzt
  • über die __pdvmDateInSplit() werden aus dem pdvmdatetime die Eigenschaften self.year, self.month, self.day, self.hour, self.minute, self.second, self.microsecond berechnet
  • über die __pdvmdatime() werden die Properties des Objektes gebildet.
  • ist die Eigenschaft vChr == wahr wird das Ergebnis negativ ausgegeben
Die Property PdvmDateTime kann als set und get verwendet werden.

PdvmDateTimeT (Property)

Beschreibung
    # --------------------------------------------------------------------
    # PdvmDateTimeT
    # --------------------------------------------------------------------
    def __setPdvmDateTimeT(self,pdvmdtt):
        try:
            self.__pdvmdatime(pdvmdtt[0],pdvmdtt[1],pdvmdtt[2],
                                           pdvmdtt[3],pdvmdtt[4],pdvmdtt[5],
                                           pdvmdtt[6])
        except:
            printMessage("error",pdvmObjekt,"PDT_002",["def: setPdvmDateTimeT", "Eingabe: " + str(pdvmdtt)], self.language)
  
    def __getPdvmDateTimeT(self):
        return self.dtt

    PdvmDateTimeT = property(__getPdvmDateTimeT,__setPdvmDateTimeT)
 

PdvmDateTimeT - Beschreibung

Neuer Text
Source
Hiermit können Datum und Zeit über einen Tuple mit der Ausprägung von 6 Bereiche (Jahr, Monat, Tag, Stunde, Minute, Sekunde, Microsekunde) gesetzt werden. Wenn nicht alle Werte angegeben werden, so werden diese einfach mit 0 angenommen.

Ablauf
  • mit __pdvmdatime() werden die Werte in das Objekt übernommen
  • im Fehlerfall wird eine Meldung mit dem versuchten Eingabewert ausgegeben
Die Property PdvmDateTimeT kann als set und get verwendet werden.

PdvmDate (Property)

Beschreibung
    # --------------------------------------------------------------------
    # PdvmDate
    # --------------------------------------------------------------------
    def __setPdvmDate(self,pdvmdt):
        try:
            self.pdvmdatetime = float(int(pdvmdt))
            self.__pdvmDateInDateSplit()
            self.__pdvmdatime(self.year,self.month,self.day,
                            self.hour,self.minute,self.second,self.microsecond)
        except:
            printMessage("error",pdvmObjekt,"PDT_003",["def: setPdvmDate", "Eingabe: " + str(pdvmdt)], self.language)

    def __getPdvmDate(self):
        if self.vChr:
            return self.pdvmdate
        else:
            return self.pdvmdate

    PdvmDate = property(__getPdvmDate,__setPdvmDate)

PdvmDate - Beschreibung

Source
Hiermit kann das Datum im PDVM-Format (Julianisches Datum) gesetzt oder bereitgestellt werden. Auch wenn ein PdvmDateTime mitgegeben wird wird nur das Datum mit 00:00 Uhr angenommen.

Ablauf
Sobald im Ablauf ein Fehler auftritt, wird eine Fehlermeldung im Log ausgegeben bei dem der eingegebene Wert angezeigt wird.
  • pdvmdatetime wird mit dem Integer der Eingabe gesetzt. Damit keine Nachkommastellen --> 00:00:00 Uhr
  • __pdvmDateInSplit() teilt diesen Wert in Jahr, Monat, Tag, Stunden, Minuten, Sekunden, Microsekunden auf
  • __pdvmdatime() setzt die Proterties im Objekt
  • ist die Eigenschaft vChr == wahr dann wird das Ergebnis negativ ausgegeben.
Die Property PdvmDate kann als set und get verwendet werden.

PdvmDateT (Property)

Beschreibung
    # --------------------------------------------------------------------
    # PdvmDateT
    # --------------------------------------------------------------------
    def __setPdvmDateT(self,pdvmdtt):
        try:
            self.__pdvmdatime(pdvmdtt[0],pdvmdtt[1],pdvmdtt[2],0,0,0,0)
        except:
            printMessage("error",pdvmObjekt,"PDT_004",["def: setPdvmDateT", "Eingabe: " + str(pdvmdtt)], self.language)
  
    def __getPdvmDateT(self):
        return self.dd

    PdvmDateT = property(__getPdvmDateT,__setPdvmDateT)

PdvmDateT - Beschreibung

Source
Über einen Tuple (Jahr, Monat, Tag) kann hier das Datum gesetzt werden. Die Uhrzeit ist hierbei immer 00:00:00 Uhr.

Ablauf
  • Über die __pdvmdatime() wird das Datum gesetzt
  • Tritt ein Fehler auf, wird ein eine Fehlermeldung ausgegeben in der der Eingabewert dargestellt wird.
Die Property PdvmDateT kann als set und get verwendet werden.

PdvmTime (Property)

Beschreibung
    # --------------------------------------------------------------------
    # PdvmTime
    # --------------------------------------------------------------------
    def __setPdvmTime(self,pdvmtt):
        try:
            xx = int(pdvmtt)
            self.pdvmdatetime = float(pdvmtt)-xx
            self.__pdvmDateInDateSplit()
            self.__pdvmdatime(self.year,self.month,self.day,
                            self.hour,self.minute,self.second,self.microsecond)
        except:
            printMessage("error",pdvmObjekt,"PDT_005",["def: setPdvmTime", "Eingabe: " + str(pdvmtt)], self.language)

    def __getPdvmTime(self):
        return self.pdvmtime

    PdvmTime = property(__getPdvmTime,__setPdvmTime)
 

PdvmTime - Beschreibung

Source
Damit kann eine Zeit im Pdvm Format gesetzt werden. Ein im Wert eventuell vorhandenes Datum wird auf 0 gesetzt, also entfernt.

Ablauf
  • ein eventuell vorhandenes Jahr wir in die Variable xx extrahiert.
  • pdvmdatetime wird mit dem Eingabewert - xx (eventuell vorhandenes Jahr) gesetzt
  • __pdvmDateInDateSplit teilt den Wert auf
  • __pdvmdatime() setzt die Zeit und die anderen Eigenschaften
  • Im Falle eines Fehlers wird im Log eine Fehlermeldung ausgegeben, die auch den Eingabewert anzeigt.
Die Property PdvmTime kann als set und get verwendet werden.

PdvmTimeT (Property)

Beschreibung
    # --------------------------------------------------------------------
    # PdvmTimeT
    # --------------------------------------------------------------------
    def __setPdvmTimeT(self,pdvmttt):
        try:
            self.__pdvmdatime(0,0,0,pdvmttt[0],pdvmttt[1],pdvmttt[2],pdvmttt[3])
        except:
            printMessage("error",pdvmObjekt,"PDT_006",["def: setPdvmTimeT", "Eingabe: " + str(pdvmttt)], self.language)
  
    def __getPdvmTimeT(self):
        return self.dt

    PdvmTimeT = property(__getPdvmTimeT,__setPdvmTimeT)
 

PdvmTimeT - Beschreibung

Source
Über einen Tuple (Studen, Minuten, Sekunden, Microsekunden) kann die Zeit gesetzt werden. Das Datum ist hierbei immer 0.

Ablauf
  • Mit __pdvmdatime() wird die Zeit im Objekt gesetzt
  • Tritt ein Fehler auf, wird im Log eine Fehlermeldung ausgegeben, diese enthält auch den Eingabewert.
Die Property PdvmTimeT kann als set und get verwendet werden.

Weekday

Beschreibung
    # --------------------------------------------------------------------
    # Weekday    --- Wochentag ermitteln
    # --------------------------------------------------------------------
    def __getWeekday(self):
        # Wochentag wird auf Basis der Gesamttage ab Beginn des
        # des Kalenders berechnet und inter die Tage im Jahr addiert.
        # Jahr 0 hat Wochentag 5 Samstag, Jahr 1 hat 6 Sonntag, da der
        # Kalender im Jahre 1 mit Sonntag beginnt. 
        # Für das Jahr 0 und die negative Jahre wird dieses einfach logisch
        #    weitergeführt    
        year = self.year                # Jahreszahl
        if self.vChr:  
            year = year * -1         
        x_year = year                   # für spätere Verwendung       
        if year <= 0:                   # für Jahr 0 und kleiner, volle Jahre ohne Korrektur   
            pass
        else:
            year -= 1                   # Anzahl volle Jahre
        yday = self.yday                # Anzahl Tage im Jahr
        sjahr= int(year/4)              # Anzahl grundsätzliche Schaltjahre
        n_sjahr = int(year/100)         # Anzahl doch keine Schaltjahre
        d_jahr = int(year/400)          # Anzahl doch wieder Schaltjahre
        all_years_day = year*365        # Anzahl Tage der Jahre
        all_s_years = sjahr - n_sjahr + d_jahr      # Summe der Schaltjahre
        if x_year < 1:
            year_number = all_years_day + all_s_years - yday
        else:   
            year_number = all_years_day + all_s_years + yday -1
        return year_number%7

    Weekday = property(__getWeekday,)
 

Weekday - Beschreibung

Source
Die Wochentage werden wie folgt ermittelt. Es wird hierbei davon ausgegangen, dass das Jahr 1 mit dem Sonntag (6) wird. Nun mit den Wochentagen für das Jahr 0 und weiter die negativen Jahre ist es so, dass dieses mit den Regel für Schaltjahre in die urückliegende Zeit berechnet werden. Hierbei gehe ich davon aus, dass es sich bei dem Jahre 0 nicht um ein Schaltjahr handelt. Eine genaue Festlegung konnte ich nicht finden. Da hier der Wochentag nicht von wesentlichem Belang ist, wird diese Ungenauigkeit hingenommen.

Ablauf
  • Die Eigenschaft Jahr wird in year übernommen
  • Ist es aus einem negativen Datum (vChr) wird year negiert
  • Für spätere Verwendung wird year in x_year gesichert
  • Anzahl der vollen Jahre wird berechnet (im positiven Bereich einfach -1)
  • Die Anzahl der Tage wird in yday übernommen.
  • Die Anzahl der Schaltjahre aus der year wird berechnet ( int(year/4).
  • Die Anzahl der Schaltjahre die nicht zu bereücksichtigen sind (int(year/100).
  • Die Anzahl der Schaltjahre, die doch wiederrum zu zählen sind (int(year/400).
  • Die Anzahl der Gesamttage der vollen Jahre (korrigiert um die Schaltjahre - für jedes Schaltjahr +1)
  • Ist x_year < 1 --> die Tage werden abgezogen // anderenfalls werden die Tage addiert.
  • Aus den Gesamttagen wird bei einer Divison mit 7 der Rest errechnen (Gesamttage mod 7)
  • Der Rest ist der Wochentag.
Die Property Weekday kann als set und get verwendet werden.

Date

Beschreibung
    # --------------------------------------------------------------------
    # Date    --- Datum yyyy-mm-dd ausgeben
    #           Datumsformate nach DIN 5008:2011-04
    #
    #   auf dieses Format werden wir uns immer beziehen. Die Unterschiede in
    #   Trennzeichen, besonderer Formate (DEU, ENG, USA) werden demnach nur
    #   in unterschiedlichen Darstellungsformen (Ausgaben) wiederspiegeln.
    #   Dazu schaffen wir uns Parameter für das Objekt
    #       - Form Land (ohne Angabe - DIN) [self.formCountry] siehe Property
    #       - Trennzeichen (ohne Angabe oder kein Land - DIN) aus formCountry [dateSplitter]
    #       - Position Jahr (ohne Angabe oder kein Land - DIN) aus formCountry [dateYearPos]
    #       - Position Monat (ohne Angabe oder kein Land - DIN) aus formCountry [dateMonthPos]
    #       - Ausgabe Stellen Monat / Tag (ohne Angabe oder kein Land - DIN) aus formCountry [monthDayLen]
    #   mit __setFormCountry als Objektparameter gesetzt.
    #   Hinweis: Erfolgt eine Eingabe mit ainem Minus am Anfang so wird intern self.vChr auf True
    #   -------- gesetzt. In den Berechungen hat es noch keine Auswirkungen. Datum wird wie positiv
    #            verwaltet. Als PDVM_DateTime erfolgt die Ausgabe und damit ggf. die Speicherung negativ.
    # --------------------------------------------------------------------
    def __setDate(self,datein):
        # Initalisierung
        ok    = True
        year  = 0
        month = 0
        day   = 0
        pdate  = {
            'year':year,
            'month':month,
            'day':day
        }
        splitter = '-'
        # Datum mit korrektem Splitter wird einfach zerlegt, egal ob Tag Monat 1 oder zweistellig sind
        # Es sollen ja alle Jahre (auch < 1000) verarbeitet werden können. Vorerst keine Modifikation von
        # 2-stelligen Jahreszahlen.
        # Eingaben ohne Splitter setzt voraus, Tag / Monat immer 2-stellig, Jahreszahl 4 Stellen, wenn
        # zwei Stellen, dann folgende Modifikationsregel (bis aktuelles Jahr + 5 --> aktuelles Jahrundert //
        # danach Jahrundert - 1)
        # Bei 4 Stellen wird davon ausgegangen, dass das aktuelle Jahr gültig ist
        if datein[0:1]=='-':
            self.vChr = True
            datein = datein[1:]
        else:
            self.vChr = False
        datein = datein.replace('/', '-')
        datein = datein.replace('.', '-')
        if datein.find(splitter) == -1:        # Trennzeichen nicht gefunden
            try:
                int(datein)                    # Prüfung numerischer Wert
            except:
                printMessage("error",pdvmObjekt,"PDT_007",["def: __setDate","Eingabe: " + datein], self.language)
                ok = False

            if ok == True:       # kein Splitter und nicht numerisch
                if len(datein) > 8:                       # für numerischen Wert zu lange
                    printMessage("error",pdvmObjekt,"PDT_008",["def: __setDate","Eingabe: " + datein], self.language)
                    ok = False
                elif (len(datein) == 8                    # mit 4 Stellen Jahr
                        or len(datein) == 6               # mit 2 Stellen Jahr
                        or len(datein) == 4):             # ohne Jahreszahl
                    pdate = self.__calcDateToForm(datein, len(datein))
                else:
                    printMessage("error",pdvmObjekt,"PDT_009",["def: __setDate","Eingabe: " + datein], self.language)
                    ok = False
        else:
            xdate = datein.split(splitter)
          
            for i in range(0, 3):
                if outpos[self.dateYearPos][self.dateMonthPos][i]==0:
                    year = xdate[i]
                if outpos[self.dateYearPos][self.dateMonthPos][i]==1:
                    month = xdate[i]
                if outpos[self.dateYearPos][self.dateMonthPos][i]==2:
                    day = xdate[i]

            pdate = [year,month,day]

            for i in range(1, 3):
                if len(pdate[i])==1:
                    pdate[i] = pdate[i].rjust(2, "0")

        if ok:
            ok = self.__checkDate(pdate[0],pdate[1],pdate[2])

        if ok:
            self.PdvmDateT = (int(pdate[0]),int(pdate[1]),int(pdate[2]))
            return 0        # Return 0k - Datum gesetzt
        else:
            return -1       # Return für falsch - Datum nicht gesetzt

    def __getDate(self):
        ret = ()
        xdate = [str(self.year),str(self.month),str(self.day)]
        for i in range(1, 3):                           # 0 ist Jahr bleibt wie es ist
            if len(xdate[i])<self.monthDayLen:
                    xdate[i] = xdate[i].rjust(2, "0")
            ret = (xdate[outpos[self.dateYearPos][self.dateMonthPos][0]]
                +self.dateSplitter+xdate[outpos[self.dateYearPos][self.dateMonthPos][1]]
                +self.dateSplitter+xdate[outpos[self.dateYearPos][self.dateMonthPos][2]])

        return ret

    Date = property(__getDate,__setDate)
 

Date - Beschreibung

Source
Über die Eigenschaft Date kann man ein Datum in verschiedener Weise setzten. Es gibt hier unterschiedliche (Land-)Formate:
  • DIN --> Format nach DIN 5008:2011-01, wird als default verwendet, wenn kein anderes Format vorhanden ist (JJJJ-MM-TT)
  • DEU --> deutsches Format (TT.MM.JJJJ)
  • ENG --> englisches Format (TT/MM/JJJJ)
  • USA --> amerikanisches Format (M/T/JJJJ)
Die Eingabe kann bei jedem Format mit Trennzeichen eingegeben werden. Alle Trennzeichen sind bei allen Formaten zugelassen. Hierbei werden immer die Werte in den Positionen verwendet. Hiermit können auch alle Daten eingegeben werden, dieses gilt auch für das Jahr 0 und negative Jahre.

Für den aktuellen Betrieb können Daten auch ohne Trennzeichen angegeben werden. Jeder Bereich ist hierbei immer mit zwei Ziffen zu beschreiben. Reihenfolge wird immer nach dem Format angenommen. Beispiele können in den Tests nachvollzogen werden.

Damit gibt es folgende Eingabemöglichkeiten:
  • 4 Stellen - Werte für Tag und Monat - als Jahr wird das aktuelle Jahr angenommen.
  • 6 Stellen - Werte für Tag, Monat und Jahr - aktuelles Jahr + 5 wird das aktuelle Jahrhundert genommen, sonst Jahrhundert -1
  • 8 Stellen - Werte für Tag, Monat und Jahr(vierstellig)
Ausgegeben wird diese Eigenschaft immer im entsprechenden Land-Format.

Ablauf setDate
  • Initialisierung
    • ok = True --> wird bei Fehler auf False gesetzt
    • year, month, day = 0 --> werden als Zwischenvariable verwendet
    • pdate - Wörterbuch mit year, month und day. Ergebniswerte.
    • splitter = '-' --> Standardwert
  • Wenn die 1. Stelle des Eingabewertes ein Minus(-) ist, wird dieses abgeschnitten und die Eigenschaft vChr auf True gesetzt.
  • Die Trennzeichen '/' und '.' des Eingabewertes werden auf '-' gesetzt.
  • Wenn Trennzeichen '-' nicht vorhanden ist und der Wert nicht numerisch ist wird die Fehlermeldung PDT_007 ausgegeben. ok = False.
  • Wenn kein Splitter und Wert numerisch
    • ist Wert länger 8 Stellen dann Fehlermeldung PDT_008. ok = False
    • wenn Länge 8, 6, oder 4 Stellen dann __calcDateToForm(datein, len(datein))
      • sonst Fehlermeldung PDF_009. ok = False
  • sonst - Wert mit Splitter
    • xdate = Eingabewert nach dem Splitter gesplittet.
    • entprechend der Formatpositionen (siehe Definitonen vor der Klasse) wird pdate(Jahr, Monat,Tag) gesetzt.
    • einstellige Werte in pdate werden mit einer führenden 0 versehen.
  • Wenn noch alles ok ist dann erfolgt der Aufruf von __checkDate(pdate[0],pdate[1],pdate[2]) zur Prüfung des Datums
  • Wenn es immer noch ok ist, dann wird die Property PdvmDateT mit  (int(pdate[0]),int(pdate[1]),int(pdate[2])) gesetzt und 0 (ok Returncode) zurückgegeben
  • Anderenfalls wird -1 (falsch Retruncode) zurückgegeben.
Mit getDate wird das Datum formatgerecht in einer Schleife formatgerecht zusammengebaut und zurückgegeben.

Die Property Date kann als set und get verwendet werden.

Time

Beschreibung
    # --------------------------------------------------------------------
    # Time
    #
    # Hier werden nur Stunden, Minuten und Sekunden zugelassen.
    # Der Trenner ist hier : .. ohne Trenner müssen alle Bereiche mit 2 Stellen eingegeben werden.
    # als zusätzlich Trenner werden auch . und , beachtet
    # Die Millisekunden werden immer mit 0 angefügt
    # Bei Landformat USA sind die Angaben von PM und AM zugelassen. Ohne Angabe kann die Stunden-
    #    eingabe auch mit 24 Stunden erfolgen, dieses wird dann intern umgesetzt.
    # --------------------------------------------------------------------
    def __setTime(self,timein):
        hour = 0
        minute = 0
        second = 0
        ok = True
        sok = False
        splitter = ':'
        timein = timein.replace(',',splitter)
        timein = timein.replace('.',splitter)
        if timein.find(splitter)>0:
            timein = timein + splitter + '0'            # für den Fall, wenn nur ein Splitter
            sok = True                                  # nur pos 0 bis 2 werden übernommen  
        if sok:         # Eingabe mit Splitter
            tis = timein.split(splitter)
            for i in range(0,3):                        # falls ein Bereich leer ist
                if tis[i]=='':
                    tis[i] = 0
            try:
                hour = tis[0]
                minute = tis[1]
                second = tis[2]
            except:
                printMessage("error",pdvmObjekt,"PDT_014",["def: __setTime","Splitwert: " + str(tis)], self.language)
                ok = False
        else:           # Eingabe ohne Splitter
            try:
                int(timein)                             # Prüfung numerischer Wert
            except:
                printMessage("error",pdvmObjekt,"PDT_007",["def: __setTime","Eingabe: " + timein], self.language)
                ok = False
            if ok and len(timein)%2 > 0:                       #falsche Länge nicht durch 2 teilbar
                printMessage("error",pdvmObjekt,"PDT_012",["def: __setTime","Eingabe: " + timein], self.language)
                ok = False
            elif ok and len(timein) > 6:                         # zu lang
                printMessage("error",pdvmObjekt,"PDT_008",["def: __setTime","Eingabe: " + timein], self.language)
                ok = False
            if ok:  
                tin = (timein + '000000')[0:6]
                hour   = tin[0:2]
                minute = tin[2:4]
                second = tin[4:6]

        if ok:
            self.PdvmTimeT = (int(hour),int(minute),int(second),0)
            return 0
        else:
            return -1

    def __getTimeCalc(self):
        if self.formCountry == 'USA':
            if self.hour > 12 and self.hour < 24:
                hour = self.hour - 12
                pmam = ' PM'
            elif self.hour < 12:
                hour = self.hour
                pmam = ' AM'
            elif self.hour == 12:
                hour = self.hour
                pmam = ' PM'
            elif self.hour == 24:
                hour = self.hour - 12
                pmam = ' AM'
        else:
            hour = "%02i" % self.hour
            pmam = ''
        minute = "%02i" % self.minute
        second = "%02i" % self.second

        return str(hour)+':'+str(minute)+':'+str(second),pmam

    def __getTime(self):        # Ausgabe Stunden, Minuten, Sekunden
        gein = self.__getTimeCalc()
        return gein[0]+gein[1]

    Time = property(__getTime,__setTime)

Time - Beschreibung

Source
  • Für die Eingabe werden hier nur Stunden, Minuten und Sekunden zugelassen.
  • Der Trenner ist hier der Doppelpunkt (:). Ohne Trenner müssen alle Werte mit 2 Stellen angegeben werden.
  • Als zusätzliche Trenner werden Punkt (.) und Komma (,) beachtet.
  • Als Mikrosekunden wird immer 0 angenommen.
  • Erfolgt die Eingabe mit nur einem Splitter wird der Wert von 0 Sekunden angefügt
  • Beim Landformat USA werden PM und AM in der Ausgabe beachtet. Die Eingabe erfolgt auch hier mit 24 Stunden.
  • Die Eingabe ohne Trenner muss sich von der Länge her durch 2 teilen lassen und darf nicht länger als 6 Stellen sein. Diese wird immer von links nach rechts in Zweierschritten als Stunden, Minuten und Sekunden betrachtet.
  • Ist die Eingabe kürzer als 6 Stellen, wird der Rest mit 0 aufgefüllt.
  • Die Ausgabe erfolgt in der Regel mit hh:mm:ss. Die Ausnahme ist USA hier wir AM und PM verwendet (h:m:s).

FormTimeStamp

Beschreibung
    # --------------------------------------------------------------------
    # FormTimeStamp    --- Zeitstempel ausgeben
    # --------------------------------------------------------------------
    def __setFormTimeStamp(self, inaxxo):             # muss ggf. noch ausgebaut werden
        dt = inaxxo.split(' - ')
        self.Date = dt[0]
        da = self.pdvmdatetime
        self.Time = dt[1]
        self.PdvmDateTime = float(da) + float(self.pdvmdatetime)

    def __getFormTimeStamp(self):
        return self.Date + " - " + self.Time

    FormTimeStamp = property(__getFormTimeStamp, __setFormTimeStamp)

FormTimeStamp - Beschreibung

Source
Hier wird der komplette Zeitstempel im Landformat für die Ein- und Ausgabe herangezogen. Eine Bindestrich (-) trennt das Datum von der Zeit. Für den Fall, dass andere Trennzeichen verwendung finden sollten muss dieses in der Zeile 'dt = inaxxo.split(' - ')' entsprechend geändert werden.

Zur Zeit wird der Zeitstempel mitgegeben. Damit kann einfach ein Zeitstempel gesetzt werden und das pdvmdatetime steht zur Verfügung. Brauchbar für die Konvertierung bestehender Zeitstempel.
Share by: