Newsgroup: it.comp.lang.c
Titolo: Calendario Perpetuo e Y2K...

Devo fare una funzione che si pappa giorno, mese, anno (espresso con 4
cifre) e restituisce il giorno della settimana (lu, ma, me...).
Tra le librerie del Borland C(4.5) non ho trovato niente e quel poco che c'č
funziona solo con le ultime 2 cifre per l'anno. Come si puň fare?
Grazie

cifre) e restituisce il giorno della settimana (lu, ma, me...).
Se interessa qualcosa di veloce puoi usare questo (dopo le opportune
modifiche) :
#include <time.h>
int dow(time_t data)
 {
 struct tm * lt;
 lt = localtime(& data);
 return lt->tm_wday;      /* 0 = domenica, etc. */
 }
Altrimenti puoi usare quest'algoritmo (preso da un messaggio inviato
in Fidonet) :
Algoritmo tratto da J. Meeus, Astronomia con il computer, Hoepli ed.
0) Sia YYYY l'anno, MM il mese, DD il giorno.
1) Trasforma la data di calendario in Giorno Giuliano:
 
    se MM > 2  prendi y = YYYY   e m = MM      
    se MM <= 2 prendi y = YYYY-1 e m = MM + 12
Se YYYY/MM/DD > 1582/10/15 (data di introduzione della "correzione" di
10 giorni e alcune variazioni sugli anni bisest.)
       A = INT(y/100) e B = 2-A+INT(A/4)
 
altrimenti A = B = 0.
Quindi hai:
JD = INT(326.25*(y+4716))+INT(30.6*(m+1))+DD+B-1524
2) Giorno della settimana = JD % 7 (non mi ricordo a quale corrisponde
il lunedì ecc., comunque sono sequenziali: fai una semplice prova)
Il programma funziona SEMPRE (include infatti la correzione di papa
Gregorio del 1582) e l'ho già usato innumerevoli volte. Consiglio: se
vuoi evitare di linkare la libreria FP (se non l'hai già linkata) puoi
scrivere l'ultima formula come:
[long] JD = (32625L*(y+4716L))/100+(306L*(m+1))/10+DD+B-1524
Altrimenti : nelle Snippets (raccolta di routine con molti esempi
prelevabile da molti siti in rete) hai delle routine piu' complesse.
Altrimenti : parliamone :-)))
ciao

funziona solo con le ultime 2 cifre per l'anno. Come si può fare?
int dayofweek(int y, int m, int d)	/* 0 = Domenica */
{
	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;
}
per riconoscere se un anno e' bisestile o no, usa la formula:
year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
--
Andrea Laforgia        (
andrea_...@bigfoot.com
)

/*-------------------------------------------------------------------*
 | This algorithm, "Zeller's congruence", is the usual - and fairly  |
 | efficient - method of finding out on which day of the week a date |
 | falls.  Note that the year is not a two-digits sequence, but the  |
 | FULL year number, e.g. "1989".                                    |
 *-------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#define isleap(year) (((year) % 4   == 0) && \
                     (((year) % 100 != 0) || ((year) % 400 == 0)))
int weekDay(int, int, int);
int main(
  int argc,
  char *argv[]
) {
  int retVal = EXIT_FAILURE;
  if (argc != 4) {
    fprintf(stderr, "Usage: %s <day> <month> <year>\n", argv[0]);
  } else {
    int d, m, y;
    d = atoi(*++argv);
    m = atoi(*++argv);
    y = atoi(*++argv);
    if (y < 1753) {
      fputs("The year should be at least 1753\n", stderr);
    } else if (m < 1   ||   m > 12) {
      fputs("The month should be in the range 1..12\n", stderr);
    } else {
      int monthDays[] = {
         0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
      };
 
      monthDays[2] = isleap(y) ? 29 : 28;
      if (d < 1   ||   d > monthDays[m]) {
        fprintf(stderr, "The day should be in the range 1..%d\n",
                monthDays[m]);
      } else {
        char const *dayNames[] = {
          "sunday", "monday", "tuesday", "wednesday",
          "thursday", "friday", "saturday"
        };
        char const *monthNames[] = {
          "BAD", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
        };
        fprintf(stdout, "%02d-%s-%d is a %s\n",
                d, monthNames[m], y, dayNames[weekDay(d, m, y)]);
        retVal = EXIT_SUCCESS;
      }
    }
  }
  return retVal;
}
int weekDay(
  int d,
  int m,
  int y
) {
  if (m < 3) {
    m += 12;
    y--;
  }
  return ((d + (13 * m - 27)/5 + y + y/4 - y/100 + y/400) % 7);
}
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it