Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Day of First Month (https://www.delphipraxis.net/194777-day-first-month.html)

danten 3. Jan 2018 19:02

Day of First Month
 
Hello,
what is the first Monday last month?

result => '4.12.2017'
result => '6.11.2017'
result => '2.10.2017'
....

Thank you

Michael II 3. Jan 2018 22:32

AW: Day of First Month
 
Delphi-Quellcode:
function FirstMondayOfMonth( year, month : integer ):TDateTime;
var dof, firstday : integer;
begin
    firstday := trunc(EncodeDate( year, month, 1 ));
    dof := DayOfWeek( firstday ); // dof : 1= Sunday 2=Monday 3=Tuesday ...
    if dof <= 2 then Result := firstday + 2-dof
    else Result := firstday + 9-dof;
end;

himitsu 4. Jan 2018 01:50

AW: Day of First Month
 
Wozu Trunc?
Für das bessere Codeverständnis würde ich eher zu Delphi-Referenz durchsuchenDateOf raten,
aber wozu überhaupt? In EncodeDate kann es keinen Uhrzeit-Anteil geben.

@Michael: Kennst du schon den Unterschied zwischen Delphi-Referenz durchsuchenSysUtils.DayOfWeek und Delphi-Referenz durchsuchenDateUtils.DayOfTheWeek?
Da dort der Wochenanfang dem Wunschtag dieser Funktion entspricht, entfällt somit das ELSE.

Delphi-Quellcode:
function FirstMondayOfMonth(Year, Month: Integer): TDateTime;
var
  Dow: Integer;
begin
  Result := EncodeDate(Year, Month, 1);
  Dow := DayOfTheWeek(Result);
  if Dow <> DayMonday then
    Result := IncDay(Result, DaysPerWeek + 1 - Dow);
end;

function FirstMondayOfMonth(Date: TDateTime): TDateTime;
var
  Dow: Integer;
begin
  Result := RecodeDay(Date, 1);
  Dow := DayOfTheWeek(Result);
  if Dow <> DayMonday then
    Result := IncDay(Result, DaysPerWeek + 1 - Dow);
end;



function FirstMondayOfMonth(Date: TDateTime): TDateTime;
var
  Dow: Integer;
begin
  Date := RecodeDay(DateOf(Date), 1);
  Result := StartOfTheWeek(Date);
  if Result < Date then
    Result := IncWeek(Result); // Result := IncDay(Result, DaysPerWeek);
end;
DaysPerWeek + 1 wird vom Compiler zu 8 optimiert, aber so ist verständlicher was das soll,
und eine Konstante für Montag, statt dem komischen 2, vereinfacht auch das Leben und schon kann dein Kommentar weg, was welche Zahl bedeuten soll. (wobei Standardsachen aus der OH nicht unbedingt in Kommentare gehören)

danten 4. Jan 2018 08:30

AW: Day of First Month
 
Zitat:

Zitat von himitsu (Beitrag 1390297)
Wozu Trunc?
Für das bessere Codeverständnis würde ich eher zu Delphi-Referenz durchsuchenDateOf raten,
aber wozu überhaupt? In EncodeDate kann es keinen Uhrzeit-Anteil geben.

Hello,
I have already understood.
Thank you all for help.

Michael II 4. Jan 2018 13:19

AW: Day of First Month
 
Zitat:

Zitat von himitsu (Beitrag 1390297)
Wozu Trunc?
Für das bessere Codeverständnis würde ich eher zu Delphi-Referenz durchsuchenDateOf raten,
aber wozu überhaupt? In EncodeDate kann es keinen Uhrzeit-Anteil geben.

@Michael: Kennst du schon den Unterschied zwischen Delphi-Referenz durchsuchenSysUtils.DayOfWeek und Delphi-Referenz durchsuchenDateUtils.DayOfTheWeek?

Hallo himitsu

Danke für deine wertvollen Tipps. Dein Code sieht in der Tat viel übersichtlicher aus - und ich gebe zu: Wenn jemand von aussen deinen und meinen sieht, dann weiss man bei meinem überhaupt nicht was Sache ist - bei deinem erkennt man aber ales sofort.

Den Unterschied zwischen DayOfWeek und DayOfTheWeek kenne ich. Aber besten Dank!

trunc hatte ich verwendet, weil ich das Zwischenresultat nicht als TDateTime, sondern als Integer gespeichert hatte. [ Ich mach das relativ oft, wenn ich mit Datumswerten rechne und beim Debuggen lieber den Integerwert als das Datum sehe. ]

Einzig bei "Kommentaren" bin ich nicht gleicher Meinung. Ich schreib diese hin wo und wie auch immer ich will.

Es ist schon toll, wie man von dir immer wieder lernen kann. Ich hoffe du inspirierst auch im neuen Jahr viele junge Anfänger mit deiner Energie und deinen immer sinnvollen Belehrungen. Mich hast du auf jeden Fall als grosser Fan.

Besten Dank aus der Schweiz nach Deutschland.

Gruss
Michael

himitsu 4. Jan 2018 13:57

AW: Day of First Month
 
Mist stimmt, der blöde Integer, dann ist Trunc ja doch richtig. :wall::thumb:

Na gut, wichtig ist nur, dass man bei Kommentaren nur "Wichtiges" hinschreibt.
Sonst kann es schnell passieren, dass die wichtigen Dinge in einer Masse von Unwichtigem / weniger Wichtigem verschwinden.
Und da sind wir uns doch bestimmt einig, dass das nicht sonderlich glücklich wäre. :D

Bei den Datumsfunktionen gibt es schon blöde Sachen.
Früher gab es im Delphi mal eine Day-of-Week-Funktion, die von 0-6 ging.
Aber da hatten die Wochentage wenigstens die selben Werte. (Sonntag 0 oder 7 und Mo-Sa = 1..6)
Hier muß man nun aufpassen ob DateUtils oder SysUtils, und dann ist 1 = Mo oder So. :wall:

Das macht vielleicht einen Spaß, wenn man manchmal überlegen muß ob 0-6 oder 1-7 oder das andere 1-7 und ob Mo oder So der Wochenanfang ist.
Bei ..., ...A... und ...The... muß man auch erstmal das Muster erkennen. (DayOfWeek und DayOfTheWeek oder StartOfTheWeek und StartOfAWeek)

kwhk 7. Jan 2018 10:40

AW: Day of First Month
 
Das liegt evtl. auch daran, dass es länderabhängige Definitionen für die Woche gibt.
In den USA beginnt die Woche am Sonntag, der Mittwoch ist tatsächlich genau in der Mitte der Woche ( 3 Tage vorher und 3 Tage danach). In D wurde der Wochenbeginn auf den Montag gelegt, der So gehört nun zum Wochenende.
https://de.wikipedia.org/wiki/Woche

Ähnliche Unterschiede gibt es in der Definition der Nummer der Woche.
In D ist Woche 1 immer die, wo der erste Werktag liegt, in den USA ist es die Woche, in der der 1. Januar liegt.
Das gibt Probleme, wenn man z.B. die Lieferwoche, statt eine konkreten Datums, mit einem Lieferanten aus den USA vereinbaren will.

Aviator 7. Jan 2018 13:38

AW: Day of First Month
 
Zitat:

Zitat von kwhk (Beitrag 1390412)
In D ist Woche 1 immer die, wo der erste Werktag liegt, in den USA ist es die Woche, in der der 1. Januar liegt.

Das stimmt so leider nicht. In Deutschland ist die erste KW des Jahres immer die Woche, in der der erste Donnerstag liegt.

In anderen Ländern sieht es, wie du schon sagtest, unter Umständen anders aus.

Zitat:

Zitat von Wikipedia
Kalenderwoche
Das Kalenderjahr umfasst mindestens 52 Wochen, die v. a. im Geschäftsleben als Kalenderwochen (KW) durchnummeriert werden, wobei es für die Wochen-Nummerierung verschiedene Definitionen gibt. Je nach angewandter Regel kann die erste Woche eines Jahres unterschiedlich festgelegt sein:
  • Im deutschsprachigen Raum, gemäß Normen der ISO, DIN, ÖNORM und SN: jene Woche, die den ersten Donnerstag des Jahres enthält (ISO 8601, früher DIN 1355-1). Äquivalent hierzu sind, da ISO 8601 den Montag als ersten Tag der Woche definiert, die folgenden Definitionen:
    • jene Woche, die den 4. Januar enthält
    • jene Woche, die den 1. Januar enthält, falls dieser ein Montag, Dienstag, Mittwoch oder Donnerstag ist, sonst die darauf folgende Woche
    • die erste Woche, von der mehr Tage (mindestens vier) auf das neue Jahr fallen als auf das alte Jahr
  • In den USA: jene Woche, in die der 1. Januar fällt
  • Selten: die erste vollständige Woche des Jahres


samso 7. Jan 2018 13:45

AW: Day of First Month
 
Zitat:

Zitat von kwhk (Beitrag 1390412)
In D ist Woche 1 immer die, wo der erste Werktag liegt.

Och mano, es steht doch so schön in dem von Dir zitierten Artikel bei Wikipedia...
Zitat:

Die Kalenderwoche 1 eines Jahres ist diejenige, die den ersten Donnerstag enthält.
Beispiel: 2010

himitsu 8. Jan 2018 10:09

AW: Day of First Month
 
Zitat:

Die Kalenderwoche 1 eines Jahres ist diejenige, die den ersten Donnerstag enthält.
Ist eigentlich ganz leicht zu erklären:
* die Woche beginnt mit dem Montag
* und die Woche gehört zu dem Jahr, in welchem der größte Teil davon liegt

bei 01.01. = Donnerstag -> 3 Tage im Vorjahr und 4 Tage im Nächsten


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:43 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