![]() |
FMX - DX10 - Falsche Wochennummer im TCalendar
Wie ich leider gerade feststellen musste, zeigt die FMX-TCalendar-Komponente die falsche Wochennummer an (für diese Woche, den 6. Januar schon die 2. Woche, ist aber tatsächlich die erste, das Jahr 2015 hatte 53 Wochen).
Siehe Meldung bei QC hier: ![]() Nur gut, dass ich die MAC-Version meines Termin- und Aufgabenprogramms noch unter Beta-Status veröffentlicht habe, mit falschen Wochenzahlen ist das echt mies:cry: Ich hatte gerade mal versucht, die Quelle des Übels auszumachen, damit ich das evtl. selber mit einem Fix beheben kann. Irgendwie komme ich aber nicht an die Stelle ran. Die FMX-Calendar-Komponente wird vermutlich mit einem Style gezeichnet, dazu werden wohl Botschaften verschickt, ich weiß aber nicht wohin und welche Stelle ich quasi abhören müsste, um an die konkrete Zeichenroutine zu kommen. Ein Debugg-Versuch (z.B. ab OnPainting) führte leider nicht zum Ziel. Hat da evtl. Jemand eine Idee? |
AW: FMX - DX10 - Falsche Wochennummer im TCalendar
Delphi-Quellcode:
Zeile 584f :stupid:
unit FMX.Calendar.Style;
Man beachte den Kommentar in Zeile 583:
Delphi-Quellcode:
Da hat also ein Programmierer von Emba einen (angeblichen) Fehler in der Funktion
// WeekOfTheYear doesn't consider a current Locale. So for 01.01.2017 returns 52.
if MonthOf(FDateTime) = MonthJanuary then FirstWeekOfMonth := 1 else FirstWeekOfMonth := WeekOfTheYear(RecodeDay(FDateTime, 1));
Delphi-Quellcode:
festgestellt. Aber anstatt diesen Fehler einmal intern an das
WeekOfTheYear
Delphi-Quellcode:
-Team zu melden (ja, dafür hätte er wohl 4 Wochen Kaffee für alle holen müssen) denkt er sich eine ganz tolle Methode aus:
System.DateUtils
Jedes Jahr startet mit der Woche 1 :roll: Aber seine wir froh, dass er nicht einfach die
Delphi-Quellcode:
-Routine "gefixt" hat :mrgreen:
WeekOfTheYear
@Harry Melde doch mal diesen
Delphi-Quellcode:
"Fehler" und verweise stumpf und vor allem erbost auf den Kommentar. Die stellen selber Fehler fest und korrigieren die nicht. Mal sehen was passiert ... ob wir das Geschrei bis hier hören können? :stupid:
WeekOfTheYear
|
AW: FMX - DX10 - Falsche Wochennummer im TCalendar
Hmm..
Stellt sich die Frage, was liefert WeekOfYear für den 1.1.2016? Muss eigentlich KW 53 sein, so wie (richtig) 1.1.2017 noch zur KW 52 gehört ;) Blubber Blubber (noch zu Früh) "WeekOfTheYear" Und bei Delphi 6 gibt es die 'angebliche' Fehlerbehandlung noch nicht ;) |
AW: FMX - DX10 - Falsche Wochennummer im TCalendar
Zitat:
|
AW: FMX - DX10 - Falsche Wochennummer im TCalendar
Entschuldigt, aber ich glaube ihr sucht falsch.
Zitat:
![]() Je nach Sichtweise ist das also nicht unbedingt falsch. Gruß K-H |
AW: FMX - DX10 - Falsche Wochennummer im TCalendar
Nein, wir suchen nicht falsch, denn ab Februar wird die Wochennummer wieder so angezeigt wie die VCL Komponente das macht.
Die FMX-Variante ist grundsätzlich falsch implementiert. |
AW: FMX - DX10 - Falsche Wochennummer im TCalendar
Super, erst mal Danke für die Ausweisung der Stelle.
Allerdings reicht es leider nicht, die 3 Zeilen zu löschen, wie von Dir auf QC vorgeschlagen, denn dann zählt die Woche mit 54,55 Woche in Januar 2016 weiter (entscheidend ist die Zeichenroutine, die da unten weiter geht). Das ist mein aktueller Stand eines Workarounds (muss jetzt runter, haben Besuch), scheint zu funktionieren:
Delphi-Quellcode:
Wird erforderlich, um Umbrüche der Wochennummern im Dez/Januar richtig auszugeben.
procedure TStyledCalendar.FillWeeksNumbers;
var I: Integer; CaptionControl: ICaption; FirstWeekOfMonth: Byte; WeekCorrection, MNr: Integer; begin if FWeeks = nil then Exit; FWeeks.Visible := Model.WeekNumbers; // WeekOfTheYear doesn't consider a current Locale. So for 01.01.2017 returns 52. if ((MonthOf(FDateTime) = MonthJanuary)) then begin if (Weekoftheyear (FDateTime) <> 53) then begin FirstWeekOfMonth := WeekOfTheYear(RecodeDay (FDateTime, 1)); end else begin FirstWeekOfMonth := 1; end; end else begin FirstWeekOfMonth := WeekOfTheYear(RecodeDay (FDateTime,1)); end; // First week in FDay may be a last week of previous month. So we need to keep offset for correct counting of weeks. WeekCorrection := (DefineItemIndexOfFirstDayInCurrentMonth - 1) div 7; for I := 0 to FWeeks.ControlsCount - 1 do if Supports(FWeeks.Controls[I], ICaption, CaptionControl) then begin MNr := FirstWeekOfMonth + I - WeekCorrection; // Year 2015 has 53 Weeks; If Drawing parts of January in DEC-Calendar, start again with "1" in drawing if MNr > 53 then begin FirstWeekOfMonth := 0; MNr := 1; end; // eg. Dez. 2016 has 52 Weeks, so start after that again with "1" in drawing if ((MonthOf(FDateTime) = MonthDecember)) then begin if (MNr = 53) and (WeeksInAYear (YearOf (FDateTime)) =52) then begin FirstWeekOfMonth := 0; MNr := 1; end; end; // No 53.week in second week-Row in January possible if ((MonthOf(FDateTime) = MonthJanuary)) then begin if (MNr = 53) and (I = 1) then begin FirstWeekOfMonth := 0; MNr := 1; end; end; CaptionControl.Text := MNr.ToString; end; end; Edit: Den letzten IF-Block habe ich gerade (22:10) noch ergänzt. |
AW: FMX - DX10 - Falsche Wochennummer im TCalendar
Ähm, dieser Workaround ist noch schlimmer als der Bug im Original-Code.
Diese Änderungen reichen (einfaches Auskommentieren)
Delphi-Quellcode:
// WeekOfTheYear doesn't consider a current Locale. So for 01.01.2017 returns 52.
// if MonthOf(FDateTime) = MonthJanuary then // FirstWeekOfMonth := 1 // else FirstWeekOfMonth := WeekOfTheYear(RecodeDay(FDateTime, 1)); |
AW: FMX - DX10 - Falsche Wochennummer im TCalendar
Liste der Anhänge anzeigen (Anzahl: 3)
Also noch mal, Dein Vorschlag korrigiert zwar die falsche Berechnung an dieser Stelle, aber nicht die Ausgabe der Wochennummern insgesamt für den Kalender.
Deine "Korrektur" bringt u.a. die in den anliegenden Screenshots ersichtlichen fehlerhaften Ausgaben als Ergebnis (fehlerhafte Wochennummern in gelb). Ich gebe ja gerne zu, dass in der halben Stunde Zeit, die ich gerade hatte, der Workaround sicher nicht optimal geschrieben ist, sieht aber nach kurzen Tests (Vergleich einiger Jahre mit einem richtigen Kalender) vom Ergebnis erst mal ganz gut aus. Für alternative (schönere Lösungen) bin ich aber immer gerne zu haben.:wink: Davon mal abgesehen sollte der WA aber schnell von EMBA kommen, ist hier ja nicht unsere Aufgabe, deren Arbeit zu machen. |
AW: FMX - DX10 - Falsche Wochennummer im TCalendar
Nun ja, es ist eigentlich kein Hexenwerk, sondern nur logisches Vorgehen.
Delphi-Quellcode:
Sorry for being short :mrgreen:
procedure TStyledCalendar.FillWeeksNumbers;
var I: Integer; CaptionControl: ICaption; LMonday : TDate; begin if FWeeks = nil then Exit; FWeeks.Visible := Model.WeekNumbers; // Vom Monatsanfang den Wochenanfang ermitteln LMonday := StartOfTheWeek( StartOfTheMonth( FDateTime ) ); // für jede Zeile for I := 0 to FWeeks.ControlsCount-1 do begin // die Wochennummer ermitteln if Supports(FWeeks.Controls[I], ICaption, CaptionControl) then CaptionControl.Text := WeekOfTheYear(lMonday).ToString; // Tag eine Woche weiterzählen lMonday := IncWeek( lMonday ); end; end; Für die Überprüfung kann man auch gerne dieses kleine Konsolen-Programm starten (zeigt das Kalandar-Blatt) für den aktuellen Monat an.
Delphi-Quellcode:
Sieht dann so aus
program MonthCalendar;
{$APPTYPE CONSOLE} {$R *.res} uses System.DateUtils, System.SysUtils; procedure OutputMonthCalendarFor( const aDate: TDate; aRows: Integer = 6; aWeekNumbers: Boolean = true ); var lFirstMonday: TDate; lDay : TDate; row, day : Integer; begin lFirstMonday := StartOfTheWeek( StartOfTheMonth( aDate ) ); if aWeekNumbers then write( ' ' ); WriteLn( FormatDateTime( 'mmmm yyyy', aDate ):26 ); WriteLn; lDay := lFirstMonday; if aWeekNumbers then write( ' ' ); for day := 1 to 7 do begin write( FormatDateTime( '" "ddd" "', lDay ) ); lDay := IncDay( lDay, 1 ); end; WriteLn; lDay := lFirstMonday; for row := 0 to aRows - 1 do begin if aWeekNumbers then write( WeekOfTheYear( lDay ):2, ' ' ); for day := 0 to 6 do begin if lDay = DateOf( aDate ) then write( '<', DayOf( lDay ):2, '>' ) else write( ' ', DayOf( lDay ):2, ' ' ); lDay := IncDay( lDay, 1 ); end; WriteLn; end; end; begin try OutputMonthCalendarFor( Date ); except on E: Exception do WriteLn( E.ClassName, ': ', E.Message ); end; ReadLn; end.
Code:
Januar 2016
Mo Di Mi Do Fr Sa So 53 28 29 30 31 1 2 3 1 4 5 < 6> 7 8 9 10 2 11 12 13 14 15 16 17 3 18 19 20 21 22 23 24 4 25 26 27 28 29 30 31 5 1 2 3 4 5 6 7 |
AW: FMX - DX10 - Falsche Wochennummer im TCalendar
Ach, jetzt weiß ich, was Du meinst. Der erste Teil hatte noch die überflüssigen Überreste, bevor ich merkte, dass es für die Ausgabe auf weitere Anpassungen danach ankommt.
Da oben reicht also tatsächlich die eine Zeile. Deine jetzt angebotene Lösung sieht ja sehr galant aus. Werde ich gleich mal testen.:thumb: |
AW: FMX - DX10 - Falsche Wochennummer im TCalendar
Liste der Anhänge anzeigen (Anzahl: 3)
OK, Deine Variante hat das gleiche Ergebnis und berücksichtigt zudem noch die lokale Einstellung des Wochenbeginns, also nehme ich gerne Deine Lösung.
Danke! Wie machst Du das immer nur in so kurzer Zeit? Kleine interessante Sache noch: Deine und meine Lösung geben für Mo, 31. Dezember 2018, die Woche 1 aus, der eigene APPLE-MAC-Kalender gibt auch Woche 1 aus. Outlook 2016 zeigt den 31. Dezember 2018 auch als erste Woche des Jahres (2019) an. Putzig. Der VCL-Kalender gibt Woche 53 aus (ebenfalls mit Wochenanfang LocaleDefault). |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:06 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