Hauptmenü

Kalenderwoche in FHEM

Begonnen von Freibeuter, 22 Mai 2015, 16:39:08

Vorheriges Thema - Nächstes Thema

Lichti

Entschuldigung. Hatte vergessen den Inhalt der Zeile 159 mitzuschicken.
Da steht bei mir:
my $currentDateTime = timelocal(0, 0, 14, $day, $month, $year);

Der Ausdruck
$weekNumber = checkWeekNumber($year, 1, 1);
steht bei mir in Zeile 124
Habe das au
$weekNumber = checkWeekNumber($year, 0, 1);
geändert.

Aber immer noch die Fehlermeldung:
Error evaluating astro userReading kw: Month '12' out of range 0..11 at ./FHEM/99_myUtils.pm line 159

Hier nochmal der ganze Code:
#########################
# Kalenderwoche berechnen
sub getWeekNumber
{
my ($sec,$min,$hour,$dayn,$month,$year,$wday,$yday,$isdst) = localtime(time);
my $weekNumber = checkWeekNumber($year, $month, $dayn);
# wenn Wochennummer gleich 0, dann ist das aktuelle Datum
# in der Woche vor dem 4. Januar
# also in der letzten Woche des letzten Jahres
if ($weekNumber == 0)
{
   # Wochennummer des letzten Woche des letzten Jahres suchen
   $weekNumber = checkWeekNumber(($year - 1), 12, 31);
   # wenn die Wochennummer größer als 52 ist
   # dann prüfen ob diese Wochennummer korrekt ist oder
   # sie bereits die erste Woche des aktuellen Jahres ist
   if ($weekNumber > 52)
   {
     $weekNumber = checkWeekNumber($year, 0, 1);
     # wenn der 1. Januar des aktuellen Jahres in der Woche 0 liegt
     # dann ist es die Woche 53
     if ($weekNumber == 0)
     {
       $weekNumber = 53;
     }
   }
}
# wenn die Wochennummer größer als 52 ist
# dann prüfen ob diese Wochennummer korrekt ist oder
# sie bereits die erste Woche des nächsten Jahres ist
elsif ($weekNumber > 52)
{
   $weekNumber = checkWeekNumber(($year + 1), 1, 1);
   # wenn der 1. Januar des nächsten Jahres in der Woche 0 liegt
   # dann ist es die Woche 53
   if ($weekNumber == 0)
   {
     $weekNumber = 53;
   }
}
return ($weekNumber);
}

sub checkWeekNumber {
my ($year, $month, $day) = @_;
# 4. Januar als erste Woche erstellen
my $firstDateTime = timelocal(0, 0, 12, 4, 0, $year);
# Wochentag des 4. Januar ermitteln
my $dayOfWeek = (localtime($firstDateTime))[6];
$dayOfWeek = abs((($dayOfWeek + 6) % 7));
# geh zu Wochenanfang (Montag) zurück
$firstDateTime -= ($dayOfWeek * 3600 * 24);
# aktuelles Datum erstellen
my $currentDateTime = timelocal(0, 0, 14, $day, $month, $year);
# Differenz in Tagen berechnen
my $diffInDay = ($currentDateTime - $firstDateTime) / 3600 / 24;
# Anzahl der Wochen zwischen aktuellem Datum und 4. Januar berechnen
my $weekNumber = floor($diffInDay / 7) + 1;
return ($weekNumber);
}

Jamo

In der Zeile ,    $weekNumber = checkWeekNumber(($year - 1), 12, 31);'
die 12 gegen 11 tauschen.
Bullseye auf iNUC, Homematic + HMIP(UART/HMUSB), Debmatic, HUEBridge, Zigbee/Conbee III, FB7690, Alexa (fhem-lazy), Livetracking, LaCrosse JeeLink, LoRaWan / TTN / Chirpstack, Sonos, ESPresence

Christoph Morrison

Vielleicht übersehe ich etwas, aber:


$ perl -MPOSIX -e 'print strftime(q(%V), localtime)'
53

$ corelist POSIX
Data for 2018-11-29
POSIX was first released with perl 5



Lichti

In der Zeile ,    $weekNumber = checkWeekNumber(($year - 1), 12, 31);'
die 12 gegen 11 tauschen.


Das war's.

Vielen Dank !

Damian

Zitat von: Christoph Morrison am 01 Januar 2021, 15:17:16
Vielleicht übersehe ich etwas, aber:


$ perl -MPOSIX -e 'print strftime(q(%V), localtime)'
53

$ corelist POSIX
Data for 2018-11-29
POSIX was first released with perl 5


Das ist korrekt, siehe https://www.aktuelle-kalenderwoche.com/

daher hat der Einzeiler im Status auch immer die korrekte Wochenzahl:

defmod di_week DOIF init{[00:00];;set_State($week)}
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

andies

Wir wollten halt auch mal programmieren  8)
FHEM 6.3 auf RaspPi4 (Raspbian:  6.6.28+; Perl: v5.36.0)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Damian

Zitat von: andies am 01 Januar 2021, 17:34:38
Wir wollten halt auch mal programmieren  8)

Klar kann man machen, aber ich habe auch nicht im DOIF intern programmiert, sondern habe einfach den Parameter %V von strftime benutzt. Da haben sich bestimmt schon einige Programmierer Gedanken zur Korrektheit des Codes der Funktion strftime gemacht.  ;)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

fiedel

#52
Zitat von: Christoph Morrison am 01 Januar 2021, 15:17:16
Vielleicht übersehe ich etwas, aber:


$ perl -MPOSIX -e 'print strftime(q(%V), localtime)'
53

$ corelist POSIX
Data for 2018-11-29
POSIX was first released with perl 5


Genial! Konkurrenzlos wenig Code. Hab ich sofort übernommen.  :)

Gesundes Neues Euch!

Edit: In der myUtils sieht das dann z.B. so aus:sub getWeekNumber{strftime(q(%V), localtime)}
oder als Variable innerhalb einer Sub:
my $kw = strftime(q(%V), localtime);
FeatureLevel: 6.1 auf Wyse N03D ; Deb. 11 ; Perl: v5.14.2 ; IO: HM-MOD-RPI-PCB + VCCU|CUL 868 V 1.66|LinkUSBi |TEK603
HM: SEC-SCO|SCI-3-FM|LC-SW4-PCB|ES-PMSW1-PL|RC-4-2|SEN-MDIR-O|SEC-WDS-2
CUL: HMS100TF|FS20 S4A-2 ; OWDevice: DS18S20|DS2401|DS2406|DS2423

andies

Bitte nicht falsch verstehen: aber hatte Richard nicht empfohlen, POSIX aus dem Code zu werfen, https://forum.fhem.de/index.php/topic,109509.msg1034932.html#msg1034932? Sonst würde ich nämlich Euren Code nehmen, der ist in der Tat schön kurz und ich muss ja nicht programmieren, was wahrscheinlich schon an anderer Stelle erreicht wurde.
FHEM 6.3 auf RaspPi4 (Raspbian:  6.6.28+; Perl: v5.36.0)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

Damian

Zitat von: andies am 02 Januar 2021, 11:01:53
Bitte nicht falsch verstehen: aber hatte Richard nicht empfohlen, POSIX aus dem Code zu werfen, https://forum.fhem.de/index.php/topic,109509.msg1034932.html#msg1034932? Sonst würde ich nämlich Euren Code nehmen, der ist in der Tat schön kurz und ich muss ja nicht programmieren, was wahrscheinlich schon an anderer Stelle erreicht wurde.

Im DOIF wurde POSIX nicht explizit angezogen, es wird lediglich package main verwendet.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Christoph Morrison

Zitat von: andies am 02 Januar 2021, 11:01:53
Bitte nicht falsch verstehen: aber hatte Richard nicht empfohlen, POSIX aus dem Code zu werfen, https://forum.fhem.de/index.php/topic,109509.msg1034932.html#msg1034932? Sonst würde ich nämlich Euren Code nehmen, der ist in der Tat schön kurz und ich muss ja nicht programmieren, was wahrscheinlich schon an anderer Stelle erreicht wurde.

Nein, das hat er nicht und das wäre auch Unfug. Richard hat darauf hingewiesen, dass

use POSIX;

aus kompatibilitätsgründen jede Menge Zeug in main:: importiert. Ich zitiere mal perldoc:

Zitat
Everything is exported by default (with a handful of exceptions). This is an unfortunate backwards compatibility feature and its use is strongly discouraged. You should either prevent the exporting (by saying use POSIX ();, as usual) and then use fully qualified names (e.g. POSIX::SEEK_END), or give an explicit import list. If you do neither and opt for the default (as in use POSIX;), you will import hundreds and hundreds of symbols into your namespace.

D.h. du machst einfach:

use POSIX ();  # nix aus POSIX:: nach main:: importieren


und später dann


POSIX::strftime() # explizit strftime aus POSIX aufrufen


und alle sind glücklich.




Christoph Morrison

#56
Zitat von: Damian am 02 Januar 2021, 12:08:08
Im DOIF wurde POSIX nicht explizit angezogen, es wird lediglich package main verwendet.

Jein, denn Rudolf erledigt das schon für dich - nur früher. D.h. du benutzt bereits das von POSIX exportierte strftime aus fhem.pl und würde Rudolf das (hoffentlich) umstellen, hätte DOIF ein Problem, denn strftime gibt es in main nicht (ist ja aus POSIX).


$ perl -e 'print strftime(q(%V), localtime)'
Undefined subroutine &main::strftime called at -e line 1.

$ perl -MPOSIX -e 'print strftime(q(%V), localtime)'
53


Die Tatsache, dass du das nicht wusstest, zeigt gut, was das Problem mit dem vollgemüllten main-Namespace ist.

Damian

ZitatJein, denn Rudolf erledigt das schon für dich - nur früher. D.h. du benutzt bereits das von POSIX exportierte strftime aus fhem.pl und würde Rudolf das (hoffentlich) umstellen, hätte DOIF ein Problem, denn strftime gibt es in main nicht (ist ja aus POSIX).

Naja, immerhin wird strftime offenbar in 65! Modulen benutzt, dann viel Spaß beim Umstellen ;)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Christoph Morrison

Zitat von: Damian am 02 Januar 2021, 14:49:57
Naja, immerhin wird strftime offenbar in 65! Modulen benutzt, dann viel Spaß beim Umstellen ;)

Macht nix, denn jedes davon bindet POSIX ja noch mal ein und importiert wieder alles nach main ;-)

Wzut

Jedes , sicher ? Ich war der Meinung damals als Richard das Thema erklärt hat und ich eh dabei war meine Module auf package umzubauen,
das  jetzt use POSIX qw(strftime) im eigenen Modul der richtige Weg sei.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher