Interval.cz
Calendar control a v²poΦet data Velikonoc v ASP.NET

Calendar control je vestav∞n² webov² ovlßdacφ prvek v ASP.NET, jeho₧ prost°ednictvφm lze pracovat s kalendß°em. V ukßzce jej vyu₧ijeme jako ukazatele data VelkΘ noci v danΘm roce, kterΘ se nauΦφme vypoΦφtat.

Nejprve k ovlßdacφmu prvku - kalendß° musφ b²t vlo₧en ve formulß°i, nem∙₧e b²t ve strßnce samostatn∞, do strßnky jej proto vklßdßme nßsledovn∞:

<form runat="server">
  <asp:Calendar id="Calendar1" runat="server" />
</form>

Tento kalendß° mß opravdu hodn∞ nastaviteln²ch vlastnostφ, kterΘ jsou p°φstupnΘ pomocφ °ady atribut∙. Atributy (vlastnosti) jsou popsßny na strßnkßch MSDN, vzhledem k jejich mno₧stvφ se vßm ale urΦit∞ bude prvek nastavovat lΘpe v n∞jakΘm vizußlnφm prost°edφ, jako je t°eba WebMatrix nebo Visual Studio.

Primßrn∞ slou₧φ tento ovlßdacφ prvek pro pohodlnΘ zadßvßnφ data u₧ivatelem, dovede vÜak v zobrazenΘm kalendß°i vyznaΦit i aktußlnφ datum a takΘ ukßzat zadanΘ datum. Prßv∞ toho vyu₧ijeme v naÜφ ukßzce - vypoΦφtanΘ datum Velikonoc nastavφme do atributu SelectedDate, Φφm₧ se kalendß° "p°epne" na dan² rok a m∞sφc a zvlßÜ¥ vyznaΦφ zvolen² den. Aby bylo zvolenΘ datum takΘ vid∞t, je pot°eba jeÜt∞ pomocφ atributu VisibleDate kalendß° "narolovat" do pozice m∞sφce, ve kterΘm se nßÜ den nachßzφ. Jinak by sice datum bylo zvoleno, ale nebylo by vid∞t, kalendß° toti₧ bez urΦenφ VisibleDate ukazuje v₧dy aktußlnφ m∞sφc.

Proto₧e chceme kalendß° vyu₧φt jen jako indikßtor, zakß₧eme mo₧nost vybφrat datum (v tΘto aplikaci by to bylo pro u₧ivatele matoucφ, datum z kalendß°e zde nijak nezpracovßvßme) nastavenφm atributu SelectionMode na hodnotu none. Celß naÜe aplikace je tak i ukßzkou prßce s webov²m formulß°em - od ov∞°enφ, zda jde o prvnφ zobrazenφ strßnky, zpracovßnφ udßlostφ, oÜet°enφ v²jimek a₧ po vyu₧itφ tzv. VIEWSTATE pro udr₧ovßnφ stavu aplikace. ProhlΘdn∞te si ukßzku (zdrojovΘ soubory).

K v²poΦtu data Velikonoc je zapot°ebφ znßt nejprve trochu historie. Na zaΦßtku naÜeho letopoΦtu byl pr² uk°i₧ovßn Je₧φÜ Kristus a v noci ze soboty na ned∞li se odehrßl zßzrak zmrtv²chvstßnφ. Proto se ta noc naz²vß Velkou nocφ. O tom, co se tehdy odehrßlo, se zachovalo velmi mßlo historick²ch pramen∙ a ₧ßdn² z nich neudßvß p°esnΘ datum. Tradice klade ned∞li po "VelkΘ noci" na prvnφ jarnφ ·pln∞k, kdy slavφ sv∙j velk² svßtek Pesach (p°echod Rud²m mo°em) i ÄidΘ. Datum Velikonoc tedy p°ipadß na ned∞li po prvnφm jarnφm ·pl≥ku.

Jak vidφte, nßÜ algoritmus musφ v∞d∞t, kdy zaΦφnß jaro a kdy je ·pln∞k. Algoritm∙ pro v²poΦet existuje n∞kolik. Pro ukßzku jsem pou₧il tzv. algorythm of Oudin, kter² staΦφ jen upravit do jazyka C# ASP.NET aplikace.

C = Y/100
N = Y - 19*(Y/19)
K = (C - 17)/25
I = C - C/4 - (C - K)/3 + 19*N + 15
I = I - 30*(I/30)
I = I - (I/28)*(1 - (I/28)*(29/(I + 1))*((21 - N)/11))
J = Y + Y/4 + I + 2 - C + C/4
J = J - 7*(J/7)
L = I - J
M = 3 + (L + 40)/44
D = L + 28 - 31*(M/4)

Pokud se podφvßte na funkΦnφ algoritmus, vidφte, ₧e jej p°ipravoval erudovan² v∞dec, kter² precizn∞ ovlßdal matematiku, ale chyb∞l mu programßtorsk² operßtor modulo - zbytek po d∞lenφ. C# samoz°ejm∞ tento operßtor mß takΘ (%), a tak by byla Ükoda jej nepou₧φt pro zjednoduÜenφ v²poΦtu. Metoda, kterß pro zadan² rok vypoΦφtß datum Velikonoc, bude vypadat takto:

System.DateTime EasterDay(int EYear)
{
  int G,C,H,i,j,L,EMonth,EDay;
  G = EYear % 19;
  C = EYear / 100;
  H = ((C - (C / 4) - ((8 * C + 13) / 25) + (19 * G) + 15) % 30);
  i = H - ((H / 28) * (1 - (H / 28) * (29 / (H + 1)) * ((21 - G) / 11)));
  j = ((EYear + (EYear / 4) + i + 2 - C + (C / 4)) % 7);
  L = i - j;
  EMonth = 3 + ((L + 40) / 44);
  EDay = L + 28 - (31 * (EMonth / 4));
  System.DateTime EDateTime = new System.DateTime(EYear, EMonth, EDay,0,0,0,0);
  return EDateTime;
}

Do strßnky s formulß°em pak u₧ jen staΦφ p°idat textovΘ pole pro zadßvßnφ roku a tlaΦφtko pro odeslßnφ. Ve skriptu p°evezmeme od u₧ivatele rok, pokusφme se zjistit datum velikonoc a zobrazφme v²slednΘ datum, nejen jako text, ale takΘ nßzorn∞ pomocφ prvku kalendß°e. Pokud bude rok zadßn nekorektn∞, zachytφme vzniklou v²jimku, vypφÜeme zprßvu o chyb∞ a zneviditelnφme prvek kalendß°e - ten se pak ve strßnce v∙bec neobjevφ (nebude renderovßn).

<%@ Page Language="C#" %>
<script language="C#" runat="server">

System.DateTime EasterDay(int EYear)
{ // implementace algoritmu Oudina do metody v C#
  int G,C,H,i,j,L,EMonth,EDay;
  G = EYear % 19; // pou₧itφ operßtoru modulo pro zφskßnφ zbytku po d∞lenφ
  C = EYear / 100;
  H = ((C - (C / 4) - ((8 * C + 13) / 25) + (19 * G) + 15) % 30);
  i = H - ((H / 28) * (1 - (H / 28) * (29 / (H + 1)) * ((21 - G) / 11)));
  j = ((EYear + (EYear / 4) + i + 2 - C + (C / 4)) % 7);
  L = i - j;
  EMonth = 3 + ((L + 40) / 44);
  EDay = L + 28 - (31 * (EMonth / 4));
  System.DateTime EDateTime = new System.DateTime(EYear, EMonth, EDay,0,0,0,0); // vytvo°enφ instance vypoΦφtanΘho data velikonoc
  return EDateTime; // p°edat jako v²sledek metody
}

DateTime EasterDate; // pomocnß prom∞nnß pro prßci s datem velikonoc

void Page_Load(object sender, System.EventArgs e)
{ // p°i naΦφtßnφ strßnky provΘst
  if (!IsPostBack)
  { // pokud nenφ webov² formulß° jeÜt∞ odeslßn (jde o prvnφ zobrazenφ strßnky)
    txtYear.Text=System.DateTime.Today.Year.ToString(); // nastavit pole pro zadßnφ roku na souΦasn² rok
  }
  try
  { // pokusit se
    EasterDate = EasterDay(Convert.ToInt32(txtYear.Text)); // vypoΦφtet datum velikonoc
    lblEasterDay.Text="Velkß noc je v nedìli " + EasterDate.ToShortDateString()+ "."; // vypsat datum velikonoc p°evedenΘ na ShortDate (bez hodin,minut, sekund)
    Calendar1.SelectedDate=EasterDate; // nastavit v kalendß°i datum velikonoc
    Calendar1.VisibleDate=Calendar1.SelectedDate; // p°epnout kalendß° tak, aby zobrazoval m∞sφc, v kterΘm je zvolenΘ datum
    Calendar1.Visible=true; // zviditelnit kalendß°
  }
  catch
  { // doÜlo k v²jimce
    lblEasterDay.Text="Chybn∞ zadan² rok!"; // nastavit chybovou zprßvu
    Calendar1.Visible=false; // kalendß° nebude zobrazen
  }
}
</script>
<html>
<head>
<title>Web Control Kalendß° a datum velikonoc</title>
</head>
<body>
<form runat="server">
  Datum velikonoc v roce <asp:TextBox AutoPostBack="true" id="txtYear" size="4" maxlength="4" runat="server" />
  <asp:Button runat="server" Text="?" />
  <br /><br />
  <strong><asp:Label id="lblEasterDay" runat="server" /></strong>
  <br /><br />
  <asp:Calendar id="Calendar1" Visible="false" runat="server" SelectionMode="None" BackColor="White" Width="200px" DayNameFormat="FirstLetter" ForeColor="Black" Height="180px" Font-Size="8pt" Font-Names="Verdana" BorderColor="#999999" CellPadding="4">
  <TodayDayStyle forecolor="Black" backcolor="#CCCCCC" />
  <SelectorStyle backcolor="#CCCCCC"></SelectorStyle>
  <NextPrevStyle verticalalign="Bottom" />
  <DayHeaderStyle font-size="7pt" font-bold="True" backcolor="#CCCCCC" />
  <SelectedDayStyle font-bold="True" forecolor="White" backcolor="#666666" />
  <TitleStyle font-bold="True" bordercolor="Black" backcolor="#999999" />
  <WeekendDayStyle backcolor="#FFFFCC" />
  <OtherMonthDayStyle forecolor="#808080" />
  </asp:Calendar>
</form>
</body>
</html> 

V tomto webovΘm formulß°i vidφme textovΘ pole, mß nastaveno AutoPostBack="true", co₧ znamenß, ₧e k odeslßnφ formulß°e (a tedy vystavenφ nov²ch hodnot) dojde automaticky p°i zm∞n∞ textu v tomto poli stejn∞ jako p°i stisku klßvesy Enter (pokud se podφvßte do zdroje ukßzky, vidφte, ₧e systΘm ASP.NET vygeneroval Φßst JavaScriptu, kter² toto zajistφ). Dßle je obsa₧eno odesφlacφ tlaΦφtko, kterΘ nenφ svßzßno s ₧ßdnou udßlostφ, slou₧φ k prostΘmu odeslßnφ formulß°e. Pomocφ nßv∞Ütφ (label) vypisujeme text s datem Velikonoc nebo zprßvu o chyb∞.

Poslednφm prvkem strßnky je ji₧ zmφn∞n² kalendß°, kde vidφte i nastavenφ n∞kter²ch atribut∙ a parametr∙ (zejmΘna v²Üe zmφn∞n² zßkaz v²b∞ru data SelectionMode="none"), kterΘ slou₧φ pro nastavenφ vzhledu a stylu kalendß°e ve strßnce.

Pokud se vßm aplikace lφbφ, jist∞ zvlßdnete upravit obslu₧n² skript tak, aby bylo mo₧no vybφrat rok i pomocφ kalendß°e. Uvedenou metodu EasterDay() je vhodnΘ zakomponovat do n∞jakΘ vlastnφ t°φdy nebo namespace, zde slou₧φ hlavn∞ pro demonstraci mo₧nostφ kalendß°e, proto je vepsßna rovnou do Φßsti skriptu strßnky.



Pavel R∙₧iΦka (21.4. 2003)
odborn² redaktor Interval.cz

Redakce Interval.cz |  Inzerce na Interval.cz |  Hledßme novΘ autory ISSN 1212-8651 
 ⌐ Zoner software, s.r.o., vÜechna prßva vyhrazena, tento server dodr₧uje prßvnφ p°edpisy o ochran∞ osobnφch ·daj∙.