![]() |
Kalenderwoche ermitteln
Hallo zusammen, ich benötige eine Funktion, die bei einem 'on change' Ereignis eines Editfeldes aufgerufen wird. Sie soll folgendes tun: Es gibt ein Editfeld mit einer Kalenderwoche und eines mit der Jahresangabe. Wird nun in ein 3. Editfeld eine Wochenanzahl eingegeben, soll in ein viertes Feld automatisch die 1. Kalenderwoche + der eingegebenen Wochenanzahl erscheinen. Ein 5. Feld beinhaltet das errechnete Jahr.
cw year Wochen cw year 12 2013 5 17 2013 oder 52 2013 6 6 2014 Hat jemand eine Idee? Vielen Dank und Grüße |
AW: Kalenderwoche ermitteln
Da würde ich zuerst einen Blick in DateUtils.pas werfen.
|
AW: Kalenderwoche ermitteln
Hallo,
zum Berechnen der Kalenderwoche wirst Du eine Menge Tipps in allen möglichen Code-Collections finden, u.a. hier: ![]() Gruß Thomas |
AW: Kalenderwoche ermitteln
Oder in
![]() |
AW: Kalenderwoche ermitteln
Gibts na nicht ne fertige Funktion in einer der Units, die bei Delphi dabei sind?
Wie hieß die doch gleich... Verdammt, komm nich drauf, irgendwas mit ...Utils. tcpUtils.pas? Nee. |
AW: Kalenderwoche ermitteln
Hallo,
eigentlich ist das doch "nur" ein bisserl Rechenarbeit. Eventuell hilft dasda ja:
Delphi-Quellcode:
Ist ungetestet mal einfach so dahingedaddelt.
procedure Wochenrechner;
var dt : TDateTime; cw1 : Integer; Wochen : Integer; cw2 : Integer; Jahr : Integer; begin cw1 := StrToInt(edCW1.Text); // im Beispiel 52 cw1 := cw1 * 7; // Ergibt die Anzahl Tage für 52 Wochen. dt := StrToDate('01.01.') + StrToInt(edYear.Text); // im Beispiel 2013 dt := dt + cw1; // Ist das Datum der 52. Woche. Wochen := StrToInt(edWochen.Text); // im Beispiel 6 Wochen := Wochen * 7; // Ergibt die Anzahl Tage für 6 Wochen. dt := dt + Wochen; // Zum Datum der 52 Wochen entsprechende Anzahl Tage hinzuzählen. cw2 := WeekOfTheYear(dt); // Die Woche des errechneten Datums ermitteln. Jahr := YearOf(dt); // Das Jahr des errechneten Datums ermitteln. edCW2.Text := IntToStr(cw2); edYear.Text := IntToStr(Jahr); end; Oder ein bisserl kürzer:
Delphi-Quellcode:
Latürnich auch nicht getestet.
var
dt : TDateTime; begin dt := StrToDate('01.01.') + StrToInt(edYear.Text) + (StrToInt(edCW1.Text) + StrToInt(edWochen.Text)) * 7; edCW2.Text := IntToStr(WeekOfTheYear(dt)); edYear.Text := IntToStr(YearOf(dt)); end; |
AW: Kalenderwoche ermitteln
Ganz so einfach ist das nicht, schon deshalb nicht, weil der 01.01.jjjj nicht unbedingt der Beginn der Woche 1 des Jahres jjjj sein muss. 2014 beginnt die Woche 1 am 30.12.2013, zumindest in Deutschland, wenn man sich mal darauf reduziert.
Die Woche 1 in Deutschland ist die, die den ersten Donnerstag enthält. ![]() Die Woche 1 in den USA ist die, die den 1. Januar enthält. Ist der 01.01. ein Fr,Sa,So, beginnt die Woche 1 in Deutschland am folgenden Montag. Ist der 01.01. ein Mo,Di,Mi,Do, beginnt die Woche 1 in Deutschland in dieser Woche, auch wenn davon noch ein paar Tage zum alten Jahr gehören (siehe Kalender 2014) Man muss also zunächst ermitteln, zu welchem Wochentag der 01.01. des Ausgangsjahres gehört und danach bestimmen, an welchem Tag die Woche 1 des Ausgangsjahres beginnt, das kann u.U. auch ein Tag des Vorjahres sein, z.B.30.12.2013 = 1. Tag der Woche 1 von 2014. Die Anzahl Wochen kann man mit 7 (Tage pro Woche) multiplizieren und zum Datum des ersten Tages der Woche 1 addieren. Aus dem dabei entstehenden Datum (1. Tag der gesuchten Woche) muss nun ähnlich wie vorher die Woche ermittelt werden. Dazu zunächst das Datum der ersten Tages der Woche 1 ermitteln und dann die Tagesdifferenz zwischen 1.Tag Woche 1 und berechnetem Datum / 7 ergibt die gewünschte Woche. Auch hier aufpassen, wenn das ermittelte Datum z.B. der 31.12.2013 ist, dann ist das die Woche 1 des Jahres 2014 ! Das Jahr des Datums des Wochenbeginns muss nicht das Jahr der zugehörogen Woche sein. Beispiel 30.12.2013 gehört zur Woche 01-2014 |
AW: Kalenderwoche ermitteln
Ich weiß nicht, ob ich neuerdings in Geheimschrift tippe oder einfach ignoriert werde :gruebel:
Zitat:
|
AW: Kalenderwoche ermitteln
@DeddyH
Zitat:
Also: Die Beachtung der Sonderregeln erfolgt durch die Nutzung der von Dir genannten Funktion. Oder: Einfacher gehts nicht ;-) |
AW: Kalenderwoche ermitteln
Delphi-Quellcode:
Ich habe das mal getestet jedoch zuvor ein bisschen geändert
var
dt : TDateTime; begin dt := StrToDate('01.01.') + StrToInt(edYear.Text) + (StrToInt(edCW1.Text) + StrToInt(edWochen.Text)) * 7; edCW2.Text := IntToStr(WeekOfTheYear(dt)); edYear.Text := IntToStr(YearOf(dt)); end;
Delphi-Quellcode:
Wenn z.B. Woche 52/2013 + 1 Woche, dann wird als Datum der 07.01.2014 ermittelt, und das ist die Woche 02/2014, richtig wäre jedoch Woche 01/2014.
var
dt : TDateTime; begin dt := StrToDate('01.01.'+edYear.Text)) // <== Hier wurde Str und Int addiert, gemeint was '01.01.JJJJ' + (StrToInt(edCW1.Text) + StrToInt(edWochen.Text)) * 7; Label6.Caption := 'Datum = '+DateToStr(dt); // edCW2 := IntToStr(WeekOfTheYear(dt)); // edYear := IntToStr(YearOf(dt));end; Die Ursache ist, wie von mir oben genannt, man kann nicht einfach den 01.01. als Startdatum nehmen (das war 2013 ein Dienstag) sondern, wenn man es so macht, den Montag der Woche 01/2013, das war der 31.12.2012 - und das muss man etwas aufwendiger im Vorfeld ermitteln. In der Anweisung dt:= werden zum 01.01.2013 (52+1)*7 = 371 Tage dazugezählt. Das ergibt den 372. Tag 2013, die Funktion DateToStr ermittelt daraus den 07.01.2014, das ist richtig, wenn man 365 abzieht und beim Jahr 1 dazuzählt. Die Woche 52/2013 geht vom 23.12.-29.12.2013, die Woche+1 vom 30.12.2013-05.01.2014. Der ermittelte Tag 07.01.2014 stimmt in keine Weise. Die beiden letzten Anweisungen musste ich deaktivieren, weil mein D7 die Funktionen nicht übersetzen kann. Übrigens auch das ganz oben genannte Aufgabenbeispiel : Woche 12/2013 + 5 Wochen => 17/2013 ergibt das Datum 30.04.2013, und das liegt in der Woche 18/2013 Man käme wahrscheinlich etwas besser, wenn man statt (StrToInt(edCW1.Text) + StrToInt(edWochen.Text)) * 7 besser (StrToInt(edCW1.Text) -1 + StrToInt(edWochen.Text)) * 7 benutzt. z.B. Woche 1 + 1 Woche im alten Verfahren (1+1)*7 = 14 Tage + 01.01. = 15.01. Der 15.01 liegt immer in Woche 3, richtig wäre aber Woche 2. |
AW: Kalenderwoche ermitteln
Gerade mit Delphi 7 geschrieben:
Delphi-Quellcode:
uses DateUtils;
procedure CalculateNewWeekOfYear(WeekIn, YearIn, Offset: integer; out WeekOut, YearOut: integer); var DateValue: TDateTime; begin DateValue:= IncWeek(StartOfAWeek(YearIn, WeekIn), Offset); WeekOut := WeekOfTheYear(DateValue); YearOut := YearOf(DateValue); end; procedure TForm1.Button1Click(Sender: TObject); var OldYear, OldWeek, NewYear, NewWeek, Offset: integer; begin OldWeek := StrToInt(Edit1.Text); OldYear := StrToInt(Edit2.Text); Offset := StrToInt(Edit3.Text); CalculateNewWeekOfYear(OldWeek, OldYear, Offset, NewWeek, NewYear); Edit4.Text := IntToStr(NewWeek); Edit5.Text := IntToStr(NewYear); end; |
AW: Kalenderwoche ermitteln
Hallo,
bist Du damit zufrieden? ;-)
Delphi-Quellcode:
In die Uses-Klausel
procedure TForm1.Button1Click(Sender: TObject);
var dt : TDateTime; dw : Integer; begin dt := StrToDate('01.01.' + edYear.Text); dw := DayOfWeek(dt); if dw < 5 then dw := 7 else dw := 0; dt := dt + (StrToInt(edCW1.Text) + StrToInt(edWochen.Text)) * 7 - dw; edCW2.Text := IntToStr(WeekOfTheYear(dt)); edYear2.Text := IntToStr(YearOf(dt)); end;
Delphi-Quellcode:
mit aufnehmen, dann dürften auch
DateUtils
Delphi-Quellcode:
und
WeekOfTheYear
Delphi-Quellcode:
funktionieren.
YearOf
|
AW: Kalenderwoche ermitteln
Die Uses-Klausel an der richtigen Stelle habe ich bereits eingebaut (dank diesem Forum !).
Jetzt sieht es schon etwas besser aus, ist aber immer noch fehlerbehaftet, weil die Funktion YearOf(dt) zwar das richtige Jahr zum Datum liefert, dieses Jahr gehört aber nicht zur Woche. Test: Woche 52/2013 + 1 Woche => ergibt als Datum den 30.12.2013 (ist ok) und als Woche 01 (auch ok) aber als Jahr 2013, das ist falsch, es muss ja die Woche 01/2014 sein. Es müsste also eine Funktion JAHR-ZUM-DATUM(dt) und JAHR-ZUR-WOCHE(dt) geben. Evtl kann man das lösen, indem man abfragt, ob die Woche-Neu kleiner als die Woche-alt ist und in diesem Fall zum JAHR-NEU eine 1 dazu addieren, aber nur dann, wenn der Monat des Datums-Woche-neu eine 12 ist. Das klappt aber auch nicht immer, z.B. Test: Woche 52/2003 + 1 Woche = 31.12.2003 (ein Mittwoch), der 1.1.2004=Donnerstag, demnach beginnt Woche 1/2004. Es wird statt 01/2004 das Ergebnis 01/2003 geliefert. Also für das richtige Jahr zur Woche bei Jahreswechselüberschreitung muss man noch eine 100%ige Lösung finden. Die vorhandenen Funktionen liefern das für Deutschland nicht. In den USA, wo immer die Woche 1 mit dem 01.01. beginnt, stimmt das vielleicht. Obwohl das Beispiel 2003/2004 zeigt, dass es nicht stimmt.
Delphi-Quellcode:
@DeddyH, ich habe Deine Version probiert, auch damit wird z.B. bei 52/2003 + 1 Wo = 01/2003 ermittelt, statt 1/2004 - also die gleiche Jahreswechselproblematik.
procedure TForm1.Button2Click(Sender: TObject);
var dt : TDateTime; iYear2,iWeek1,iWeek2,iMon2 : Integer; begin iWeek1 := StrToInt(ComboBox1.Items[Combobox1.ItemIndex]); dt := StrToDate('01.01.' + ComboBox3.Items[Combobox3.ItemIndex]) //edYear.Text) + (iWeek1 -1 + StrToInt(ComboBox2.Items[Combobox2.ItemIndex])) * 7; iWeek2 := WeekOfTheYear(dt); iMon2 := MonthOfTheYear(dt); iYear2 := YearOf(dt); if iWeek2 < iWeek1 then if iMon2 = 12 then Inc(iYear2); Label6.Caption := 'Datum = '+DateToStr(dt); Label7.Caption := 'Woche = '+IntToStr(iWeek2)+'/'+IntToStr(iYear2); end; |
AW: Kalenderwoche ermitteln
In der Hilfe habe ich folgendes gefunden
Delphi-Quellcode:
Wenn man die Aufrufvariante mit den zwei Parametern benutzt, dann bekommt man das hoffentlich richtige Jahr zur Woche.
Die Funktion gibt die Woche des Jahres zurück, das durch einen TDateTime-Wert repräsentiert wird.
Unit DateUtils Kategorie Datum/Zeit Delphi-Syntax: function WeekOfTheYear(const AValue: TDateTime): Word; overload; function WeekOfTheYear(const AValue: TDateTime; var AYear): Word; overload; Beschreibung Mit WeekOfTheYear können Sie die Woche des Jahres ermitteln, das durch den angegebenen TDateTime-Wert repräsentiert wird. WeekOfTheYear gibt einen Wert zwischen 1 und 53 zurück. AYear gibt das Jahr mit der angegebenen Woche zurück. Dieser Wert darf nicht mit dem Jahr in AValue identisch sein. Der Grund liegt darin, dass die erste Woche eines Jahres als erste Woche definiert ist, von der mindestens vier Tage in das betreffende Jahr fallen. Ist also der erste Kalendertag eines Jahres der Freitag, Samstag oder Sonntag, gibt WeekOfTheYear für die ersten drei oder zwei Tage oder für den ersten Tag des Kalenderjahres die Woche des vorhergehenden Jahres zurück. Entsprechendes gilt am Jahresende: Ist der letze Kalendertag eines Jahres ein Montag, Dienstag oder Mittwoch, gibt WeekOfTheYear für die letzten drei oder zwei Tage bzw. den letzten Tag des Kalenderjahres den Wert 1 (erste Woche des nächsten Kalenderjahres) zurück. Hinweis: WeekOfTheYear verwendet die Wochendefinition des ISO-Standards 8601. Demzufolge beginnt eine Woche am Montag und endet mit dem Sonntag. Hinweis: WeekOfTheYear gibt den gleichen Wert wie die Funktion WeekOf zurück. Zum 31.12.2003 wird als Woche/Jahr => 01/2004 geliefert. Das JAHR der WOCHE und des konkreten Tages stimmen beim Jahreswechsel nicht zwingend überein.
Delphi-Quellcode:
Var
wo,jw : Word; :::: wo := WeekOfTheYear(pdDate, jw); |
AW: Kalenderwoche ermitteln
Hallo,
wenn man kein DateUtils hat und so und so auf "Handarbeit" steht, macht es folgender Code richtig.
Delphi-Quellcode:
Bei Übergabe von Tag, Monat und Jahr an die Routine Kalenderwoche gibt's den richtigen Wert zurück.
function Schaltjahr(word_Jahr : Word) : Boolean;
Begin result := ( (word_Jahr mod 4 = 0) and not (word_Jahr mod 100 = 0) ) or (word_Jahr mod 400 = 0); end; function Wochentag_(t, m : Byte; j : Word) : Byte; const c1 : ARRAY[1..12] OF Byte = (0,3,3,6,1,4,6,2,5,0,3,5); c2 : ARRAY[0..3] OF Byte = (6,4,2,0); var a,w, j1, j2 : Byte; begin j1 := j div 100; j2 := j mod 100; a:= (t MOD 7) + (c1[m]) + (j2 MOD 7) + ((j2 DIV 4) MOD 7) + (c2[(j1 MOD 4)]); IF Schaltjahr(j) THEN Dec(a); w := a MOD 7; Wochentag_ := w; end; function Kalendertag(tag, monat : byte; jahr : word) : Word; const TageProMonat : ARRAY[1..11] OF Byte =(31,28,31,30,31,30,31,31,30,31,30); var counter : Byte; GesamtTage : Word; begin GesamtTage:=0; FOR counter := 1 TO (monat-1) DO GesamtTage := GesamtTage + TageProMonat[counter]; GesamtTage := GesamtTage + tag; IF Schaltjahr(jahr) AND (monat > 2) THEN Inc(GesamtTage); Kalendertag := GesamtTage; end; function Kalenderwoche(Tag, Monat: Byte; Jahr : Word) : Byte; var Kalendertage, Vorjahr : Word; Woche, Primus : Byte; const Korrektur : ARRAY[0..6,1..2] OF ShortInt = ((-6,0),(0,1),(-1,1),(-2,1),(-3,1),(-4,0),(-5,0)); begin kalendertage:=kalendertag(tag,monat,jahr); Vorjahr := Jahr - 1; Primus:=Wochentag_(1,1,Jahr); Woche:=Trunc((Kalendertage - 1 - Korrektur[Primus,1]) / 7) + Korrektur[Primus,2]; IF (Woche = 53) THEN BEGIN IF (Primus = 4) OR (Wochentag_(31,12, Jahr) = 4) THEN Woche := 53 ELSE Woche := 1; END; IF (Woche=0) THEN BEGIN IF ((Wochentag_(31,12, Vorjahr) = 4) OR (Wochentag_(1,1, Vorjahr) = 4)) THEN Woche := 53 ELSE Woche := 52; END; Kalenderwoche:=Woche; end; Diese Berechnung habe ich seit Jahren im Gebrauch und sie funktioniert tadellos. Beste Grüße Mathematiker |
AW: Kalenderwoche ermitteln
Ich habe mal (vor 20 Jahren oder so: Grauenvolle Nomenklatur) diesen Code produziert. Bisher hat sich auch noch niemand beschwert, und etwas einfacher und verständlicher als der Code vom Mathematiker ist er auch. Vielleicht stimmt die Berechnugn für das Jahr 6592 nicht, aber mir ist das wurscht.
Delphi-Quellcode:
Function CsGetWeek(_Date: TDateTime): Word;
// Zunächst wird die KW des 1.1 des Jahres ermittelt. // Sind in der ersten KW des Jahres mehr als vier Tage, // dann ist dies die KW 1, sonst die KW '0' bzw. // die KW des 31.12. des vorherigen Jahres. Var MondayOfKW1, FirstOfJanuary: TDateTime; Dow, KW, y, m, d: Word; Begin DecodeDate(_Date, y, m, d); FirstOfJanuary := EncodeDate(Y, 1, 1); Dow := SysUtils.DayOfWeek(FirstOfJanuary); If Dow <= 5 Then MondayOfKW1 := FirstOfJanuary - Dow + 1 Else MondayOfKW1 := FirstOfJanuary + 8 - Dow; KW := Trunc(_Date - MondayOfKW1) Div 7 + 1; If KW < 1 Then KW := CsGetWeek(EncodeDate(Y - 1, 12, 31)) Else If KW = 53 Then If SysUtils.DayOfWeek(EncodeDate(Y + 1, 1, 1)) <= 4 Then KW := 1; Result := KW; End; |
AW: Kalenderwoche ermitteln
Im nächsten Forum gebe ich mir auch einen Frauennamen, damit sich an trivialen Fragen die Herren die Zähne ausbeissen.
Sherlock |
AW: Kalenderwoche ermitteln
Die Kalenderwoche zu einem Datum zu ermitteln war nicht die ursprüngliche Aufgabe, sondern zu Woche/Jahr eine Anzahl Wochen zu addieren, um wieder Woche/Jahr zu erhalten. Dabei können die Anzahl Wochen auch mehrere Jahre (mit und ohne Schaltjahre) sein, z.B. um S21 oder BER fertigzustellen.
|
AW: Kalenderwoche ermitteln
Hallo,
ich weiß nicht, ob es in Delphi 2009 DateUtils schon gab. Damit gibt es jedenfalls mehrere Möglichkeiten, wie die gestellt Aufgabe gelöst werden kann. Hier ein Beispiel (ed.. sind TEdit und lbl.. TLabel):
Delphi-Quellcode:
Und wenn jemand möglichst wenig Zeilen haben will, dann kann man das Ganze auch so schreiben, dass man(n/frau) beim Lesen denken muss:
uses ..., DateUtils;
procedure TForm1.Button1Click(Sender: TObject); var dtJahr, dtWoche, dtDifferenz: Word; dt: TDateTime; begin dt := EncodeDateWeek(StrToInt(edJahr.Text), StrToInt(edWoche.Text)); dt := IncWeek(dt, StrToInt(edDifferenz.Text)); DecodeDateWeek(dt, dtJahr, dtWoche, dtDifferenz); lblJahr.Caption := IntToStr(dtJahr); lblWoche.Caption := IntToStr(dtWoche); end;
Delphi-Quellcode:
uses ..., DateUtils;
procedure TForm1.Button1Click(Sender: TObject); var dtJahr, dtWoche, dtDifferenz: Word; dt: TDateTime; begin DecodeDateWeek(IncWeek(EncodeDateWeek(StrToInt(edJahr.Text), StrToInt(edWoche.Text)), StrToInt(edDifferenz.Text)), dtJahr, dtWoche, dtDifferenz); lblJahr.Caption := IntToStr(dtJahr); lblWoche.Caption := IntToStr(dtWoche); end; |
AW: Kalenderwoche ermitteln
Das klappt auch bei meinem Delphi 7 wunderbar, man kann sogar eine negative Anzahl Wochen eingeben, um im Kalender rückwärts zu rechen.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:08 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz