Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: juhannusaatto, pääsiäinen

Sivun loppuun

manninen [06.12.2014 13:11:18]

#

Minulla on taulukko muotoinen kalenteri, joka menee ylhäältä alaspäin.

Koodissani, $i = Muuttuja jonka arvo kasvaa kierros kierrokselta, tämä arvo viittaa meneillään olevaan päivämäärään.
Koodissani, $o = Muuttuja viittaa soluun, joka luodaan päivämäärien vierelle.

Varsinainen ongelmani, miten lasken päivämäärän joka viittaa pääsiäiseen. Loogista laskentatapaa en sille saa suollettua, joten olisiko jollain antaa ajatusta ja neuvoa laskentakaavasta. Alla olevan esimerkin mukaan lasken juhannuksen ja juhannusaaton. Tästäkin tavasta voi kertoa paremman tyylin, jos mieleen tulee. Testaukseni perusteella, tuon pitäisi mennä oikein, mutta silti.

 // Juhannusaatto
if(($i >= 19 && $i <= 26) && $kuukausi == 6 && (date('N', mktime(0, 0, 0, 6, $i, $vuosi)) == 5))
{
  if($o++ <= 1)
  {

    $background = "background:red; color:white;"; $selite = 'Juhannusaatto';

  }

}

// Juhannuspäivä
if(($i >= 20 && $i <= 26) && $kuukausi == 6 && (date('N', mktime(0, 0, 0, 6, $i, $vuosi)) == 6))
{

  $background = "background:red; color:white;"; $selite = 'Juhannuspäivä';  // Juhannus

}

Grez [06.12.2014 14:19:28]

#

Tuolta löytyy esimerkiksi Gaussin ja Butcherin menetelmät pääsiäisen laskemineen sekä huomautuksia niiden soveltamisesta.

http://fi.wikipedia.org/wiki/Pääsiäisen_laskeminen

Varmaan jommassa kummassa juhannusaatto tai juhannuspäivä kaavassasi on virhe koska molemmissa $i <= 26. Itse laittaisin ehkä niin että toiselle on varsinainen kaava ja toinen riippuu siitä, jolloin mahdolliset virheet tarvitsisi korjata aina vain yhteen paikkaan.

manninen [06.12.2014 18:07:02]

#

Sen verran kaavat eroaa, että toinen katsoo milloin on aikavälille osuva launtai sekä milloin on perjantai. Juhannuspäivä osuu aina perjantaille. Toisin sanoen riittäisi yksi if-lauseke, jonka sisällä tarkistaisin tuon. En kupaakin erikseen, no aina ajattelee paremmin kun muut kyseenalaistavat :)

Kiitos. Tutustunpa tuohon pääsiäisen laskemiseen.

jalski [06.12.2014 19:02:57]

#

manninen kirjoitti:

Tutustunpa tuohon pääsiäisen laskemiseen.

Scientific American, Mar 2001 p82

Pentu [07.12.2014 22:35:28]

#

Kirjoitin joutessani funktion (Gaussin menetelmä) tätä varten.

<?php
 function easter_gauss($year, $arr){
	$a = $year % 19;
	$b = $year % 4;
	$c = $year % 7;
	$d = (19 * $a + 24) % 30;
	$e = (2 * $b + 4 * $c + 6 * $d + 5) % 7;
	$h = 0;		// Oletusarvoisesti pääsiäinen ei ole huhtikuussa

	// Pääsiäinen on maaliskuun (22 + d + e):s päivä.
	$day = 22 + $d + $e;

	// Jos $day on yli 31, pääsiäinen on huhtikuun (d + e - 9):s päivä.
	if($day > 31){
		$h = 1;					// Pääsiäinen on huhtikuussa
		$day = $d + $e - 9;		// Lasketaan päivä

		// Jos $day on 26, pääsiäinen on aina viikkoa aiemmin.
		if($day == 26){
			$day -= 7;
		}
		// samoin jos $day on 25 sekä $d = 28 ja $a yli 10, kuten vuosina 1954 ja 2049.
		elseif($day == 25 && $d=28 && $a>10){
			$day -= 7;
		}
	}

	// Kuukausi
	$m = ($h == 0) ? '3' : '4';

	// Palautetaan merkkijonona
	if($arr == 0)$easter = $day .".". $m;
	// Palautetaan taulukkona
	else{
		$easter["d"] = $day;
		$easter["m"] = $m;
	}
	return $easter;
 }

echo easter_gauss(2015, 0); // Palauttaa 5.4
?>

