Jak z podanej daty odliczyć dzień tygodnia

scott91

<font name="Verdana"><font size="3"><font color="green">Jak z podanej daty odliczyć dzień tygodnia</span></span></span>

Jest to mój pierwszy gotowiec, a ja jestem początkujący więc proszę byście mnie nie zasztyletowali
Wiec tak przedstawię kodzik który może przydać się początkującym.
Jak w tytule zaznaczyłem napisze procedurę obliczającą z podanej daty dzień.
Ale zanim zacznę przydało by się słowo objaśnienia:

<font name="Verdana"><font size="2"><font color="green">Jak to obliczyć</span></span></span>

No wiec załóżmy że obliczymy dzień tygodnia daty 21.12.2012 (Ma być niby Koniec świata :-P) 1.Wiec tak musimy najpierw obliczyć liczbę lat przestępnych od początku naszej ery do roku 2012. Robimy to w następujący sposób nasz podany rok dzielimy przez 4: 2012 : 4 = 503 2.W kalendarzu gregoriańskim musimy odjąć 13 dni: 503 - 13 = 490 3.Następnie musimy obliczyć ile upłynie dni od 1 Stycznia do 21 Grudnia: Styczeń(31) + Luty(28) + Marzec(31) + Kwiecień(30) + Maj(31) + Czerwiec(30) + Lipiec(31) + Sierpień (31) + Wrzesień(30) + Październik(31) + Listopad(30) + Grudzień(20) = 354

<font color="red">Uwaga!
W drugim miesiącu (Luty) musi być 28 dni bo obliczyliśmy już rok przestępne</span>
4.Teraz musimy sumować nasze wyniki:
2012 + 490 + 354 = 2856
5.I na koniec musimy podzielić nasz wynik przez 7 by uzyskać resztę tego wyniku:
2856 : 7 = 408.0

<font color="red">Uwaga!
Akurat w tym wyniku nie ma reszty lecz dobrze się składa bo wytłumaczę ważną rzecz:
Gdy niema reszty (0) to uznajemy, że jest to 7 więc 21.12.2012 wypadnie w Piątek
1 2 3 4 5 6 7
Sobota Niedziela Poniedziałek Wtorek Środa Czwartek Piątek</span>

<font name="Verdana"><font size="2"><font color="green">A teras kodzik! :-)</span></span></span>

Na formę wrzucamy 4 komponenty 3 edit i 1 button. Klikany 2 razy na formę i wpisujemy taki kodzik: ```delphi procedure TForm1.FormCreate(Sender: TObject); var data: string; dmr: TStringList; begin data:=datetostr(date); //Pobieramy date dmr:=TStringList.Create; dmr.Delimiter:='-'; dmr.DelimitedText := data; //Dzielimy ją na dzień miesiąc i rok edit1.Text:=dmr.Strings[2]; //Dzień edit2.Text:=dmr.Strings[1]; //Miesiąc edit3.Text:=dmr.Strings[0]; //Rok dmr.Free; end; ``` Teraz klikamy 2 razy na Button i wpisujemy taki kodzik: ```delphi procedure TForm1.Button1Click(Sender: TObject); const dni_miesiecy : array[1..12] of integer = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); dni_tygodnia : array[1..7] of string = (('Sobota'), ('Niedziela'), ('Poniedziałek'), ('Wtorek'), ('Środa'), ('Czwartek'), ('Piątek')); var rok, dni, i, suma: integer; begin dni:= 0; rok:= strtoint(edit3.Text) div 4 - 13; //Obliczamy liczbę lat przestępnych i odejmujemy 13 (Punkt 1 i 2) if (strtoint(edit2.Text)> 1) then //Jeżeli jest styczeń to nie wykonuje pętli (Punkt 3) begin for i:= 1 to strtoint(edit2.Text) - 1 do begin dni:= dni + dni_miesiecy[i]; //Dodaje miesiące bez miesiąca który obliczamy end; dni:= dni + strtoint(edit1.Text) - 1;//Odejmuje jeden dzień i dodaje do reszty end else begin dni:= strtoint(edit1.Text) - 1; //Jeżeli jest styczeń to odejmuje jeden dzień i zapisuje do zmiennej end; //Koniec punktu 3 suma:= strtoint(edit3.Text) + rok + dni; //Sumuje wyniki (punkt 4) suma:= suma mod 7; //Pobiera resztę z dzielenia if(suma = 0) then suma := 7; //Jeżeli niema reszty ustawia 7 form1.Caption:= dni_tygodnia[suma]; //No i wyświetlamy Dzień tygodnia end; ```

To by było na tyle :-) Jak wspominałem jest to mój pierwszy gotowiec!

7 komentarzy

Czy ktoś Cię zasztyletował? Ja tu widzę konstruktywną krytykę. Nie najechaliśmy na Ciebie tylko na Twój algorytm. Wyciągnij wnioski i popraw artykuł. IHMO zasztyletowałem Twój kod.

Prosiłem byście mnie nie zasztyletowali, jestem początkujący a kodzik z głowy brałem wstyd sie przyznać ale niewiedziałem, że mój kod można tak skrócić. Ale dziękuje za szczere komentarze bo chciałem usłyszeć od innych co myślą o moim kodzie. Pozdrawiam

Racja, zapomniałem, że US ma totalnie wszystko nieco inaczej od reszty świata. Masakra z nimi.

Trzeba przyznać, że Scott91 zaistniał na 4p.

Dla mnie każdy sposób dobry, byle skuteczny.
Przykład innego sposobu na DoW: http://www.algorytm.org/index.php?option=com_content&task=view&id=227&Itemid=28

@Oleksy_Adam pkt. 6: Jest pewna nieścisłość w array'u. Kod z help'a Delphi'ego podaje:

procedure TForm1.Button1Click(Sender: TObject);

var
  ADate: TDateTime;
  days: array[1..7] of string;
begin
  days[1] := 'Sunday';
  days[2] := 'Monday';
  days[3] := 'Tuesday';
  days[4] := 'Wednesday';
  days[5] := 'Thursday';
  days[6] := 'Friday';
  days[7] := 'Saturday';
  ADate := StrToDate(Edit1.Text);
  ShowMessage(Edit1.Text + ' is a ' + days[DayOfWeek(ADate)];
end;

Sądzę, że nie trzeba nic więcej dodawać.

Pozdrawiam
ME

Oleksy_Adam: Hehehe.. brutalna prawda :P

@Oleksy_Adam: Porządne zestawienie, może warto byłoby wydzielić to do osobnego artykułu? :>

1). Datę przechowuje się jako TDateTime.
2). Jest gotowa funkcja DayOfWeek().
3). Do rozpakowania daty na składowe służy EncodeDate().
4). Zawiłość kodu i ilość StrToInt() jest porażająca.
5). Jak już musisz pokazać algorytm obliczania to wklej ten:

Pascal\Delphi:

FUNCTION dtyg(d, m, r: integer): integer;
VAR
  w: integer;
BEGIN
  IF m>2 THEN m := m-2 ELSE
  BEGIN
    m := m+10;
    r := r-1;
  END;
  w := r DIV 100;
  r := r MOD 100;
  dtyg := (d + (13*m-1) DIV 5 + r  + r DIV 4 + w DIV 4 + 5*w) MOD 7;
END;

C\C++\C#

int dtyg(int d, int m, int r)
{
   int w;
   if (m > 2)
      m -= 2;
   else
   {
      m += 10;
      r--;
   }
   w = r/100;
   r %= 100;
   return (d + (13*m-1)/5 + r + r/4 + w/4 + 5*w) % 7;
}

VB\VBA

Public Function dtyg(d As Integer, m As Integer, r As Integer)
Dim w As Integer

If m > 2 Then
  m = m - 2
Else
  m = m + 10
  r = r - 1
End If
w = r \ 100
r = r Mod 100

dtyg = (d + (13 * m - 1) \ 5 + r + r \ 4 + w \ 4 + 5 * w) Mod 7
End Function

6). Skrócona wersja Twojego kodu

const
  Dow :array[1..7] of string[20] = ('N', 'PN', 'WT', 'SR', 'CZ', 'PT', 'S');

Result := Dow[DayOfWeek(Now())];

7). Na forum powinien być zakaz uczenia brzydkich kodów.