formula used in calculating diffrence between dates

Discussion in 'C Programming' started by celsius, Jan 3, 2005.

  1. celsius

    celsius Guest

    Hi folks,
    Al Bowers wrote this program on comp.lang.c
    Date: 2001-07-09 13:41:58 PST
    #include <stdio.h>

    int isleap (unsigned yr);
    static unsigned months_to_days (unsigned month);
    static long years_to_days (unsigned yr);
    long ymd_to_scalar (unsigned yr, unsigned mo, unsigned day);

    int main(void) {
    unsigned y1 = 2000, m1 = 2, d1 = 1, /* represent 01FEB2000 */
    y2 = 2000, m2 = 3,d2 = 1; /* represent 01MAR2000 */
    long date1,date2;

    date1 = ymd_to_scalar(y1,m1,d1);
    date2 = ymd_to_scalar(y2,m2,d2);
    printf("There are %ld days\n",date2-date1);
    printf("It %s a leap year\n",(isleap(y1))?"is":"is not");
    return 0;
    }

    int isleap (unsigned yr)
    { return yr % 400 == 0 || (yr % 4 == 0 && yr % 100 != 0);}

    static unsigned months_to_days (unsigned month)
    { return (month * 3057 - 3007) / 100; }

    static long years_to_days (unsigned yr)
    {return yr * 365L + yr / 4 - yr / 100 + yr / 400;}

    long ymd_to_scalar (unsigned yr, unsigned mo, unsigned day)
    {
    long scalar;
    scalar = day + months_to_days(mo);
    if ( mo > 2 ) /* adjust if past February */
    scalar -= isleap(yr) ? 1 : 2;
    yr--;
    scalar += years_to_days(yr);
    return scalar;
    }

    can anybody explain the logic or formula applied in functions:-

    static unsigned months_to_days (unsigned month);
    static long years_to_days (unsigned yr):


    if want to know about the formula which is used here
    --
    comp.lang.c.moderated - moderation address: -- you must
    have an appropriate newsgroups line in your header for your mail to be seen,
    or the newsgroup name in square brackets in the subject line. Sorry.
    celsius, Jan 3, 2005
    #1
    1. Advertising

  2. --------long reply below

    "celsius" <> wrote in message
    news:...
    > Hi folks,
    > Al Bowers wrote this program on comp.lang.c
    > Date: 2001-07-09 13:41:58 PST
    > #include <stdio.h>
    >
    > int isleap (unsigned yr);
    > static unsigned months_to_days (unsigned month);
    > static long years_to_days (unsigned yr);
    > long ymd_to_scalar (unsigned yr, unsigned mo, unsigned day);
    >
    > int main(void) {
    > unsigned y1 = 2000, m1 = 2, d1 = 1, /* represent 01FEB2000 */
    > y2 = 2000, m2 = 3,d2 = 1; /* represent 01MAR2000 */
    > long date1,date2;
    >
    > date1 = ymd_to_scalar(y1,m1,d1);
    > date2 = ymd_to_scalar(y2,m2,d2);
    > printf("There are %ld days\n",date2-date1);
    > printf("It %s a leap year\n",(isleap(y1))?"is":"is not");
    > return 0;
    > }
    >
    > int isleap (unsigned yr)
    > { return yr % 400 == 0 || (yr % 4 == 0 && yr % 100 != 0);}
    >
    > static unsigned months_to_days (unsigned month)
    > { return (month * 3057 - 3007) / 100; }
    >
    > static long years_to_days (unsigned yr)
    > {return yr * 365L + yr / 4 - yr / 100 + yr / 400;}
    >
    > long ymd_to_scalar (unsigned yr, unsigned mo, unsigned day)
    > {
    > long scalar;
    > scalar = day + months_to_days(mo);
    > if ( mo > 2 ) /* adjust if past February */
    > scalar -= isleap(yr) ? 1 : 2;
    > yr--;
    > scalar += years_to_days(yr);
    > return scalar;
    > }
    >
    > can anybody explain the logic or formula applied in functions:-
    >
    > static unsigned months_to_days (unsigned month);
    > static long years_to_days (unsigned yr):
    >
    >
    > if want to know about the formula which is used here
    > --


    IMHO the formula in months_to_days is ad hoc, made up to work.
    Remember that integer divides truncate. Follow the flow of control
    to figure out what is done where. Start at main, January is month 1
    since Feb is month 2. ymd_to_scalar is called. Clearly this takes
    year-month-day to a long (i.e. scalar).

    In ymd_to_scalar, months_to_days(month) is called. This returns
    0 for January, 31 for February. Jan 1 is 0 days into the year,
    Feb 1 is 31 days into the year. For March the formula gives 61.64,
    truncates to 61, 2 days more than Mar 1 is into a non-leap year(31+28=59).
    This goes on with 2 days extra. (I checked it for December).
    Return to ymd_to_scalar and you see:
    if ( mo > 2 ) /* adjust if past February */
    scalar -= isleap(yr) ? 1 : 2;
    This takes out the extra day in leap year and extra 2 days in
    non-leap years.

    Now, scalar is the number of days into the year, based on day of month,
    month and leapyear. Then scalar is adjusted by the number of days since
    some the fictitious year zero, including adjustments for leap days. The
    leap day formula in isleap() and years_to_days() is based on
    the Gregorian calendar which did not exist until 1582 (see the calendar FAQ
    http://www.tondering.dk/claus/calendar.html ). Therefore, DO NOT USE
    this program for years before Gregorian calendar was introduced.

    yr--; //NEW NOTE calculate days that occurred
    before this year
    scalar += years_to_days(yr);

    > static long years_to_days (unsigned yr)
    > {return yr * 365L + yr / 4 - yr / 100 + yr / 400;}


    Here, yr*365L is the days if all years are non-leap years (365L is a long
    constant).
    + yr/4 adds a day for each four year cycle
    -yr/100 subtracts a day for each century year (like 1900,
    2000)
    +yr/400 adds a day for century years that are leap years
    (2000).

    ---------------- Bill

    > comp.lang.c.moderated - moderation address: -- you must
    > have an appropriate newsgroups line in your header for your mail to be

    seen,
    > or the newsgroup name in square brackets in the subject line. Sorry.

    --
    comp.lang.c.moderated - moderation address: -- you must
    have an appropriate newsgroups line in your header for your mail to be seen,
    or the newsgroup name in square brackets in the subject line. Sorry.
    William Gabler, Jan 5, 2005
    #2
    1. Advertising

  3. celsius

    Stan Milam Guest

    celsius wrote:

    > Hi folks,
    > Al Bowers wrote this program on comp.lang.c
    > Date: 2001-07-09 13:41:58 PST
    > #include <stdio.h>
    >
    > int isleap (unsigned yr);
    > static unsigned months_to_days (unsigned month);
    > static long years_to_days (unsigned yr);
    > long ymd_to_scalar (unsigned yr, unsigned mo, unsigned day);
    >
    > int main(void) {
    > unsigned y1 = 2000, m1 = 2, d1 = 1, /* represent 01FEB2000 */
    > y2 = 2000, m2 = 3,d2 = 1; /* represent 01MAR2000 */
    > long date1,date2;
    >
    > date1 = ymd_to_scalar(y1,m1,d1);
    > date2 = ymd_to_scalar(y2,m2,d2);
    > printf("There are %ld days\n",date2-date1);
    > printf("It %s a leap year\n",(isleap(y1))?"is":"is not");
    > return 0;
    > }
    >
    > int isleap (unsigned yr)
    > { return yr % 400 == 0 || (yr % 4 == 0 && yr % 100 != 0);}
    >
    > static unsigned months_to_days (unsigned month)
    > { return (month * 3057 - 3007) / 100; }
    >
    > static long years_to_days (unsigned yr)
    > {return yr * 365L + yr / 4 - yr / 100 + yr / 400;}
    >
    > long ymd_to_scalar (unsigned yr, unsigned mo, unsigned day)
    > {
    > long scalar;
    > scalar = day + months_to_days(mo);
    > if ( mo > 2 ) /* adjust if past February */
    > scalar -= isleap(yr) ? 1 : 2;
    > yr--;
    > scalar += years_to_days(yr);
    > return scalar;
    > }
    >
    > can anybody explain the logic or formula applied in functions:-
    >
    > static unsigned months_to_days (unsigned month);
    > static long years_to_days (unsigned yr):
    >
    >
    > if want to know about the formula which is used here


    The years_to_days() function is based on the formula used to calculate
    when a year is a leap year or not. This is years evenly divisible by 4
    are leap years, unless they are also evenly divisable by 100 with the
    exception they are evenly divisible by 400. Clear as mud, right?
    Basically, it calculates the number of days in a year (365L) and adjusts
    for all the leap years (366 days a year) that have intervened.

    I am not quite sure of what the month_to_days() function is based on,
    but I feel strongly that it is premised on the fact that months are
    either 30 or 31 days, with the exception of February which has 28 or 29
    days. The function is flawed because it makes the adjustment for leap
    years outside of the of the function. By this I mean that
    month_to_days() should take care of make the adjustments, not the
    calling function. If I were writing this I would do the following:

    1. Determine if the year is a leap year and store that value ( 0 or 1 ):
    is_it_a_leap_year = isleap( yr );

    2. Determine the number of days elapsed for years and store that:
    days = years_to_days( yr );

    Also, years_to_days() should make the adjustment of subtracting 1
    from the year.

    3. Determine the number of days elapsed in the current year as follows:
    days += month_to_days( month, day, is_it_a_leap_year );

    The month_to_days() function would make the adjustment for leap years
    (subtract 2 days for non leap years, or 1 day for leap years).


    --
    Regards,
    Stan Milam.
    -----------------------------------------------------------------------------
    Vita Brevis. Carpe Guitarum! - Jamie Kinscherff
    -----------------------------------------------------------------------------
    --
    comp.lang.c.moderated - moderation address: -- you must
    have an appropriate newsgroups line in your header for your mail to be seen,
    or the newsgroup name in square brackets in the subject line. Sorry.
    Stan Milam, Jan 5, 2005
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. mohammed rafi
    Replies:
    3
    Views:
    14,384
    Charles Bailey
    May 7, 2004
  2. David Lozzi

    Dates dates dates dates... SQL and ASP.NET

    David Lozzi, Sep 29, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    845
    Rob Schieber
    Sep 30, 2005
  3. clintonb
    Replies:
    9
    Views:
    857
    James Kanze
    May 23, 2007
  4. PW

    Dates! Dates! Dates!

    PW, Aug 7, 2004, in forum: ASP General
    Replies:
    4
    Views:
    178
    Mark Schupp
    Aug 9, 2004
  5. Yotam
    Replies:
    4
    Views:
    600
    Dr J R Stockton
    Nov 10, 2006
Loading...

Share This Page