Clanintern Clanintern Clanintern

Forum

Öffentliche Foren
FORUM: Spiele & Computer THEMA: SQL Datum Verwaltung
AUTOR BEITRAG
Morph

RANG Deckschrubber

#1 - 19.11 20:22

Abend Leute,

mir fehlt die Erkenntnis, wie ich etwas strukturiert am besten Aufbaue. Folgendes habe ich:

Einen Evenkalender an dem man sein tolles Event an einem Datum eintragen kann - hui. Jetzt kommt aber der knifflige Teil. Ich habe ala Google Kalender

[für die Leute die das Ding nicht kennen hier weiterlesen]
Man hat die Möglichkeit in dem Google Kalender, Termine wiederholen zu lassen. Das sie z.b. alle 2 Wochen am Mo, Mi, und Freitag stattfinden, oder jeder dritte Mittwoch im Monat, oder alle 2 Monate am 3ten Tag. Das kann man sich dann über Javascript zusammen klicken, sieht ansich ganz hübsch aus.
[/für die Leute die das Ding nicht kennen hier weiterlesen]

halt so eine Auswahlmenü für Wiederholungen. Für Events die sich Wiederholen möchte ich eine 2te Tabelle basteln, sowas in der Art wie event_repeat. Wie baue ich die Tabelle am besten auf? Mir geht es nachher vorallem auch ums einfache Auslesen für die Kalendergenerierung ... . Bis jetzt ist mir plumperweise nur eingefallen, für jedes ein einzelnes Feld zu machen, das wirkt aber irgendwie umständlich. Gibt es da keine bessere Idee, vll irgendeine Mathematische Rechnung die man da besser einbauen könnte?
*al!ve* - Vorbereitung aufs Urlaubssemester

RANG Master of Clanintern

#2 - 20.11 03:17

Willkommen in der wunderbaren Welt des Kalenderbaus. Ich hab mir in der nahen Vergangenheit so den ein oder anderen Gedanken darüber gemacht.


Für das von dir angesprochene Problem bin ich zu dem Schluss gekommen, dass es wohl das sinnvollste wäre, einen Termin in TerminInhalt und TerminDurchführung zu trennen.

TerminInhalt:
- TerminInhaltID
- Textuelle Beschreibung des Termins
- Start einer Periode (Start des ersten Auftretens)
- Länge einer Periode
- Dauer jeder Durchführung eines Termins
- Mathematische Beschreibung für Wiederholungen

TerminDurchführung:
- TerminDurchführungID
- TerminInhaltID (um eine Durchführung einem Inhalt zuordnen zu können)
- Textuelle Beschreibung des Termins (kann vom Inhalt des TerminInhalts abweichen, im Regelfall aber nicht)
- Start des Termins
- Dauer des Termins (kann von der Dauer des TerminInhalts abweichen, im Regelfall aber nicht)


Beim Erstellen eines einzelnen Termins wird ein TerminInhalt erzeugt und eine TerminDurchführung, deren Werte für Start und Dauer identisch sind, Länge der Durchführung ist Dauer des Termins.

Beim Erstellen eines wiederholten Termins wird ein TerminINhalt erzeugt und entsprechend der mathematischen Beschreibung eine gewisse Anzahl von TerminDurchführungen.

Sollte sich ein einzelner Termin mal von der Regel der zugehörigen Termine unterscheiden, kann das trotzdem formuliert werden, indem einfach die Werte gegenüber den Standardwerten geändert werden. Das kann sowohl die Zeiten (Start und Dauer) als auch die Beschreibung betreffen. Für den Fall, dass ein Termin mal ausfallen sollte, kann die Dauer auf 0 gelegt werden oder die Durchführung ganz gelöscht, je nach Belieben. Bei Dauer 0 besteht die Möglichkeit, einen ausgesetzten Termin wieder zu rekonstruieren. Jeden Montag (von 1. Januar bis 12. Dezember, beginnend ab *Zeit des ersten Montags im Jahr* und dann fortlaufend alle sieben Tage) wird Stammtisch gehalten, der Ostermontag fällt aus, was man im Februar einträgt, im März stellt man fest, dass man sich auch trotz Ostermontag treffen kann. Jetzt einfach "zeig mir alle Druchführungen des Termins, auch ausgesetzte" anclicken und den ausgesetzten auf "aussetzen aufheben" wählen.

Die mathematische Formulierung des Termins hängt jedoch davon ab, welche Möglichkeiten man dem Benutzer an die Hand geben will. "Jeden dritten Montag im Monat" zum Beispiel kann man so nur schlecht bis gar nicht angeben.

Alternativ könnte man eine Schreibweise eines Termins mit Variablen testen.
tag.monat.jahr, stunde:minute => immer
tag.1.jahr, 10:00 => im Januar täglich
15.monat.jahr, stunde:30 => zum 15. jedes Monats, halbstündlich

Die Erzeugung von Terminen nach beiden Schemata könnte jedoch etwas rechenlastig sein. Auch aus diesem Grund würde ich die Erzeugung von Terminen nicht bei jeder Abfrage temporär neu berechnen lassen sondern einmalig bei Eintragung.


Weiterhin wäre es möglich, für jede Variable Schrittweiten zu definieren

tag.monat.jahr, stunde:minute; tag=1-1/1, monat=1-12/3, jahr=2007-2007/1 stunde=10-10/1, minute=0-0/1 => quartalsweise 2007 um 10:00, beginnend am 1.1.

Hier wäre zwar die "jeder dritte Montag"-Formulierung nicht enthalten, jedoch reduziert sich der Berechnungsaufwand gegenüber einer mathematischen Gleichung oderd er vorherigen Variablenschreibweise enorm, weil nicht pauschal alle möglichen Werte durchgerechnet werden müssen sondern lediglich Schleifen in den definierten Grenzen mit definierter Schrittweite durchlaufen werden.

Nachdem ich die letzte Idee sehr cool finde, werd ich bei Gelegenheit mal versuchen, einen Zeitenkonstruktor dafür zu schreiben.
*al!ve* - Vorbereitung aufs Urlaubssemester

RANG Master of Clanintern

#3 - 20.11 09:22

http://alive.no-ip.com/kalender/terminkonstruktor/terminkonstruktor.php
http://alive.no-ip.com/kalender/terminkonstruktor/terminkonstruktor.phps

Ich hab mir mal erlaubt, n bissl was zu schreiben. Kommentare folgen, ich muss jetzt los.
Morph

RANG Deckschrubber

#4 - 20.11 21:35

Respekt, danke alive, also so ne Antwort habe ich bis jetzt selten bekommen. Hätte alles etwas gröber erwartet. Danke für die Mühe!
h¥pertex

RANG Deckschrubber

#5 - 20.11 21:49

Tja, so isser ;) Der alive gibt immer so Monsterantworten, und programmiert auch gern mal ein paar Zeilen.
*al!ve* - Vorbereitung aufs Urlaubssemester

RANG Master of Clanintern

#6 - 21.11 00:40

N paar Zeilen ist gut. Ich hab das Thema hier einfach zum Anlass genommen, meine bisherigen Gedanken mal auszuprogrammieren. Hat etwa 2.5 Stunden gedauert (4:30 bis 7:00), leider war da grade CI down. Deshalb hab war ich von 7:00 bis 10:00 im Bett (7:00 bis 8:00 wach gelegen, 8:00 bis 9:00 geschlafen, 9:00 von ner Freundin per Telefon geweckt worden ob ich mit ihr frühstücken will, 9:00 bis 10:00 geschlafen, aufgestanden, geduscht, 10:30 gefrühstückt, 11:00 angefangen zu arbeiten ...) und hab das Ding erst veröffentlicht, als ich eben um 10:00 wieder auf war.

Das Script hab ich also so wie es da steht komplett gestern Nacht geschrieben. Es könnte noch Fehler enthalten, weiter getestet als durch die gezeigten Beispiele hab ich s noch nicht.


Zur Erklärung:

Mittels tag, monat, jahr, minute und stunde werden Intervallgrenzen für die jeweilige Zeiteinheit definiert. Jede dieser Methoden hat die Parameter ($start, $ende, $weite). $start definiert den Anfang des Intervals, $ende das Ende und $weite die Schrittlänge, in der es durchlaufen wird. $tk->jahr(2000, 2007, 2) gibt also die Jahre zwischen 2000 und 2007 mit Abstand 2 an, heißt 2000, 2002 und 2004. Wenn $weite nicht angegeben wird wird standardmäßig 1 gewählt, wenn $ende nicht angegeben wird standardmäßig der selbe Wert wie $start. $tk->tag(1) beschreibt also exakt "den ersten".

Die Formulierung eines wiederholten Termins könnte also aussehen:
code:
$tk->tag(1, 31, 2);
$tk->monat(1, 12);
$tk->jahr(2007);
$tk->stunde(18);
$tk->minute(30);

Damit wären die ungeradzahligen Tage (1, 3, 5, ..., 31) der Monate 1 bis 12 des Jahres 2007, jeweils 18:30 gemeint. Was man damit anfangen will weiß ich nicht, nur so als Beispiel.

Anschließend hab ich einen regulären Ausdruck geschrieben, der tag.monat.jahr stunde:minute einliest. Auf Punkte sowie das Leerzeichen und den Doppelpunkt ist zu achten, außerdem sind die Klammern nötig, die im folgenden beschrieben werden.
Jeder Parameter kann wahlweise auf die folgenden Arten geschrieben werden:
- Einzelne Zahl: 18
- Intervall in Grenzen: (1-12)
- Intervall in Grenzen mit Schrittweite: (1-31/2)


Im Script habe ich folgende Beispiele eingebaut:
(2-24/7).12.2007 6:00 Die Adventssonntage, vom 2. bis 23.12.2007 je 6:00
24.12.2007 18:00 Heiliger Abend 18:00
29.2.(1990-2007) 10:00 Jeden 29.2. zwischen 1990 und 2007, also nur in den Schaltjahren
29.2.(1992-2004/4) 10:00 Jedens vierte Jahr am 29.2. zwischen 1992 und 2004, ebenfalls also die Schaltjahre
31.(1-12).2007 12:00 Der 31. jedes Monats, sofern vorhanden
20.11.2007 (8-18)0-30/30) Heute zwischen 8:00 und 18:30 halbstündlich

Mittels $tk->parse() wird eine solche Zeichenkette übernommen. Der erste Parameter übergibt die Zeichenkette, der zweite (optionale) gibt an, ob ein so definierter Termin wirklich angewendet und im Objekt gespeichert oder lediglich als Array zurückgegeben werden soll.


Sollte eine Formulierung einen ungültigen Einzeltermin ergeben (der 31. Februar zum Beispiel) wird ein solcher Termin ignoriert. Alle anderen Termine einer Terminreihe bleiben von der Ungültigkeit eines Einzeltermins unberührt.


$tk->generate liefert ein Array aller durch die gewählten Parameter definierten Termine. Schlüssel jedes Elements ist der time()-Wert, der Inhalt eine lesbare Form. Darf natürlich geändert werden, im Regelfall interessiert mich beim Aufruf eines solchen Scripts die lesbare Form nicht.



Die Erkennung, ob der auszuwertende String ein gültiger ist oder nicht ist anscheinend noch fehlerhaft, ab und an "denkt" mein Script es hätte einen gültigen String vor sich, liest allerdings zu wenige Parameter aus wirft dann einen in Schleife erzeugten Fehler.
*al!ve* - Vorbereitung aufs Urlaubssemester

RANG Master of Clanintern

#7 - 22.11 20:23

Kommt schon, ich bin doch sicher nicht der einzige Leser hier. Meine Apache-Logs beweisen, dass mehrere (eine zweistellige Anzahl sogar) Personen mein Script begutachtet haben. Wenigstens ein "ja, so hätte ich das auch gemacht" oder "nein, ich würd s anders machen" könnte man loswerden. Muss ja nicht jeder programmieren, ein kurzer Dreizeiler genügt ja.
inta

RANG Master of Clanintern

#8 - 22.11 22:56

Hab jetzt draufgeklickt, weil du hier rummäckerst
Bin aber zu betüdelt mich jetzt damit zu beschäftigen, ich würd dir nur mal empfehlen auf php5 zu wechseln.
vaest´ark // patrick *ich bin hier nicht der depp*

RANG Master of Clanintern

#9 - 23.11 15:26

ich habs mir auch direkt angesehen und fands eigentlich gut gelöst. das parameter-system ist zwar nicht unbedingt offensichtlich, aber wenn mans mal durchblickt hat ganz brauchbar.

nur eins hat mich gestört:
31.(1-12).2007 12:00

ergibt ja 7 monate (die, wos 31 tage gibt). ich würde allerdings den termin, wos eben keinen 31ten gibt, auf den nächsten 1. schieben.
ok, implementierungs- und geschmackssache. ich fänds nur sinnvoller
*al!ve* - Vorbereitung aufs Urlaubssemester

RANG Master of Clanintern

#10 - 23.11 17:41

Und ich hab extra ne Abfrage eingebaut, damit das eben *nicht* passiert.

Aber du hast natürlich Recht, das ist Geschmackssache. Und genau das ist die Art von Punkten, auf die ich hier abziele.

Eine Möglichkeit wäre, einen "Overflow"-Parameter einzuführen, der definiert, ob in einem solchen Fall der nächste gültige Wert verwendet werden soll, der letzte gültige oder ob das verworfen werden soll. Denkbar wäre immerhin auch, dass der 31. auf den 30., 29. oder sogar 28. reduziert wird, sofern der zuvor gewählte eben nicht existiert. Somit wäre auch "jeder letzte Tag im Monat" oder sowas in der Art ausdrückbar.
(31-overflow).(1-12).2007 12:00
(31-fallback).(1-12).2007 12:00

Oder ein Alternativparameter der versucht wird, sofern der erste nicht funktioniert.
31(alternativ:30).(1.12).2007 12:00
*al!ve* - Vorbereitung aufs Urlaubssemester

RANG Master of Clanintern

#11 - 24.11 03:38

Ich bin gerade darauf aufmerksam (gemacht) worden, dass sich durch mein System so essenzielle Dinge wie "von a bis b alle zwei Wochen" nicht formulieren lassen. Ich werde das Ding also bei Gelegenheit entsprechend erweitern müssen. Sollte aber kein Stress sein, einfach (ta.ma.ya ha:ma-tb.mb.yb hb:mb/schrittweite) mit schrittweite als Anzahl Minuten definieren oder so.

[edit]

Geändert.

Alt, allerdings jetzt mit Komma:
(2-24/7).12.2007, 6:00
24.12.2007, 18:00
29.2.(1990-2007), 10:00
29.2.(1992-2004/4), 10:00
31.(1-12).2007, 12:00
20.11.2007, (8-18):(0-30/30)

Neu:
1.1.2007, 12:00 - 31.2.2007, 12:00 / 7 days
1.1.2007, 12:00 - 31.2.2007, 12:00 / 1 weeks
31.12.2007, 23:00 - 1.1.2008, 00:00/ 1 minutes
1.1.2007, 0:00 - 31.12.2007, 0:00 / 1 days 2 weeks 3 hours 4 minutes
horst

RANG Prophet of Clanintern

#12 - 24.11 09:10

ich überflieg hier ja nur... aber was war nochmal schlecht am ical format?
jett werde ich bestimmt in grund und boden geredet
*al!ve* - Vorbereitung aufs Urlaubssemester

RANG Master of Clanintern

#13 - 24.11 17:07

ical find ich brauchbar zur Übertragung eines Kalenderzustands (vom Server zum Client, zum Beispiel), wahlweise im Ganzen oder zum Teil. Zur Speicherung eines Kalenders finde ich ical allerdings nur dann überhaupt handhabbar, wenn eine "sehr schnell" (im Regelfall kompilierte, selbstlaufende) Kalenderanwendung dahinter steht. Mehr als handhabbar sondern evtl. sogar "schnell" wird ein Kalender, der all seine Information in einer einzigen (xml ähnlichen) Datei speichert und bei jeder Anfrage diese Datenbankdatei neu übersetzt im Vergleich zu Programmen mit unmittelbarem Datenbankzugriff nie sein.

Wir stellen uns mal vor ich hab i5 bis 10 Termine pro Tag (ich persönlich hab allein 6 geschäftliche täglich, dazu kommen je nach Tag zwischen 0 und 4 weitere private), im Schnitt sagen wir mal 8. Dann führe den Kalender ein Jahr lang. Ich hab somit einen Kalender mit etwa 2800 Einzelterminen, sagen wir 3000 wenn ich drei Wochen im Voraus plane. Mein Kalender fragt den Server jetzt "zeig mir mal die heutigen Termine" und der Server fängt an, eine Datei einzulesen und aus den 3000 enthaltenen Datensätzen die 8 rauszusuchen, die für heute gültig sind.

Für den Transport von Informationen ist ical machbar, für die Speicherung nicht.

Du hast natürlich Recht, man könnte jeden Einzeltermin wie ich es vor habe in der "breit gefecherten" Ausführung speichern und als "Wiederholungsformulierung" anstatt des von mir definierten Formats im ical-Schema. Ical ist mir aber dafür deutlich zu groß und zu umständlich.
horst

RANG Prophet of Clanintern

#14 - 25.11 11:53

sag ich ja .... in grund und boden geredet... macht aber sinn *daumen*