"Fossies" - the Fresh Open Source Software Archive

Member "anacron-2.5.3/gregor.c" (9 Dec 2007, 3465 Bytes) of package /linux/misc/old/anacron.2.5.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "gregor.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2     Anacron - run commands periodically
    3     Copyright (C) 1998  Itai Tzur <itzur@actcom.co.il>
    4     Copyright (C) 1999  Sean 'Shaleh' Perry <shaleh@debian.org>
    5  
    6     This program is free software; you can redistribute it and/or modify
    7     it under the terms of the GNU General Public License as published by
    8     the Free Software Foundation; either version 2 of the License, or
    9     (at your option) any later version.
   10  
   11     This program is distributed in the hope that it will be useful,
   12     but WITHOUT ANY WARRANTY; without even the implied warranty of
   13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14     GNU General Public License for more details.
   15  
   16     You should have received a copy of the GNU General Public License
   17     along with this program; if not, write to the Free Software
   18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   19  
   20     The GNU General Public License can also be found in the file
   21     `COPYING' that comes with the Anacron source distribution.
   22 */
   23 
   24 
   25 #include <limits.h>
   26 #include "gregor.h"
   27 
   28 const static int
   29 days_in_month[] = {
   30     31,  /* Jan */
   31     28,  /* Feb (non-leap) */
   32     31,  /* Mar */
   33     30,  /* Apr */
   34     31,  /* May */
   35     30,  /* Jun */
   36     31,  /* Jul */
   37     31,  /* Aug */
   38     30,  /* Sep */
   39     31,  /* Oct */
   40     30,  /* Nov */
   41     31  /* Dec */
   42 };
   43 
   44 static int leap(int year);
   45 
   46 int
   47 day_num(int year, int month, int day)
   48 /* Return the "day number" of the date year-month-day according to the
   49  * "proleptic Gregorian calendar".
   50  * If the given date is invalid, return -1.
   51  *
   52  * Here, "day number" is defined as the number of days since December 31,
   53  * 1 B.C. (Gregorian).  (January 1, 1 A.D. is day number 1 etc...)
   54  *
   55  * The Gregorian calendar was instituted by Pope Gregory XIII in 1582,
   56  * and has gradually spread to become the international standard calendar.
   57  * The proleptic Gregorian calendar is formed by projecting the date system
   58  * of the Gregorian calendar to dates before its adoption.
   59  *
   60  * For more details, see:
   61  * http://astro.nmsu.edu/~lhuber/leaphist.html
   62  * http://www.magnet.ch/serendipity/hermetic/cal_stud/cal_art.htm
   63  * and your local library.
   64  */
   65 {
   66     int dn;
   67     int i;
   68     int isleap; /* save three calls to leap() */
   69 
   70     /* Some validity checks */
   71 
   72     /* we don't deal with B.C. years here */
   73     if (year < 1) return - 1;
   74     /* conservative overflow estimate */
   75     if (year > (INT_MAX / 366)) return - 1;
   76     if (month > 12 || month < 1) return - 1;
   77     if (day < 1) return - 1;
   78   
   79     isleap = leap(year);
   80   
   81     if (month != 2) {
   82     if(day > days_in_month[month - 1]) return - 1;
   83     }
   84     else if ((isleap && day > 29) || (!isleap && day > 28))
   85     return - 1;
   86 
   87     /* First calculate the day number of December 31 last year */
   88 
   89     /* save us from doing (year - 1) over and over */
   90     i = year - 1;
   91     /* 365 days in a "regular" year + number of leap days */
   92     dn = (i * 365) + ((i / 4) - (i / 100) + (i / 400));
   93 
   94     /* Now, day number of the last day of the previous month */
   95 
   96     for (i = month - 1; i > 0; --i)
   97     dn += days_in_month[i - 1];
   98     /* Add 29 February ? */
   99     if (month > 2 && isleap) ++dn;
  100 
  101     /* How many days into month are we */
  102 
  103     dn += day;
  104 
  105     return dn;
  106 }
  107 
  108 static int
  109 leap(int year)
  110 /* Is this a leap year ? */
  111 {
  112     /* every year exactly divisible by 4 is "leap" */
  113     /* unless it is exactly divisible by 100 */
  114     /* but not by 400 */
  115     return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
  116 }