AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Wochentagsberechnung

Ein Thema von Balu der Bär · begonnen am 1. Okt 2006 · letzter Beitrag vom 2. Okt 2006
Antwort Antwort
Balu der Bär
(Gast)

n/a Beiträge
 
#1

Wochentagsberechnung

  Alt 1. Okt 2006, 18:42
Nochmal ein Versuch eines Algorithmuses, schnell frei "übersetzt" nach Delphi aus der Wikipedia.

Ist sicherlich noch verbesserungswürdig, Vorschläge können gern gemacht werden.

Delphi-Quellcode:
(*

Wochentagsberechnung

Frei nach Wikipedia ([url]http://de.wikipedia.org/wiki/Wochentagsberechnung[/url])

Gibt den Wochentag zu einem Datum zurück.

Diese Funktion gibt eine Ganzzahl 0 bis 6 zurück, 0 steht dabei fuer Sonntag,
1 fuer Montag und so weiter. Die Jahreszahl des Datums muss zwischen 800
und 3100 liegen!

Datum: 02.10.2006
Autor: Balu der Baer

*)
 

function GetDaybyDate(day, month, year : Word) : Integer;
var
step1, step2, step3, step4, step5 : Integer;
yearnumbers, centurynumbers, i : Integer;
begin
 yearnumbers := year mod 100;
 centurynumbers := year div 100;
 if not ((centurynumbers >= 8) and (centurynumbers <= 31)) then
 begin
  raise Exception.CreateFmt('function GetDaybyDate: parameter Year must be between 800 and 3100 but is %d', [Year]);
 end else
 begin
  step1 := day mod 7;
  case month of
   1, 10: step2 := 0;
   2, 3, 11: step2 := 3;
   4, 7: step2 := 6;
   5: step2 := 1;
   6: step2 := 4;
   8: step2 := 2;
   9, 12: step2 := 5;
  end;
  step3 := (yearnumbers div 12) + (yearnumbers mod 12) + ((yearnumbers mod 12) div 4);
  case centurynumbers of
   11,15,19,23,27,31 : step4 := 0;
   10,14,18,22,26,30 : step4 := 2;
   9,13,17,21,25,29 : step4 := 4;
   8,12,16,20,24,28 : step4 := 6;
  end;
  if (IsLeapYear(year) and (month = 1)) or (IsLeapYear(year) and (month = 2)) then step5 := 6 else step5 := 0;
  i := (step1 + step2 + step3 + step4 + step5) mod 7;
  result := i;
  end;
end;
Möglicher Aufruf:
Delphi-Quellcode:
var
 days : array [0..6] of String = ('Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag');

...

procedure TForm1.Button1Click(Sender: TObject);
begin
 ShowMessage(days[GetDaybyDate(StrToInt(edit1.Text), StrToInt(edit2.Text), StrToInt(edit3.Text))]);
end;
So, jetzt könnt ihr mich zerfleischen, obwohl ich hoffe das das so in Ordnung ist.
  Mit Zitat antworten Zitat
Benutzerbild von Meflin
Meflin

Registriert seit: 21. Aug 2003
4.856 Beiträge
 
#2

Re: Wochentagsberechnung

  Alt 1. Okt 2006, 18:45
das ist aber suboptimal, weil man sollte noch auswählen können ob die Woche am Sonntag oder Montag beginnt

  Mit Zitat antworten Zitat
Balu der Bär
(Gast)

n/a Beiträge
 
#3

Re: Wochentagsberechnung

  Alt 1. Okt 2006, 18:49
Nach dem gregorianischen Kalender beginnt die Woche imho Sonntag.
  Mit Zitat antworten Zitat
Benutzerbild von Meflin
Meflin

Registriert seit: 21. Aug 2003
4.856 Beiträge
 
#4

Re: Wochentagsberechnung

  Alt 1. Okt 2006, 18:52
Zitat von Balu der Bär:
Nach dem gregorianischen Kalender beginnt die Woche imho Sonntag.
naja...
Zitat:
Der Sonntag gilt in den meisten Ländern der Erde als Wochenbeginn, in Europa hat sich zumindestend im Geschäftsbereich weitestgehend der Montag durchgesetzt. Der Sonnabend als erster Tag findet sich häufig in arabischen Ländern.
http://www.pjh2.de/datetime/weeknumber/ws.php?l=de

Ich wüsste nicht dass der gregorianische Kalender da was festlegt

  Mit Zitat antworten Zitat
Balu der Bär
(Gast)

n/a Beiträge
 
#5

Re: Wochentagsberechnung

  Alt 1. Okt 2006, 19:21
Naja Meflin, meine Funktion hält sich an die Standards die auch Delphi benutzt. Zum Beispiel die Funktion DayOfWeek arbeitet auch mit diesem Prinzip. Auszug OH:
Zitat:
Dabei ist Sonntag Tag 1 und Samstag Tag 7.
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#6

Re: Wochentagsberechnung

  Alt 1. Okt 2006, 19:27
hast du mal das analysiert ?

Delphi-Quellcode:
function DayOfWeek(Date: TDateTime): Integer;
begin
  Result := Trunc(Date) mod 7 +1;
end;
Zitat:
Zum Beispiel die Funktion DayOfWeek arbeitet auch mit diesem Prinzip.
Ja das stimmt, nur das die RTL es viel effizienter macht, siehe meinen Source

Gruß Hagen

[edit]
mein Posting könnte sich eventuell ein bischen arrogant anhören, sorry dafür, ist natürlich nicht so gemeint.

Ein Schmunzeln kann ich mir aber denoch nicht vermeiden, denn wie man sieht kann man mit TDateTime viel effiezienter rechnen als man es vielleicht vermuten würde.

Der Trick ist ganz einfach: TDateTime im Vorkommapart enthält die Anzahl der Tage seit einem fixen Startdatum. Ein TDateTime = 0 ist demzufolge gleich diesem STartdatum. Das Startdatum wurde so gewählt das es ein 1.1. eines Jahres ist und dieser Tag zusätzlich nich ein Sonntag war.

Ergo: den Wochentag eines TDateTime zu berechen oder die Differenz zweier TDateTime in Tagen zu berechnen sind ganz normale mathematiche Operationen, simple Formeln die mit divisionen/subtraktionen auskommen.
[/edit]
  Mit Zitat antworten Zitat
Balu der Bär
(Gast)

n/a Beiträge
 
#7

Re: Wochentagsberechnung

  Alt 1. Okt 2006, 19:31
Zitat:
Ja das stimmt, nur das die RTL es viel effizienter macht, siehe meinen Source
Naja, letztendlich ist es ja auch egal, oder?
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#8

Re: Wochentagsberechnung

  Alt 2. Okt 2006, 10:08
nein ist es eben nicht.

1.) bei häufigen Aufrufen, zb. in Calendarcontrols, spielt die Performance eine große Rolle

2.) die Frage der Gültigkeit deiner Funktion ist entscheidend, denn deine kann nur in einem Bruchteil (Jahr muß 1200 bis 2700 sein), angewendet werden. DayOfWeek() der RTL arbeitet mit jedem Datum was per TDateTime möglich sein kann -> Jahr = -2^47 bis +2^47. Das ist eine rießige Menge mehr.

3.) dein Source sagt einem erfahrenen Programmierer das du garnicht weist wie TDateTime funktioniert. Denn wenn du es wüsstest würdest du eingestehen das dein Source "von hinten in den Kopf und dann durch die Brust" programmiert ist.
Schau mal, dein Posting soll in eine CodeLib, das heist das ich annehmen muß das du der Meinung bist, das andere Programmierer deine Funktion nutzen sollen, als Ersatz für eine optimale DayOfWeek() Funktion der RTL ??
Wenn du diesen Thread in der Delphi Sparte gepostet hättest, zb. mit dem Titel "eine andere Möglichkeit den Wochentag zu berechnen" dann hätte ich es noch verstehen können.

Baue deine Funktion so um das du als Parameter keinen TDateTime erwartest sondern das Jahr,Monat und Tag als Integer. Denn exakt dann, also wenn man in seinem Code eben keinen TDateTime hat sondern nur diese 3 Werte, macht deine Funktion einen Sinn. Zb. als Referenz für Mikrocontroller oder andere Systeme die kein TDateTime kennen. Auf solchen Plattformen wird nämlich meistens mit Jahr,Monat,Tag gerechnet. Aber für einen Anwender der Delphi RTL ist deine Wochentagfunktion schlichtweg sinnlos.

Ich weis das meine Worte eine harte Kritik sind, aber besser die Tatsachen auf den Tisch gelegt als drumherum geredet.

Gruß Hagen
  Mit Zitat antworten Zitat
Balu der Bär
(Gast)

n/a Beiträge
 
#9

Re: Wochentagsberechnung

  Alt 2. Okt 2006, 11:27
Zitat von negaH:
Ich weis das meine Worte eine harte Kritik sind, aber besser die Tatsachen auf den Tisch gelegt als drumherum geredet.
Sehe ich auch so und finde es auch gut.

Zitat:
1.) bei häufigen Aufrufen, zb. in Calendarcontrols, spielt die Performance eine große Rolle
Sicherlich, dass ist mir bewusst. Ich schrieb diese Funktion auch nicht für eine Kalenderkomponente, sondern weil ich so etwas in meinem Programm brauchte. Und da ich dachte es wäre eventuell für den ein oder anderern nützlich, habe ich es mal hier herein gestellt.

Zitat:
2.) die Frage der Gültigkeit deiner Funktion ist entscheidend, denn deine kann nur in einem Bruchteil (Jahr muß 1200 bis 2700 sein), angewendet werden.
Ist mir auch klar, da ich es aber nur in diesem Zeitpunkt brauchte habe ich es nur so geschrieben. Man könnte die Funktion auch einfach weiter ausdehnen, indem man hier
Delphi-Quellcode:
  case centurynumbers of
   15,19,23,27 : step4 := 0;
   14,18,22,26 : step4 := 2;
   13,17,21,25 : step4 := 4;
   12,16,20,24 : step4 := 6;
  end;
den Code entsprechend um weitere Jahrhunderte erweitert, es würde trotzdem nie an TDateTime herankommen, wie du schon richtig erwähnt hast.

Zitat:
3.) dein Source sagt einem erfahrenen Programmierer das du garnicht weist wie TDateTime funktioniert. Denn wenn du es wüsstest würdest du eingestehen das dein Source "von hinten in den Kopf und dann durch die Brust" programmiert ist.
Jupp, gestehe ich gerne ein. Ich hab mich tatsächlich nur sehr flüchtig mit TDateTime beschäftigt, da ich aber schnellstens eine solche Funktion brauchte habe ich in der Wikipedia nach einer Lösung gesucht, und diese dann mit Delphi umgesetzt. Das es bessere und andere Wege gibt war mir immer bewusst, trotzdem dachte ich vielleicht könnte es jemand gebrauchen. Sollte dem nicht so sein kann dieser Thread meinetwegen auch gern in eine andere Forensparte verschoben werden.

Edit: Neue Version siehe oben
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:23 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz