Kalenderwoche ermitteln

Begonnen von qwert73, 25. Oktober 2009, 20:55:10

Vorheriges Thema - Nächstes Thema

qwert73

... einfach 1 abziehen! Wenn es denn so einfach wäre - ich versteh nur Bahnhof! ;)
Wenn Du irgendwann mal in den nächsten Jahren soviel Zeit haben solltest, dass du nicht weißt, wie Du die Langeweile bekämpfen sollst, könntest Du ja die Bestimmung der Kalenderwoche in Title Formatting übersetzen. Zumindest ich wäre dir sehr dankbar. :)

Thema von hier abgetrennt - tedgo

tedgo

#1
@qwert73
Tja, gar nicht so einfach, weil man für eine exakte Kalenderwochenbestimmung ja den Wochentag berücksichtigen muss...

Einfach wäre zunächst natürlich mal festzustellen, der wievielte Tag des Jahres das betreffende Datum überhaupt hat (mal am Beispiel von %added%, inkl. Berücksichtigung von Schaltjahren):

$puts(ad.raw.m,$select($month(%added%),0,31,59,90,120,151,181,212,243,273,304,334))
$puts(ad.m,$ifgreater($month(%added%),2,$add($get(ad.raw.m),$select($add($mod($year(%added%),4),1),1)),$get(ad.raw.m)))
$puts(ad.d,$day_of_month(%added%))
$puts(ad.days,$add($get(ad.m),$get(ad.d)))

Jetzt könnte man ad.days einfach durch 7 teilen, das wäre aber nicht gerade exakt und würde außerdem - da TitleFormatting ja nur mit integren Zahlen arbeitet - in den ersten 6 Tagen immer Woche 0 ergeben. Also müsste man zum Ergebnis entweder 1 dazuzählen oder sagen 0=53...
Vielleicht bleib ich mal dran, das ist eine gar nicht so uninteressante Herausforderung :)
Vielleicht gehe ich die ganze Sache aber auch von der völlig falschen Seite an und jemand hat bereits eine viel einfachere Lösung...

Erich_2

Es ist eigentlich unfassbar, dass Programmierer des Jahres 2009 sich mit diesem Datums-Sch*** auseinander setzen müssen. Eigentlich gehört auf jedes Mainboard ein eigener Datums-Chip implementiert, auf dessen Funktionen man zugreifen sollte - und zwar Länderspezifisch. Ich  bin u. a. Computer-Dozent und ernte jedes Mal große ungläubige Blicke von den vor mir sitzenden Fortschrittsgäubigen, welche bekloppten Dinge man machen muss, wenn man Datums- oder Zeitberechnungen durchführen muss (gleich welcher Art oder mit welcher Sprache oder Programm). Die Frage: "Wie viele Tage bin ich schon auf der Welt?" ist analog zu betrachten zur Frage: "Wie viele Tage sind seit 'first played' vergangen?".
Wir sind mitten im Mittelalter!  :(

Trotzdem noch ein interessanter Text dazu:
http://www.enterag.ch/hartwig/julian/julian.html

qwert73

#3
Zitat von: tedgo in 26. Oktober 2009, 08:24:03

Tja, gar nicht so einfach, weil man für eine exakte Kalenderwochenbestimmung ja den Wochentag berücksichtigen muss...

Stimmt, weil ja die erste Kalenderwoche nicht zwangsläufig am 1. Januar eines Jahres beginnt, sondern am ersten Montag eines jeweiligen Jahres.

Die Berechnung des Wochentages ist ja schon auf der von mir verlinkten Seite in HA geleistet worden:
$select($add($mod($add(
$mul(2,$sub(3,$mod($left($year(%last_modified%),2),4))),
$right($year(%last_modified%),2),
$div($right($year(%last_modified%),2),4),
$select($month(%last_modified%),$ifequal($mod($year(%last_modified%),4),0,6,0),
$ifequal($mod($year(%last_modified%),4),0,2,3),3,6,1,4,6,2,5,0,3,5),
$day_of_month(%last_modified%)),
7),1),Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday)


Desweiteren ist für die Ermittlung der Kalenderwoche (siehe hier) entscheidend, den wievielten Tag des Jahres ein bestimmtes Datum repräsentiert. Die daraus folgende Rechnung ist dann relativ simpel: Nehmen wir an, der erste eines Jahres ist ein Samstag, dann würde die erste Kalenderwoche 2 Tage später am 3. Januar beginnen. Wenn wir nun von einem Datum wissen, dass es der 250. Tag eines Jahres ist, so müssen wir von 250 die 2 Tage abziehen und die Differenz durch 7 dividieren. Zu berücksichtigen bleibt noch das Schaltjahr, in dem es noch den 29. Februar gibt (siehe hier).

Das alles zu verstehen ist nicht so schwierig: Das eigentliche Kunststück besteht darin, das Gewußte in Title Formatting zu zwingen.

Edit:

Zitat von: tedgo in 26. Oktober 2009, 08:24:03

Vielleicht bleib ich mal dran, das ist eine gar nicht so uninteressante Herausforderung ...


Och, irgendwie habe ich auch Lust, mich daran zu machen - leider bleibt nicht soviel Zeit bei Job und Kind. Darüberhinaus bin ich nicht wirklich versiert im Schreiben komplexerer TF Snippets.





tedgo

#4
Ach, den Link habe ich übersehen...
Na, daraus lässt sich vielleicht was machen. Mal sehen :)

Das Schaltjahr ist in meinem TF-Snippet zur "Tag des Jahres"-Ermittlung übrigens bereits berücksichtigt ;)

Auf was soll sich denn diese Kalenderwoche eigentlich beziehen?
%added%, %first_played%, %last_played% oder %last_modified%?

qwert73

Am ehesten noch %last_played%.

In dem Zusammenhang fällt mir wieder ein, wie schön es doch wäre, wenn foobar2000 irgendwann auch %<multiple tags>% sicher in allen TF Funktionen verwenden könnte. Wenn dann auch noch das offizielle Playback Statistics %play_stamp% anböte ....

fbuser

Zitat von: qwert73 in 26. Oktober 2009, 18:52:12Stimmt, weil ja die erste Kalenderwoche nicht zwangsläufig am 1. Januar eines Jahres beginnt, sondern am ersten Montag eines jeweiligen Jahres.
Das stimmt nicht. Wikipedia:
Zitatdie erste Woche, in die mindestens vier Tage des neuen Jahres fallen (DIN 1355 / ISO 8601); äquivalent dazu
    * die Woche, die den 4. Januar enthält
    * die Woche, die den ersten Donnerstag des Jahres enthält
Die erste Kalenderwoche eines Jahres kann im Extremfall also bereits am 29.12. des Vorjahres beginnen.

tedgo

#7
Stimmt, das habe ich bereits berücksichtige ;)

Hiermit:

$puts(predays,$select($add($mod($add(6,$right($year(%last_played%),2),$div($right($year(%last_played%),2),4),$ifequal($mod($year(%last_played%),4),0,6,0),1),7),1),5,6,7,8,9,3,4))
$puts(lp.raw.m,$select($month(%last_played%),0,31,59,90,120,151,181,212,243,273,304,334))
$puts(lp.m,$ifgreater($month(%last_played%),2,$add($get(lp.raw.m),$select($add($mod($year(%last_played%),4),1),1)),$get(lp.raw.m)))
$puts(lp.d,$day_of_month(%last_played%))
$puts(lp.days,$add($get(lp.m),$get(lp.d),$get(predays)))
$puts(cal.week,$ifgreater($get(lp.days),6,$div($get(lp.days),7),53))


$get(cal.week) sollte jetzt die richtige Kalenderwoche ausgeben.
Soweit die Ermittlung des Wochentages aus dem Link korrekt ist (das habe ich jetzt nicht geprüft)...
Ich habe die Ermittlung allerdings etwas vereinfacht und auf last_played zwischen 2000 und 2100 beschränkt.
Denn es kann kaum sein, dass jemand ein Lied in seiner Sammlung hat, dass vorher zum letzten mal gespielt wurde (zumal es foobar2000 da noch gar nicht gab) oder ein last_played nach 2099 erleben wird ;)

Ich gebe aber keine Garantie auf die Richtigkeit dieser Kalenderwochen-Ermittlung!
Zum einen, weil ich die Ermittlung des Wochentages nicht überprüft habe und zum anderen, weil ich das jetzt mal so schnell dahingeschludert habe  ::)
Sollte aber passen.

qwert73

Sag mal: wie schnell geht das bei dir?  ;)

Wenn ich mal zeit habe, teste ich das Snippet.

Danke Schön!

tedgo

#9
:D
Na ich musste ja nur noch die beiden Schnipsel zusammensetzen und ein klein wenig anpassen.

Aber wie gesagt: Ich weiß nicht, ob es tadellos funktioniert, da ich die TitleFormatting-Ermittlung des Wochentages, die du verlinkt hast, nicht überprüft habe...
In meinen Kurztests hat es jedenfalls geklappt.

qwert73

#10
Zitat von: fbuser in 26. Oktober 2009, 20:06:55
Zitat von: qwert73 in 26. Oktober 2009, 18:52:12Stimmt, weil ja die erste Kalenderwoche nicht zwangsläufig am 1. Januar eines Jahres beginnt, sondern am ersten Montag eines jeweiligen Jahres.
Das stimmt nicht.


Da hast Du völlig recht. Das ist mir schon aufgefallen, als ich einen Blick in die Kalenderfunktion meines Handys geworfen habe. Mir ist ein schwerwiedgender Verständnisfehler unterlaufen: Gelesen habe ich "Eine Kalenderwoche beginnt aber laut der DIN 1355 - Zeit immer Montags" - verstanden jedoch das von dir zitierte.

Am Ende der von mir verlinkten Seite ist auch zu lesen:
"Dieser Algorithmus berechnet zunächst den Jahrestag des Datums, und dann wird die Tagesanzahl so korrigiert, dass beginnend vom ersten Montag des Jahres gerechnet wird. Dies funktioniert gut für 51 Wochen des Jahres, Probleme bereiten die ersten und die letzten Tage des Jahres. Sofern eine negative Tageszahl ermittelt wurde, liegen die ersten Tage eines Jahres in der letzten Woche des Vorjahres. Dabei muss berücksichtigt werden, dass ein Jahr eine 53. Woche hat, wenn es mit einem Donnerstag beginnt oder endet. Genauso muss für die letzten Tages des Jahres bestimmt werden, ob sie in der letzten Woche des aktuellen Jahres liegt, oder aber bereits in der ersten Woche des Folgejahres. "


Zitat von: tedgo in 26. Oktober 2009, 20:18:03
Denn es kann kaum sein, dass jemand ... ein last_played nach 2099 erleben wird ;)
Warten wir lieber mal ab!

qwert73

#11
Wer zum Thema was lesen will, hier dreiArtikel, die ich gefunden habe:

http://www.doktus.de/dok/44945/an-welchem-wochentag-wurde-john-horton-conway-geboren-eine-einfuehrung-in-die-doomsday-methode.html

http://www.doktus.de/dok/51872/kalenderrechnung-wochentagsberechnung-und-berechnung-des-ostertermins-nach-christian-zeller.html

http://de.wikipedia.org/wiki/Ewiger_Kalender

(Edit: dritten Artikel hinzugefügt)

Edit2:

Hier endlich mal eine Seite, wo zur Wochentagsberechnung eine simple Formel präsentiert wird - man kann also mit dem Taschenrechner den Wochentag ermitteln:

http://de.wikisource.org/wiki/Kalender-Formeln

tedgo

#12
- mein letzter Beitrag war von der Dummheit des Authors geprägt und wurde deshalb von diesem (also mir) gelöscht -  ::)

@qwert73
Also, mal von deinem Link ausgehend folgende Ermittlung:

$puts(cent.y,$right($sub($year(%last_played%),1),2))
$puts(predays,$select($add($mod($add(2,$get(cent.y),$div($get(cent.y),4)),7),1),4,5,6,7,8,9,3))
$puts(lp.raw.m,$select($month(%last_played%),0,31,59,90,120,151,181,212,243,273,304,334))
$puts(lp.m,$ifgreater($month(%last_played%),2,$add($get(lp.raw.m),$select($add($mod($year(%last_played%),4),1),1)),$get(lp.raw.m)))
$puts(lp.d,$day_of_month(%last_played%))
$puts(lp.days,$add($get(lp.m),$get(lp.d),$get(predays)))
$puts(cal.week,$ifgreater($get(lp.days),6,$div($get(lp.days),7),53))

So müsste es jetzt passen :)

PS: Habe mir erlaubt, das Thema zu teilen und aus den Beiträgen zur Kalenderwoche ein eigenes Thema zu machen.