TIA Date and Time mit x Monaten addieren

rr_zx

Level-2
Beiträge
86
Reaktionspunkte
9
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen

Ich möchte im SCL bei einer Date_And_Time Variable x Monate dazu addieren und diese wieder in einer Date_And_Time Variable speichern.
Wobei x eine Int Variable ist.
Weiss jemand wie ich das einfach lösen kann?

Viele Grüsse
Ralph
 
Da muss aber auch der Überlauf berücksichtigt werden, Monat 13 gibts nicht. Ausserdem kommt nach 9 (September) nicht 10 sondern 16 wegen dem BCD-Code.

*thumbs up*
sollte so ziemlich alles abgedeckt sein so
bei 12+1 muss Byte 0 nach selben Regeln inkrementiert werden

und wenn man einmal dabei ist sollte man die Dekrementvorschriften auch gleich mit umsetzen
 
Moin Aventius,

man könnte, wenn man weiß welche Monate addiert werden sollen, die Monate in Tage zerlegen und in einer Schleife die Anzahl der Tage (86.400.000 ms) zu dem Startdatum mit T_ADD addieren.

Zuerst müsste man die Anzahl der Tage jeden Monats in Konstanten festlegen (z.B. 1 = 31 Tage, 4 = 30 Tage (Schaltjahre müssten extra ausgewertet werden)),
dann könnte man anhand des Startmonats die Anzahl der Tage ermitteln.

Ich gebe zu, dass das schon etwas aufwändig ist, aber dann hat man das Problem mit dem Überlauf der Monate nicht und das jeweilige Zieldatum wird korrekt berechnet.

Gruß

MFreiberger
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin Aventius,

man könnte, wenn man weiß welche Monate addiert werden sollen, die Monate in Tage zerlegen und in einer Schleife die Anzahl der Tage (86.400.000 ms) zu dem Startdatum mit T_ADD addieren.

Zuerst müsste man die Anzahl der Tage jeden Monats in Konstanten festlegen (z.B. 1 = 31 Tage, 4 = 30 Tage (Schaltjahre müssten extra ausgewertet werden)),
dann könnte man anhand des Startmonats die Anzahl der Tage ermitteln.

Ich gebe zu, dass das schon etwas aufwändig ist, aber dann hat man das Problem mit dem Überlauf der Monate nicht und das jeweilige Zieldatum wird korrekt berechnet.

Gruß

MFreiberger

das klingt wesentlich einfacher, definitiv :roll:
 
FC 1 AD_DT_TM aus den IEC function blocks

die funktion fc 1 addiert eine zeitdauer (format time) auf einen zeitpunkt (format dt) und liefert als ergebnis einen neuen zeitpunkt (format dt). Der zeitpunkt (parameter t) muß im bereich von dt#1990-01-01-00:00:00.000 und dt#2089-12-31-23:59:59.999 liegen. Die funktion führt keine eingangsprüfung durch.

der eingangsparameter t und der ausgangsparameter können nur mit einer symbolisch definierten variablen belegt werden.
 
Problem an der ganzen Geschichte wird wohl werden dass das Time-Format nur irgendwas um 28 Tage unterstützt. Du kannst also damit nur Februare addieren.
 
Was mir da aber in fällt. Wenn du dir schon die Arbeit mit der Umrechnerei von Monaten in Tage machen willst kannst du aus deinem DateAndTime mit FC6 DT_DATE das Datum extrahieren, deine Anzahl Tage einfach addieren und mit FC3 D_TOD_DT wieder zurückrechnen.
 
Moin Zusammen,

zu #10: mit der Funktion T_ADD aus dem TIA kann man direkt DT mit Time addieren. Bleibt weiterhin die Ermittlung der Anzahl der Tage. Und dazu ist mir halt nicht gescheiteres als in #5 beschrieben eingefallen.:rolleyes:
Zu dem Thema wäre ich an einer eleganteren Lösung auch brennend interessiert.;)


Gruß

MFreiberger
 
Moin Zusammen,

zu #10: mit der Funktion T_ADD aus dem TIA kann man direkt DT mit Time addieren. Bleibt weiterhin die Ermittlung der Anzahl der Tage. Und dazu ist mir halt nicht gescheiteres als in #5 beschrieben eingefallen.:rolleyes:
Zu dem Thema wäre ich an einer eleganteren Lösung auch brennend interessiert.;)


Gruß

MFreiberger

Mit TIA bin ich nicht fit, aber reicht da das Time-Format weiter als 24 Tage?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin Aventinus,

Mit TIA bin ich nicht fit, aber reicht da das Time-Format weiter als 24 Tage?

nein. Aber es gibt das LTime-Format (nur für S7-1500):

Länge (Bit)
Format
Wertebereich
Beispiele für Werteingabe
64
Zeitdauer mit Vorzeichen
LT#-106751d23h47m16s854ms775us808ns bis LT#+106751d23h47m16s854ms775us807ns
LT#11350d20h25m14s830ms652us315ns, LTIME#11350d20h25m14s830ms652us315ns
Hexadezimalzahlen
16#0 bis 16#8000000000000000
16#2



Ich muss aber gestehen, dass ich damit noch nicht gearbeitet habe.

Andere Frage: Was nutzt es Dir? Die Auflösung in Monate gibt es dabei auch nicht. Wenn Du die Anzahl der Tage ermittelt hast, ist es unerheblich, ob du einmal 500 Tage oder 500x 1 Tag (Schleife, Time-Format) hinzuaddierst , oder?

Gruß

MFreiberger
 
Code:
FUNCTION FC253 : VOID
VAR_INPUT
    inDT : DATE_AND_TIME;
    baDT AT inDT : STRUCT
        Year   : BYTE ;  // Jahr    BCD (19)90..(20)89
        Month  : BYTE ;  // Monat   BCD 01..12
        Day    : BYTE ;  // Tag     BCD 01..31
        Hour   : BYTE ;  // Stunde  BCD 00..23
        Minute : BYTE ;  // Minute  BCD 00..59
        Second : BYTE ;  // Sekunde BCD 00..59
        msMSD  : BYTE ;
        wDay_msLSD : BYTE ;
    END_STRUCT;
    inADDM : INT;
END_VAR
VAR_OUTPUT
    outDT : DATE_AND_TIME;
    bbDT AT outDT : STRUCT
        Year   : BYTE ;  // Jahr    BCD (19)90..(20)89
        Month  : BYTE ;  // Monat   BCD 01..12
        Day    : BYTE ;  // Tag     BCD 01..31
        Hour   : BYTE ;  // Stunde  BCD 00..23
        Minute : BYTE ;  // Minute  BCD 00..59
        Second : BYTE ;  // Sekunde BCD 00..59
        msMSD  : BYTE ;
        wDay_msLSD : BYTE ;
    END_STRUCT;
END_VAR
VAR_TEMP
    YEAR : INT;
    MONTH : INT;
    DAY : INT;
END_VAR

    YEAR := BCD_TO_INT(baDT.Year);
    IF (YEAR < 90) THEN
        YEAR := YEAR + 2000;
    ELSE
        YEAR := YEAR + 1900;
    END_IF;
    
    
    
    MONTH := BCD_TO_INT(baDT.Month);
    MONTH := MONTH + inAddM;
    
    IF (MONTH > 12) THEN
        MONTH := MONTH - 12;
        YEAR := YEAR + 1;
    END_IF;
       
   IF (MONTH < 1) THEN
        MONTH := MONTH + 12;
        YEAR := YEAR - 1;         
    END_IF;

   IF (YEAR < 2000) THEN
        YEAR := YEAR - 1900;
    ELSE
        YEAR := YEAR - 2000;
    END_IF;
    
    outDT := inDT;    
    bbDT.Month := WORD_TO_BYTE(INT_TO_BCD(MONTH));
    bbDT.Year := WORD_TO_BYTE(INT_TO_BCD(YEAR));
    
END_FUNCTION
 
Zuletzt bearbeitet:
Moin vierlagig,

ja, fehlt nur noch eine Schleife, falls >12Monate addiert oder subtrahiert werden sollen. Oder größere Zeitintervalle werden in Jahren angegeben.

Gruß

MFreiberger
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ja, fehlt nur noch eine Schleife, falls >12Monate addiert oder subtrahiert werden sollen.
Einfach die IF-Abfragen zu WHILE ändern:
Code:
    IF (MONTH > 12) THEN
        MONTH := MONTH - 12;
        YEAR := YEAR + 1;
    END_IF;
       
    IF (MONTH < 1) THEN
        MONTH := MONTH + 12;
        YEAR := YEAR - 1;         
    END_IF;
Code:
    WHILE (MONTH > 12) DO
        MONTH := MONTH - 12;
        YEAR := YEAR + 1;
    END_WHILE;
 
    WHILE (MONTH < 1) DO
        MONTH := MONTH + 12;
        YEAR := YEAR - 1;
    END_WHILE;
 
Hallo zusammen

Ich habe nochmals eine Frage zu diesem Thema.
Ich habe die Umwandlung so wie oben realisiert. Funktioniert auch schon auf einer Anlage.
Bis anhin habe ich diesen Wert auf einem Basic-Panel angezeigt. Das funktionierte auch.
Jedoch habe ich jetzt das Problem beim Darstellen auf einem Comfort-Panel. Es zeigt nur noch ######### an.
Zusätzlich kommt ein Fehler: Konvertierung felgeschlagen....

Auf der SPS wird der Wert im DB richtig angezeigt.

Kann es sein, das ich auch noch den Wochentag berechnen muss? Dieser Stimmt ja durch die Veränderung der Monate nicht mehr.

Gruess Ralph
 
Hallo,
ich kann deine Annahme bestätigen.
Eine DT-Variable wird nur dann angenommen wenn alle deren Inhalte korrekt sind - auch der Wochentag muss stimmen - auch wenn du ihn gar nicht brauchst.
Das war (meine ich) nur bei ProTool noch egal gewesen ...

Gruß
Larry
 
Zurück
Oben