root/anacron/gregor.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. day_num
  2. leap
  3. days_last_month
  4. days_this_month
  5. days_last_year
  6. days_this_year

   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     Copyright (C) 2004  Pascal Hakim <pasc@redellipse.net>
   6 
   7     This program is free software; you can redistribute it and/or modify
   8     it under the terms of the GNU General Public License as published by
   9     the Free Software Foundation; either version 2 of the License, or
  10     (at your option) any later version.
  11 
  12     This program is distributed in the hope that it will be useful,
  13     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15     GNU General Public License for more details.
  16 
  17     You should have received a copy of the GNU General Public License along
  18     with this program; if not, write to the Free Software Foundation, Inc.,
  19     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20  
  21     The GNU General Public License can also be found in the file
  22     `COPYING' that comes with the Anacron source distribution.
  23 */
  24 
  25 
  26 #include <limits.h>
  27 #include <time.h>
  28 #include "gregor.h"
  29 
  30 static const int
  31 days_in_month[] = {
  32     31,  /* Jan */
  33     28,  /* Feb (non-leap) */
  34     31,  /* Mar */
  35     30,  /* Apr */
  36     31,  /* May */
  37     30,  /* Jun */
  38     31,  /* Jul */
  39     31,  /* Aug */
  40     30,  /* Sep */
  41     31,  /* Oct */
  42     30,  /* Nov */
  43     31  /* Dec */
  44 };
  45 
  46 static int leap(int year);
  47 
  48 int
  49 day_num(int year, int month, int day)
     /* [previous][next][first][last][top][bottom][index][help]  */
  50 /* Return the "day number" of the date year-month-day according to the
  51  * "proleptic Gregorian calendar".
  52  * If the given date is invalid, return -1.
  53  *
  54  * Here, "day number" is defined as the number of days since December 31,
  55  * 1 B.C. (Gregorian).  (January 1, 1 A.D. is day number 1 etc...)
  56  *
  57  * The Gregorian calendar was instituted by Pope Gregory XIII in 1582,
  58  * and has gradually spread to become the international standard calendar.
  59  * The proleptic Gregorian calendar is formed by projecting the date system
  60  * of the Gregorian calendar to dates before its adoption.
  61  *
  62  * For more details, see:
  63  * http://astro.nmsu.edu/~lhuber/leaphist.html
  64  * http://www.magnet.ch/serendipity/hermetic/cal_stud/cal_art.htm
  65  * and your local library.
  66  */
  67 {
  68     int dn;
  69     int i;
  70     int isleap; /* save three calls to leap() */
  71 
  72     /* Some validity checks */
  73 
  74     /* we don't deal with B.C. years here */
  75     if (year < 1) return - 1;
  76     /* conservative overflow estimate */
  77     if (year > (INT_MAX / 366)) return - 1;
  78     if (month > 12 || month < 1) return - 1;
  79     if (day < 1) return - 1;
  80   
  81     isleap = leap(year);
  82   
  83     if (month != 2) {
  84         if(day > days_in_month[month - 1]) return - 1;
  85     }
  86     else if ((isleap && day > 29) || (!isleap && day > 28))
  87         return - 1;
  88 
  89     /* First calculate the day number of December 31 last year */
  90 
  91     /* save us from doing (year - 1) over and over */
  92     i = year - 1;
  93     /* 365 days in a "regular" year + number of leap days */
  94     dn = (i * 365) + ((i / 4) - (i / 100) + (i / 400));
  95 
  96     /* Now, day number of the last day of the previous month */
  97 
  98     for (i = month - 1; i > 0; --i)
  99         dn += days_in_month[i - 1];
 100     /* Add 29 February ? */
 101     if (month > 2 && isleap) ++dn;
 102 
 103     /* How many days into month are we */
 104 
 105     dn += day;
 106 
 107     return dn;
 108 }
 109 
 110 static int
 111 leap(int year)
     /* [previous][next][first][last][top][bottom][index][help]  */
 112 /* Is this a leap year ? */
 113 {
 114     /* every year exactly divisible by 4 is "leap" */
 115     /* unless it is exactly divisible by 100 */
 116     /* but not by 400 */
 117     return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
 118 }
 119 
 120 int
 121 days_last_month (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 122 /* How many days did last month have? */
 123 {
 124     struct tm time_record;
 125     time_t current_time;
 126     time (&current_time);
 127     localtime_r (&current_time, &time_record);
 128 
 129     switch (time_record.tm_mon) {
 130         case 0: return days_in_month[11];
 131         case 2: return days_in_month[1] + (leap (time_record.tm_year + 1900) ? 1 : 0);
 132         default: return days_in_month[time_record.tm_mon - 1];
 133     }
 134 }
 135 
 136 int
 137 days_this_month (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 138 /* How many days does this month have? */
 139 {
 140     struct tm time_record;
 141     time_t current_time;
 142     time (&current_time);
 143     localtime_r (&current_time, &time_record);
 144 
 145     switch (time_record.tm_mon) {
 146         case 1: return days_in_month[1] + (leap (time_record.tm_year + 1900) ? 1 : 0);
 147         default: return days_in_month[time_record.tm_mon];
 148     }
 149 }
 150 
 151 int
 152 days_last_year (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 153 /* How many days this last year have? */
 154 {
 155     struct tm time_record;
 156     time_t current_time;
 157     time (&current_time);
 158     localtime_r (&current_time, &time_record);
 159 
 160     if (leap(time_record.tm_year - 1 + 1900)) {
 161         return 366;
 162     }
 163 
 164     return 365;
 165 }
 166 
 167 int
 168 days_this_year (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 169 /* How many days does this year have */
 170 {
 171      struct tm time_record;
 172     time_t current_time;
 173     time (&current_time);
 174     localtime_r (&current_time, &time_record);
 175 
 176     if (leap(time_record.tm_year + 1900)) {
 177         return 366;
 178     }
 179 
 180     return 365;
 181 }

/* [previous][next][first][last][top][bottom][index][help]  */