Newsgroup: it.comp.lang.c
Titolo: Sorgenti x calendario perpetuo?

Salve a tutti , c'è qualcuno che sa dirmi dove posso
trovare sorgenti per un calendario perpetuo?
Grazie a tutti
Ciao


int dayofweek(int y, int m, int d)      /* 0 = Sunday */
{static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
 y-=m < 3;
 return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}
questa l'ho trovata in un NG vedi se funziona 

E' stato uno dei primi programmi che ho fatto quando ho cominciato a
studiare C (quindi 6 mesi fa... :-)) , però mi pare che funzioni...
ovviamente sarà molto brutto e si può migliorare in più punti ecc..., cmq le
funzioni fondamentali ci sono e si tratta solo di matematica elementare,
quindi te le puoi rigirare un po' come vuoi.
In particolare il prog. fa:
1) richiede un anno (>1900) e un mese
2) conta i giorni che sono passati dal 1/1/1900 al primo giorno del mese che
ti interessa, tenendo conto dei diversi nueri di giorni dei diversi mesi, e
del fatto dei bisestili (la formula che ho usato è: "Sono bisestili gli anni
divisibili per 4, tranne quelli divisibili per 100, che non sono bis.,
tranne gli anni divisibili per 400, che sono bisestili")
(questa è la funzione fondamentale, quella che conta i giorni. Usandola,
puoi calcolare quello che più ti aggrada, da un singolo giorno ad un anno
intero. In pratica, conta i numeri dei giorni, e quindi se poi calcoli il
resto della divisione per 7 sei a cavallo)
3) stampa sullo schermo il mese inquestione, bello ordinato con i nomi dei
giorni.
NOTA: il fatto che l'anno debba essere >=1900 l'ho fatto solo per mia
comodità: il 1° gennaio 1900 era un lunedì, così i conti tornavano tutti per
bene :-)) Ovviamente puoi partire da qualsiasi punto, basta effettuare uno
shift adeguato per i giorni della settimana... in ogni caso, come avrai
notato, questo non è un VERO calendario perpetuo per 2 motivi (AFAIK):
1) I giorni vengono contati con un long int: anche unsigned, non potrai
contare per più di circa 11,76 milioni di anni, dopo ciccia :-))
2) Cmq il calendario si riferisce al calendario odierno, per esempio nel
1400 ce n'era un altro, e nel 100 dc probabilmente c'era ancora quello di
Cesare, e per questi dovrai fare altri conti, un po' più complicati... e poi
il calendario dipende anche da paese a paese, es. la Rivoluzione Russa, o
Rivoluzione d'Ottobre, in realtà in Russia avvenne in novembre, perché erano
indietro col calendario (non vorrei aver detto un'immane cazzata ^___^;;;  )
Per finire, 
http://www.timeanddate.com/calendar/
non c'è codice, ma puoi controllare se quello che hai fatto è giusto!
Pleg
...e quindi, ecco il codice!
/* program calendario perpetuo */
#include <stdio.h>
#include <conio.h>
#define X0 7   /* ascissa da cui partire a visualizzare il calendario*/
#define DILATA_X 6   /* dilatazione sull'asse x per visualizzare il
calendario*/
#define Y0 6   /* ordinata da cui partire a visualizzare il calendario*/
#define Y_GIORNI 4 /* ordinata alla quale visualizzare i nomi dei giorni*/
typedef struct {
 int anno;
 int mese;
 int giorno;
} data;
data inserimento_dati(void);
int conteggio(data, int giorni_mese[]);
int bisestile(int);
void visualizza_calendario(data, unsigned int, int giorni_mese[]);
/* Function Main */
void main()
{
 data d;
 long int numero_giorni=0;
 int giorni_mese[12]={31,28,31,30,31,30,31,31,30,31,30,31};
 d=inserimento_dati();
 numero_giorni=conteggio(d, giorni_mese);
 visualizza_calendario(d, numero_giorni, giorni_mese);
 getch();
}
/* Other Functions */
/* Inserisce i dati e controlla che siano corretti */
data inserimento_dati()
{
 data x;
 int flag;
 do {
  clrscr();
  flag=0;
  printf("Inserire l'anno (>=1900) e il mese: ");
  scanf("%d%d", &x.anno, &x.mese);
  x.giorno=1;
  if ((x.anno<1900)||(x.mese<0)||(x.mese>12)) flag++;
  if (flag) {
   printf("\nI valori immessi sono inaccettabili. Ripetere l'inserimento
dati (premere un tasto per continuare)");
   getch();
  }
 }
 while (flag);
 return x;
}
/* Conta i giorni passati dal 1/1/1900 */
int conteggio(data d, int giorni_mese[12])
{
 int i;
 unsigned int x=0;  /* Numero giorni calcolati da questa funzione */
 for (i=1900;i<d.anno;i++)
 {
  x+=365;
  if (bisestile(i)) x++;
    }
 for (i=1;i<d.mese;i++)
 {
  x+=giorni_mese[i-1];
  if ((i==2)&&bisestile(d.anno)) x++;
 }
 x+=(d.giorno-1);
 return x;
}
/* Calcola se un anno S bisestile o no */
int bisestile(int anno) /* restituisce 0 se non bisestile, 1 se bis. */
{
 int bis=0;
 if (!(anno%4))
 {
  if (!(anno%100))
  {
   if (!(anno%400)) bis=1;
  }
  else
   bis=1;
 }
 return bis;
}
/* Visualizza il calendario del mese
d= data selezionata
x= giorni passati dal 1/1/1900
y= array che contiene i giorni dei mesi */
void visualizza_calendario(data d, unsigned int x, int y[12])
{
 int i, g=y[d.mese-1]; /* g=giorni del mese corrente */
 int shift=x%7; /* calcola che giorno S il primo del mese */
 char nome_giorno[7][4]={"lun","mar","mer","gio","ven","sab","dom"};
 if ((d.mese==2)&&(bisestile(d.anno))) g++;
 for (i=0;i<7;i++) {
  gotoxy(X0+DILATA_X*i,Y_GIORNI);
  printf("%s", nome_giorno[i]);
 }
 for (i=0;i<g;i++) {
  gotoxy(X0+DILATA_X*((i+shift)%7),Y0+(i+shift)/7);
  printf("%d", i+1);
 }
}

 questa l'ho trovata in un NG vedi se funziona
occhio: per le date storiche ci sono da considerare molte altre cose, 
oltre ai diversi periodi in cui il calendario gregoriano venne applicato 
nei vari stati (in russia tutt'ora non si usa)

 void main()
int main(void)	/* oppure */
int main(int argc, char **argv)
Quel tizio che  cerca di insegnarci il  C puo` dire quello  che gli pare
sul void  main, ma lo  standard dice il tipo  di ritorno di  main *deve*
essere un int.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
This message will self distruct in 5 seconds.

'azzo, Kronos... pure in pubblico mi devi mazziare? :-))
Cmq, l'ho premesso prima del mex che era il primo prog che facevo in C, e ho
avvertito del fatto che quello che contava era l'algoritmo, che funziava,
quindi non ho cercato di traviare nessuno... cmq mi inchino ancora una volta
alla saggezza.
Pleg

 indietro col calendario (non vorrei aver detto un'immane cazzata
___^;;;  )
Il calendario gregoriano è entrato in uso nel 1582. Prima vi era il
calendario giuliano (anni bisestili ogni 4 anni). In Russia è in vigore
ancora il calendario giuliano.
In ogni caso è utile la seguente formula che calcola i giorni trascorsi da
un ipotetico anno 0:
f  = 365*anno  + 31 * (mese - 1) + giorno - (int)(0.4 * mese + 2.3) +
(int)(anno / 4) - (int) (2/3 * (int)(anno / 100) + 1);
Il numero di giorni fra due date può essere calcolato come differenza fra
due valori di f. Il giorno della settimana si può ricavare calcolando il
resto intero della divisione fra f e 7 (0 = sabato, 6 = venerdì).
Maurizio.

 In Russia č in vigore ancora il calendario giuliano.
Quando ci son stato io, non mi e` parso. Comunque sei in buona compania, 
hai commesso lo stesso errore di Weyrother ad Austerlitz, anche se al 
contrario: egli aspetto` i russi sul fiume Inn per dieci giorni, mentre 
i francesi di Napoleone massacravano tranquillamente i suoi austriaci, 
solo perche` non aveva considerato che in Russia vigeva, appunto, il 
calendario giuliano (nel 1805, effettivamente, e fino all'istituzione 
dell'Unione delle Repubbliche socialiste sovietiche).
-- 
Baci,
Mony

 Quando ci son stato io, non mi e` parso.
Allora, per essere precisi, la Russia ha adottato il calendario gregoriano
nel 1923 ma solo per gli usi civili. Per gli usi religiosi i greci-ortodossi
seguono ancora quello giuliano.
Maurizio.

 (int)(anno / 4) - (int) (2/3 * (int)(anno / 100) + 1);
M'incuriosisce... ma da dove salta fuori una cosa così? Magari qualche
risorsa  che spieghi come si arriva a tale arcano risultato...
Pleg

 - (int) (3/4 * (int)(anno / 100) + 1) // togli i bisestili di fine secolo
aggiunti in eccesso (3 bisestili di troppo ogni 4 secoli)
Maurizio.

[megasnip]
.... grazie 1000 a tutti per il codice !!
Ciao