Edit.

Tai voithan tehdä sen yksinkertaisemminkin...

echo date("j.n", easter_date(2015));

manninen [08.12.2014 00:15:18]

#

Kappas, sehän olikin hankalampaa kuin oletinkaan.

Pentu [08.12.2014 14:12:44]

#

manninen kirjoitti:

Kappas, sehän olikin hankalampaa kuin oletinkaan.

Kun ymmärtää periaatteen, niin sen jälkeen on helpompi lähteä muodostamaan ohjelmaa. Muutaman rivin verran tota funktioo saisi pienennettyä, kun ottaa pois ton string/array -palautus virityksen pois.

Tuo ei vielä kovin monimutkainen ole, ensiksi lasketaan muutama jakojäännös. Tämän jälkeen jos päivä (lasketaan 22+d+e) on enemmän kuin 31, niin päivä (lasketaan d+e-9) on huhtikuun puolella.

Lopuksi tarkastetaan pari ehtoa liittyen huhtikuun 25 ja 26 päiviin...

Butcherin menetelmä on hieman monimutkaisempi, varmaan siihenkin funktion teen, mikäli mielenkiinto riittää :D

jalski [08.12.2014 17:20:59]

#

Pentu kirjoitti:

Butcherin menetelmä on hieman monimutkaisempi, varmaan siihenkin funktion teen, mikäli mielenkiinto riittää :D

Mielestäni tuo on selkeämpi, kun ei tarvita IF-lausekkeita ja jokunen laskutoimitus rittää. Linkittämästäni artikkelista saadaan suoraan kopioitua toimiva REXX-toteutus:

/* easter.rex

 from Scientific American, Mar 2001 p82 */

parse arg vuosi .

if vuosi = '' then
  vuosi = left( date( 'S' ), 4 )

a = vuosi // 19
b = vuosi % 100
c = vuosi // 100
d = b % 4
e = b // 4
g = ( ( 8 * b ) + 13 ) % 25
h = ( ( 19 * a ) + b - d - g + 15 ) // 30
m = ( a + 11 * h ) % 319
j = c % 4
k = c // 4
l = ( ( 2 * e ) + ( 2 * j ) - k - h + m + 32 ) // 7
n = ( h - m + l + 90 ) % 25
p = ( h - m + l + n + 19 ) // 32

kuukausi. = 'VIRHE'
kuukausi.3 = 'maaliskuu'
kuukausi.4 = 'huhtikuu'

say kuukausi.n right(p, 2)',' vuosi

Pentu [08.12.2014 20:04:23]

#

Paitsi että, ilmeisesti olet saekoittanut jakolaskun ja jakojäännöksen? Käänsin PHP:lle nuo laskut, ja vastaukseksi sain -4.-8 (2014).

Tuktittuani linkkiäsi tein oman funktion.

  function easter_butcher($year){
	// 1
	$a = $year % 19;
	// 2
	$b = floor($year / 100);
	$c = $year % 100;
	// 3
	$d = floor($b / 4);
	$e = $b % 4;
	// 4
	$g = floor((8 * $b + 13) / 25);
	// 5
	$h = (19 * $a + $b - $d - $g + 15) % 30;
	// 6
	$m = floor(($a + 11 * $h) / 319);
	// 7
	$j = floor($c / 4);
	$k = $c % 4;
	// 8
	$l =  (2 * $e + 2 * $j - $k - $h + $m + 32) % 7;
	// 9 Kuukausi
	$n = floor(($h - $m + $l + 90) / 25);
	// 10 Päivän nro
	$p = ($h - $m + $l + $n + 19) % 32 ;

	return $p .":". $n;
  }

jalski [08.12.2014 21:21:47]

#

Pentu kirjoitti:

Paitsi että, ilmeisesti olet sekoittanut jakolaskun ja jakojäännöksen?

En ole sekoittanut operaattoreita.

REXX-ohjelmointikielessä:

jakolasku: /
integer jakolasku: %
jakojäännös: //


Jakojäännöshän eroaa useimpien ohjelmointikielten modulo-operaattorista siten, että tulos voi olla negatiivinen.

Aiemmin antamani koodi on täysin toimiva.

Pentu [08.12.2014 21:25:07]

#

Ahaa, okei. Anteeksi tästä perättömästä syytöksestä siis ;) Tota en tiennytkään. Mulla ei tuosta REXXistä ole mitään kokemusta.. Ehkäpä siihenkin voisi tutustua.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta