Da ich heute vor einem ähnlichen Problem stand und dkaserer den Thread vor gar nicht allzu langer Zeit mal ausgebuddelt hat,
wollte ich noch schnell meine Lösung für die Findung des Monatsletzten hier posten, da das sonst nur über Weckalarme
möglich ist und ich in meinem Anwendungsfall auf keinen Fall die Produktion stoppen kann.
Code:
Beschreibung:
TITLE: Berechnung Monatsletzter
DATE: 08.09.2011
AUTHOR: EliteGurke
Beschreibung: In dieser Funktion wird der Monatsletzte berechnet.
z.B. Februar -> 28, es sei denn es handelt sich um ein Schaltjahr -> 29
Definition Schaltjahr:
* Ist die Jahreszahl durch 4 teilbar, aber nicht durch 100, dann ist es ein Schaltjahr
mit 366 Tagen. Beispiele: 1980, 1972, 1720.
* Ist die Jahreszahl durch 100 teilbar, aber nicht durch 400, dann ist das Jahr
ein gewöhnliches Gemeinjahr und hat nur 365 Tage, z. B. in den Jahren 1700, 1800 und 1900 oder ferner 2100.
* Ist die Jahreszahl durch 400 teilbar, ist das Jahr ein Schaltjahr. Die Jahre 1600 und 2000 waren –
in Übereinstimmung mit der Julianischen Schaltregel – Schaltjahre zu 366 Tagen.
Credits to Onkel Dagobert und D. Kaserer
------------------------------------------
Variablen:
IN
INOUT
TEMP
DateAndTime 0.0 DATE_AND_TIME
RET_VAL 8.0 RET_VAL ReturnValue von SFC1
MOD4 10.0 Bool True wenn REST = 0
MOD400 10.1 Bool True wenn REST = 0
MOD100 10.2 Bool True wenn REST = 0
Monat 12.0 INT
Jahr 14.0 INT
OUT
Schaltjahr 0.0 Bool
Monatsletzter 2.0 Int
------------------------------------------
Netzwerk: 1 --- Monat und Jahr auslesen
CALL SFC1
RET_VAL := #RET_VAL
CDT := #DateAndTime
NOP 0
Netzwerk: 2 --- BCD zu INT wandeln
L LB 0 //Jahr
BTI
T #Jahr
L LB 1 //Monat
BTI
T #Monat
Netzwerk: 3 --- Schaltjahr berechnen
//<-- Ist das Jahr ein Schaltjahr?
L #Jahr //Jahreszahl
L 4 //jedes 4. Jahr
MOD //Divisionsrest ermitteln
L 0 //wenn kein Rest,
==I
= #MOD4 //durch 4 teilbar
L #Jahr //Jahreszahl
L 400 //durch 400
MOD
L 0 //Rest 0
==I
= #MOD400 //durch 400 teilbar
L #Jahr //Jahreszahl
L 100 //durch 100
MOD
L 0 //Rest 0
==I
= #MOD100 //durch 100 teilbar
O #MOD4 //Berechnung siehe Beschreibung
UN #MOD100
O #MOD400
= #Schaltjahr
Netzwerk: 4 --- Tage zählen
//<-- Tage voller Monate seit Jahresbeginn
L #Monat
DEC 1 // 0..11
SPL ERR // >11
SPA JAN
SPA FEB
SPA MAE
SPA APR
SPA MAI
SPA JUN
SPA JUL
SPA AUG
SPA SEP
SPA OKT
SPA NOV
SPA DEZ
//<-- Verlassen mit Fehler
ERR: L 0
T #Monatsletzter
CLR
SAVE
BEA
//<-- Tage der abgeschlossenen Monate
JAN: L 31
SPA TAGE
FEB: L 28 //ohne Schaltjahr
SPA TAGE
MAE: L 31
SPA TAGE
APR: L 30
SPA TAGE
MAI: L 31
SPA TAGE
JUN: L 30
SPA TAGE
JUL: L 31
SPA TAGE
AUG: L 31
SPA TAGE
SEP: L 30
SPA TAGE
OKT: L 31
SPA TAGE
NOV: L 30
SPA TAGE
DEZ: L 31
SPA TAGE
TAGE: T #Monatsletzter
Netzwerk: 5 --- Korrektur und Ausgabe
//<-- Korrektur, wenn Schaltjahr und Monat == Februar
U #Schaltjahr
U(
L #Monat
L 2
==I
)
L #Monatsletzter
SPBN M001
L 1
+I
//<-- Ausgabe
M001: T #Monatsletzter
SET
SAVE
Damit ist es mir nun möglich auch ohne Weckalarme am letzten des Monats um 23:59:59 noch
mit dem alten Datum meine Statistiken wegzuspeichern.
Code muss allerdings noch getestet werden, habe den schnell in N++ zusammen gefriemelt.
mfg EliteGurke
Bookmarks