const unsigned char daysInMonth[12] = {
  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};

/* Algorithm from K & R, "The C Programming Language", 1st ed. */
int leapYear(int year) {
  return (year&3) == 0 && (year%100 != 0 || year % 400 == 0);
}

/* Is a day (1-31) within a given month? */
int dayWithinMonth(int day, int month, int year) {
  int dh;
  if (day <= 0 || month<1 || month>12 ) return 0;
  dh = daysInMonth[month-1];
  if (leapYear(year) && month == 2) dh++;
  return day <= dh;
}

/*
 * Convert Gregorian calendar date to the corresponding Julian day
 * number j.  Algorithm 199 from Communications of the ACM, Volume 6, No.
 * 8, (Aug. 1963), p. 444.  Gregorian calendar started on Sep. 14, 1752.
 * This function not valid before that.
 * Returns 0 if the date is invalid.
 */

unsigned long jday(int day, int month, int year) {
  unsigned long c, ya, jd;
  if( !dayWithinMonth(day, month, year) ) return 0UL;

  if (month > 2) {
    month -= 3;  /* wash out the leap day */
  } else {
    month += 9;
    year--;
  } 
  c  = year / 100;
  ya = year - 100*c;
  jd  = ((146097*c)>>2) + ((1461*ya)>>2) + (153*month + 2)/5 + day + 1721119;
  return jd;
} 

/*
 * Convert a Julian day number to its corresponding Gregorian calendar
 * date.  Algorithm 199 from Communications of the ACM, Volume 6, No. 8,
 * (Aug. 1963), p. 444.  Gregorian calendar started on Sep. 14, 1752.
 * This function not valid before that.  
 */

void dmy(unsigned long julnum, int& d, int& m, int& y)
{
  unsigned long dh;
  unsigned long jh = julnum - 1721119;
  y  = ((jh<<2) - 1) / 146097;
  jh = (jh<<2) - 1 - 146097*y;
  dh = jh>>2;
  jh = ((dh<<2) + 3) / 1461;
  dh = (dh<<2) + 3 - 1461*jh;
  dh = (dh + 4)>>2;
  m  = (5*dh - 3)/153;
  dh = 5*dh - 3 - 153*m;
  d  = (dh + 5)/5;
  y  = 100*y + jh;
  if (m < 10)
    m += 3;
  else {
    m -= 9;
    y++;
  } 
} 

/*
 * Returns today's date
 * Uses Standard C (and therefore C++) functions only
 */
#include <signal.h>
#include <time.h>

void today(int& d, int& m, int& y)
{
  time_t clk = time(0);
  struct tm t = *localtime(&clk);
  d = t.tm_mday;
  m = t.tm_mon+1;
  y = t.tm_year+1900;
}