tags:

views:

612

answers:

7
  • Any year evenly divisible by 400 is a leap year (e.g., 2000 was a leap year).
  • Any other year evenly divisible by 100 is not a leap year (e.g., 1700, 1800 and 1900 were not leap years).
  • Any other year evenly divisible by 4 is a leap year (e.g., 1996 and 2004 are leap years).

But I'm not sure how to make nested if states in my c-program that would produce the right answer...

+1  A: 

Google is your friend: http://alcor.concordia.ca/~gpkatch/gdate-algorithm.html

dmonlord
+13  A: 

Convert them both to epoch time and subtract the difference.

Epoch time = (number of seconds since 1970).

Once you've got the number of seconds, you divide that by 24 * 60 * 60 = 86,400.

Rap
Yes, yes, yes. Do this. DO NOT muck with calendrics if you value your sanity. The length of a day is fixed (if you ignore leap seconds, which you should because software does). The epoch timeline is a simple scalar number. This is the representation you want. Any answer involving calendar terms is wrong.
Andy Ross
DST in local time in much of the world has days that vary in length by an hour.If you're calculating in seconds, and dividing by 86400, I'd be careful to round, as appose to floor.
JasonWoof
Andy, beware of the year 2038 problem, etc. And you don't get dates before mid-December 1901, either.
Robert L
And I am not sane, so I muck about with calendrics.
Robert L
+1  A: 

Leap year algorithm from wikipedia:

Pseudocode 1:

if year modulo 400 is 0 then leap
 else if year modulo 100 is 0 then no_leap
 else if year modulo 4 is 0 then leap
 else no_leap

Pseudocode 2:

function isLeapYear (year):
  if ((year modulo 4 is 0) and (year modulo 100 is not 0)) or (year modulo 400 is 0)
   then true
  else false
shufler
+2  A: 

I would convert the two dates in Julian day and then do the difference, but I would have to check if this is a good solution with no drawbacks first. I suggest you to do the same.

Stefano Borini
+2  A: 

Find one of the libraries that converts dates into 'number of days since some epoch' (often called a Julian day - though there are official rules for the astronomical Julian Date, and Modified Julian Date). Then convert each date into the relevant number, and take the difference. Assuming the library handles leap years, so does your answer.

For ideas on one such set of code, see 'Calendrical Calculations'.

Jonathan Leffler
+1  A: 
#include <time.h>
#define SECONDS_PER_DAY (24 * 60 * 60)

time_t time_from_date(int year, unsigned month, unsigned day)
{
    return mktime(&(struct tm){
        .tm_year = year - 1900, .tm_mon = month - 1, .tm_mday = day });
}

int days_between(int year0, unsigned month0, unsigned day0,
    int year1, unsigned month1, unsigned day1)
{
    return difftime(time_from_date(year1, month1, day1),
        time_from_date(year0, month0, day0)) / SECONDS_PER_DAY;
}
Christoph
is it C99 ?
Stefano Borini
@Stefano: yes it is, as I used a compound literal with named initializers as argument to `mktime()`; for the C90 version, declare the struct in the function and set the members individually
Christoph
A: 

You don't need nested conditionals at all for this.

Hint: instead of trying to determine whether a given year is a leap year, try to determine the total number of leap days that came before it.

Robert L