Step 7 Wochentag(1 bis 7) durch Datums ermitteln

Zuviel Werbung?
-> Hier kostenlos registrieren
die verschiedenen informationen liegen in den 8 byte des DateAndTime folgendermaßen BCD-Codiert vor
es muss nicht unbedingt der sfc1 aufgerufen werden.
auch im ob1 ist die variable schon verfügbar
OB1_DATE_TIME Date_And_Time 12.0

Code:
      CALL  SFC    1
       RET_VAL:=#retval
       CDT    :=#t_date_time //temp-variable vom Typ DateAndTime
// ----------------------------------
      L P##t_date_time
      LAR1

      L     B [AR1,P#0.0]               //jahr
      BTI  
      T     #Jahr
      L     B [AR1,P#1.0]               //monat
      BTI  
      T     #Monat
      L     B [AR1,P#2.0]               //tag
      BTI  
      T     #Tag
      L     B [AR1,P#3.0]               //stunde
      BTI  
      T     #Stunde
      L     B [AR1,P#4.0]               //minute
      BTI  
      T     #Minute
      L     B [AR1,P#5.0]               //sekunde
      BTI  
      T     #Sekunde

      L     B [AR1,P#6.0]               //zehntel/hundertstel
      SLW   4
      BTI  
      T     #Milisekunde_zh
      L     B [AR1,P#7.0]               //tausedstel
      SRW   4
      BTI  
      L     #Milisekunde_zh
      +I   
      T     #Milisekunde

      L     B [AR1,P#7.0]               //rechte tetrade wochentag 1=sonntag
      L     2#1111
      UW   
      BTI  
      T     #Wochentag

hier ein fertiger fc
 
Code:
dDate    := DATE_TO_DINT(D#2022-10-28) ;
iWeekDay := DINT_TO_INT((dDate + 6) MOD 7) + 1 ; // 1 (sunday) .. 7 (saturday)
// b.z.w.
iWeekDay := DINT_TO_INT((dDate + 5) MOD 7) + 1 ; // 1 (monday) .. 7 (sunday)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich bin gerade dabei einige Bausteine von S7-1500 (DTL) auf S7-300 (DT) umzuschreiben und habe das gleiche Problem und bin durch die Suche auf den Thread gestoßen.

Code:
dDate    := DATE_TO_DINT(D#2022-10-28) ;
iWeekDay := DINT_TO_INT((dDate + 6) MOD 7) + 1 ; // 1 (sunday) .. 7 (saturday)

Geht leider nicht: iWeekDay = 1 (Sonntag) für heute Dienstag den 01.11.2022.

Anfangs mit AT Funktion auf das 7 Byte geschaut aber da der Wochentag 4LSB codiert ist und UW nicht in SCL Verfügbar ist wollte ich den Lösungsweg probieren
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
dDate    := DATE_TO_DINT(D#2022-10-28) ;
iWeekDay := DINT_TO_INT((dDate + 6) MOD 7) + 1 ; // 1 (sunday) .. 7 (saturday)

Geht leider nicht: iWeekDay = 1 (Sonntag) für heute Dienstag den 01.11.2022.
Die Formel von Heinrich ist leider nicht korrekt. Man kann sich aber leicht die korrekte Formel erarbeiten:

- Der Datentyp DATE ist die Anzahl Tage seit 01.01.1990
- Der 01.01.1990 ist der Tag 0
- Der 01.01.1990 (Tag 0) war nicht Sonntag, sondern ein Montag, also Wochentag = 2

D#1990-01-01 = DINT#0 ---> Wochentag Montag = 2

iWeekDay := ((dDate + x) MOD 7) + 1; ---> soll 1 (Sonntag) .. 7 (Samstag) ergeben
x := Wochentag(Montag) - Wochentag(Sonntag);

Die korrekte Formel ist:
Code:
iWeekDay := DINT_TO_INT((dDate + 1) MOD 7) + 1 ; // 1 (sunday) .. 7 (saturday)

Harald
 
Geht leider nicht: iWeekDay = 1 (Sonntag) für heute Dienstag den 01.11.2022.
Die Formel von Heinrich ist leider nicht korrekt.
Da habt ihr leider Recht, Harald und mista. Sorry vielstmals!
Ich hatte die Formel mit den TabellenBlattFunktionen von Excel getestet.
In Windows geginnt die Zählung mit dem 1900-01-01 und in SCL mit dem 1990-01-01. So weit, so schlecht.
Aber es gibt da noch einenweiteren feinen Unterschied, den ich leider übersehen hatte: in Windows beginnt die Zählung mit 1 für den 1900-01-01 und in SCL mit 0 für den 1990-01-01.
Code:
dDate    := DATE_TO_DINT(D#2022-10-28) ;
iWeekDay := DINT_TO_INT((dDate + X) MOD 7) + Y ; // 1 (monday) .. 7 (sunday)
Die richtige Formel zu ermitteln bzw. auszuprobieren (sofern man SCL zur Verfügung hat) ist aber in der Tat simpel, Harald.
Habe hier meine Formel mit X und Y anstelle der "Anpass"-Konstanten geschrieben.
Y mit den Werten 0 oder 1 entscheidet allein darüber, ob die Zählung der WochenTage bei 0 beginnt oder bei 1.
X mit den Werten 0..6 schliesslich entscheidet darüber, mit welchem Wochentag die Zählung beginnt, also hiermit anpassen!
Anfangs mit AT Funktion auf das 7 Byte geschaut aber da der Wochentag 4LSB codiert ist und UW nicht in SCL Verfügbar ist wollte ich den Lösungsweg probieren
UW ist in SCL nicht verfügbar? WORD1 AND WORD2 bzw. DWORD1 AND DWORD2 funktioniert aber doch in SCL. Aber das sagte Harald ja schon.
WOW, ich wusste nicht, dass es so einfach sein kann^^
Einfach ist daran aber lediglich, dass man sich den MOD-Operator und zwei Additionen ersparen kann, wenn man die Umrechnung in den DatenTyp DATE_AND_TIME - mit welcher Funktion auch immer - dem "BetriebsSystem" überlässt.
Leider konnte ich meiner SCL-Dokumentation nicht entnehmen, ob und wenn ja, wie man verhältnismässig "schmerzlos" von den DatenTypen TIME und DATE zum DatenTyp DATE_AND_TIME bzw. umgekehrt gelangen kann. Die "druckbaren" Versionen der DatenTypen als Schnittstelle per Umwandlung in STRING zu nutzen, fänd ich naheliegend, aber dennoch recht umständlich.
Und mein grösstes Hindernis: nicht einmal die Konvertierungen in den DatenTyp STRING oder zurück kann ich finden. :(
Muss man das alles tatsächlich "zu Fuss" programmieren?
Der DatenTyp DATE_AND_TIME mit seinen BCD-Zahlen ist zwar schon recht nah am DatenTyp STRING, weil man pro Tetrade lediglich noch 30hex bzw. 48dez bzw. '0' addieren und pro (Zwischen-)Ergebnis je 1 Byte spendieren muss, aber das erfordert ja schon einiges an Aufwand. Auch die Umrechnungen DUAL <--> BCD bleiben einem bei mehr als einstelligen DezimalZahlen nicht erspart.
Daher erschien mir "meine" Variante mit MOD und 2 Additionen und dem Rückgriff auf den DatenTyp DATE als relativ einfach und "direkt".

PS:
Wie gelangt man denn nun in SCL an eine Umwandlung von DATE in DATE_AND_TIME bzw. umgekehrt?
Gibt's das etwas "Fertiges", das ich noch nicht entdecken konnte? ;)

PPS:
Nicht einmal mit ...
Code:
dDate    := DATE_TO_DINT(D#2022-10-28) ;
... komme ich klar.
Bedeutet das etwa, dass die Schreibweise D#2022-10-28 vom Compiler in die serielle Zahl umgewandelt wird und zur Laufzeit des Programms keine entsprechende Umwandlung zur Verfügung steht?
Warum finde ich in der SCL-Doku rein gar nichts zu diesem Thema, nicht einmal ein "beiläufig" erwähntes Beispiel?
Das wäre ja wohl ein nennenswertes Manko von SCL.
 
Zuletzt bearbeitet:
Wie gelangt man denn nun in SCL an eine Umwandlung von DATE in DATE_AND_TIME bzw. umgekehrt?
In TIA sind die SCL-Konvertierfunktionen für Datum und Uhrzeit leider sehr schlecht bis gar nicht dokumentiert.

Die Konvertierfunktionen von DT zu DATE und TOD lauten:
_date_ := DT_TO_DATE(_date_and_time_in_)
_tod_ := DT_TO_TOD(_date_and_time_in_)


und Konvertierung von DATE + TOD zu DT:
_date_and_time_ := CONCAT_DATE_TOD(IN1:=_date_in_, IN2:=_time_of_day_in_)
Sehr wahrscheinlich berechnet die Funktion auch den Wochentag aus dem DATE und fügt ihn zum DATE_AND_TIME hinzu (habe ich nicht getestet).

Extrahieren des Wochentags aus einem DT (DATE_AND_TIME) bzw. berechnen des Wochentags aus einem DATE gibt es in TIA-SCL (zumindest für S7-300/400) anscheinend überhaupt nicht.
Wie man in dem Bild in Beitrag #2 sehen kann, soll es eigentlich eine Konvertierfunktion mit T_CONV zu "INT (Wochentag)" geben. Die gibt es in SCL aber nicht (vielleicht nur in FUP/KOP?) (zumindest nicht bis TIA V15.1)

Für den Wochentag braucht man die Formeln:
Code:
Wochentag := myDT.Byte7 AND 16#0F;                             //Wochentag aus einem DT extrahieren (myDT ist ein Struct "AT" ein DT)
iWeekDay := DINT_TO_INT((DATE_TO_DINT(myDate) + 1) MOD 7) + 1; //Wochentag aus einem DATE berechnen

Harald
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie man in dem Bild in Beitrag #2 sehen kann, soll es eigentlich eine Konvertierfunktion mit T_CONV zu "INT (Wochentag)" geben. Die gibt es in SCL aber nicht (vielleicht nur in FUP/KOP?) (zumindest nicht bis TIA V15.1)
Ich schaue morgen früh mal, eigentlich sollte es die Funktion auch in SCL geben.
 
Ich habe gerade gesehen, in #2 ist der falsche Link hinterlegt. Hier mal der richtige.
https://support.industry.siemens.com/cs/document/63900229/welche-funktionen-stehen-ihnen-jeweils-in-step-7-v5-x-und-im-tia-portal-für-die-bearbeitung-der-datentypen-dt-und-dtl-zur-verfügung-?dti=0&lc=de-DE

Da steht:
In STEP 7 (TIA Portal) finden Sie diese Anweisungen in der Palette "Erweiterte Anweisungen" und unter dem Ordner "Datum und Uhrzeit".
Ich habe jetzt kein TIA zur Hand aber ich denke im SCL Editor sollte man die Anweisung dort auch finden.
 
Der falsche Link? So falsch war der doch nicht, allerdings liefert Dein Link ausführlichere Informationen, Michael.

Man beachte aber - dort steht u.a.:
Bild 1 veranschaulicht die verschiedenen Funktionen, die Sie benötigen, um die Datenformate (TOD, DATE, INT, DINT und TIME) aus den Datentypen DT oder DTL zu extrahieren.
Dort steht raffinierterweise nur, welche Funktionen man benötigt. Aber das wussten wir ja auch so schon.
Dort steht aber leider (korrekterweise?) nicht, dass diese Funktionen auch verfügbar sind bzw. von Siemens bereitgestellt werden! :ROFLMAO:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dort steht aber leider (korrekterweise?) nicht, dass diese Funktionen auch verfügbar sind bzw. von Siemens bereitgestellt werden!
Warum bzw. wie meinst du dies?

Im TIA Portal sind die Bausteine doch vorhanden.
In STEP 7 (TIA Portal) finden Sie diese Anweisungen in der Palette "Erweiterte Anweisungen" und unter dem Ordner "Datum und Uhrzeit".
 
Ich schaue morgen früh mal, eigentlich sollte es die Funktion auch in SCL geben.
Im TIA Portal sind die Bausteine doch vorhanden.
Na ja, so gaaanz klar scheint es wohl doch nicht zu sein, wenn Du's morgen früh mal nachschauen willst ...

Und wenn Du schon mal dabei bist ...
  • Der Datentyp "DT" speichert die Daten zu Datum und Uhrzeit im BCD-Format, also in einer Länge von 8 Byte.
  • Eine Variable vom Datentyp "DTL" hat eine Länge von 12 Byte und speichert die Daten für Datum und Uhrzeit in einer vordefinierten Struktur.
... dort steht nicht, dass die Werte im DatenTyp DTL nicht im BCD-Format herumstehen. Aufgrund der verwendeten DatenTypen UINT, USINT und UDINT würde ich auch keine BCD-Formate erwarten. Aber es steht auch nicht ausdrücklich da, dass die Werte nicht als BCD-Werte gemeint sind ...
Wer weiss, vielleicht hat dennoch das Streben nach Kompatibilität Spuren hinterlassen. ;)
Zugegeben, für diesen Thread, in dem es um eine einzige DezimalStelle für den Wochentag geht, macht es natürlich keinen Unterschied, ob BCD oder nicht.
 
Zurück
Oben