PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/calendar - julian.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 40 43 93.0 %
Date: 2014-07-21 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* $selId: julian.c,v 2.0 1995/10/24 01:13:06 lees Exp $
       2             :  * Copyright 1993-1995, Scott E. Lee, all rights reserved.
       3             :  * Permission granted to use, copy, modify, distribute and sell so long as
       4             :  * the above copyright and this permission statement are retained in all
       5             :  * copies.  THERE IS NO WARRANTY - USE AT YOUR OWN RISK.
       6             :  */
       7             : 
       8             : /**************************************************************************
       9             :  *
      10             :  * These are the externally visible components of this file:
      11             :  *
      12             :  *     void
      13             :  *     SdnToJulian(
      14             :  *         long int  sdn,
      15             :  *         int      *pYear,
      16             :  *         int      *pMonth,
      17             :  *         int      *pDay);
      18             :  *
      19             :  * Convert a SDN to a Julian calendar date.  If the input SDN is less than
      20             :  * 1, the three output values will all be set to zero, otherwise *pYear
      21             :  * will be >= -4713 and != 0; *pMonth will be in the range 1 to 12
      22             :  * inclusive; *pDay will be in the range 1 to 31 inclusive.
      23             :  *
      24             :  *     long int
      25             :  *     JulianToSdn(
      26             :  *         int inputYear,
      27             :  *         int inputMonth,
      28             :  *         int inputDay);
      29             :  *
      30             :  * Convert a Julian calendar date to a SDN.  Zero is returned when the
      31             :  * input date is detected as invalid or out of the supported range.  The
      32             :  * return value will be > 0 for all valid, supported dates, but there are
      33             :  * some invalid dates that will return a positive value.  To verify that a
      34             :  * date is valid, convert it to SDN and then back and compare with the
      35             :  * original.
      36             :  *
      37             :  * VALID RANGE
      38             :  *
      39             :  *     4713 B.C. to at least 10000 A.D.
      40             :  *
      41             :  *     Although this software can handle dates all the way back to 4713
      42             :  *     B.C., such use may not be meaningful.  The calendar was created in
      43             :  *     46 B.C., but the details did not stabilize until at least 8 A.D.,
      44             :  *     and perhaps as late at the 4th century.  Also, the beginning of a
      45             :  *     year varied from one culture to another - not all accepted January
      46             :  *     as the first month.
      47             :  *
      48             :  * CALENDAR OVERVIEW
      49             :  *
      50             :  *     Julias Ceasar created the calendar in 46 B.C. as a modified form of
      51             :  *     the old Roman republican calendar which was based on lunar cycles.
      52             :  *     The new Julian calendar set fixed lengths for the months, abandoning
      53             :  *     the lunar cycle.  It also specified that there would be exactly 12
      54             :  *     months per year and 365.25 days per year with every 4th year being a
      55             :  *     leap year.
      56             :  *
      57             :  *     Note that the current accepted value for the tropical year is
      58             :  *     365.242199 days, not 365.25.  This lead to an 11 day shift in the
      59             :  *     calendar with respect to the seasons by the 16th century when the
      60             :  *     Gregorian calendar was created to replace the Julian calendar.
      61             :  *
      62             :  *     The difference between the Julian and today's Gregorian calendar is
      63             :  *     that the Gregorian does not make centennial years leap years unless
      64             :  *     they are a multiple of 400, which leads to a year of 365.2425 days.
      65             :  *     In other words, in the Gregorian calendar, 1700, 1800 and 1900 are
      66             :  *     not leap years, but 2000 is.  All centennial years are leap years in
      67             :  *     the Julian calendar.
      68             :  *
      69             :  *     The details are unknown, but the lengths of the months were adjusted
      70             :  *     until they finally stablized in 8 A.D. with their current lengths:
      71             :  *
      72             :  *         January          31
      73             :  *         February         28/29
      74             :  *         March            31
      75             :  *         April            30
      76             :  *         May              31
      77             :  *         June             30
      78             :  *         Quintilis/July   31
      79             :  *         Sextilis/August  31
      80             :  *         September        30
      81             :  *         October          31
      82             :  *         November         30
      83             :  *         December         31
      84             :  *
      85             :  *     In the early days of the calendar, the days of the month were not
      86             :  *     numbered as we do today.  The numbers ran backwards (decreasing) and
      87             :  *     were counted from the Ides (15th of the month - which in the old
      88             :  *     Roman republican lunar calendar would have been the full moon) or
      89             :  *     from the Nonae (9th day before the Ides) or from the beginning of
      90             :  *     the next month.
      91             :  *
      92             :  *     In the early years, the beginning of the year varied, sometimes
      93             :  *     based on the ascension of rulers.  It was not always the first of
      94             :  *     January.
      95             :  *
      96             :  *     Also, today's epoch, 1 A.D. or the birth of Jesus Christ, did not
      97             :  *     come into use until several centuries later when Christianity became
      98             :  *     a dominant religion.
      99             :  *
     100             :  * ALGORITHMS
     101             :  *
     102             :  *     The calculations are based on two different cycles: a 4 year cycle
     103             :  *     of leap years and a 5 month cycle of month lengths.
     104             :  *
     105             :  *     The 5 month cycle is used to account for the varying lengths of
     106             :  *     months.  You will notice that the lengths alternate between 30 and
     107             :  *     31 days, except for three anomalies: both July and August have 31
     108             :  *     days, both December and January have 31, and February is less than
     109             :  *     30.  Starting with March, the lengths are in a cycle of 5 months
     110             :  *     (31, 30, 31, 30, 31):
     111             :  *
     112             :  *         Mar   31 days  \
     113             :  *         Apr   30 days   |
     114             :  *         May   31 days    > First cycle
     115             :  *         Jun   30 days   |
     116             :  *         Jul   31 days  /
     117             :  *
     118             :  *         Aug   31 days  \
     119             :  *         Sep   30 days   |
     120             :  *         Oct   31 days    > Second cycle
     121             :  *         Nov   30 days   |
     122             :  *         Dec   31 days  /
     123             :  *
     124             :  *         Jan   31 days  \
     125             :  *         Feb 28/9 days   |
     126             :  *                          > Third cycle (incomplete)
     127             :  *
     128             :  *     For this reason the calculations (internally) assume that the year
     129             :  *     starts with March 1.
     130             :  *
     131             :  * TESTING
     132             :  *
     133             :  *     This algorithm has been tested from the year 4713 B.C. to 10000 A.D.
     134             :  *     The source code of the verification program is included in this
     135             :  *     package.
     136             :  *
     137             :  * REFERENCES
     138             :  *
     139             :  *     Conversions Between Calendar Date and Julian Day Number by Robert J.
     140             :  *     Tantzen, Communications of the Association for Computing Machinery
     141             :  *     August 1963.  (Also published in Collected Algorithms from CACM,
     142             :  *     algorithm number 199).  [Note: the published algorithm is for the
     143             :  *     Gregorian calendar, but was adjusted to use the Julian calendar's
     144             :  *     simpler leap year rule.]
     145             :  *
     146             :  **************************************************************************/
     147             : 
     148             : #include "sdncal.h"
     149             : #include <limits.h>
     150             : 
     151             : #define JULIAN_SDN_OFFSET         32083
     152             : #define DAYS_PER_5_MONTHS  153
     153             : #define DAYS_PER_4_YEARS   1461
     154             : 
     155          93 : void SdnToJulian(
     156             :                                         long int sdn,
     157             :                                         int *pYear,
     158             :                                         int *pMonth,
     159             :                                         int *pDay)
     160             : {
     161             :         int year;
     162             :         int month;
     163             :         int day;
     164             :         long int temp;
     165             :         int dayOfYear;
     166             : 
     167          93 :         if (sdn <= 0) {
     168           3 :                 goto fail;
     169             :         }
     170             :         /* Check for overflow */
     171          90 :         if (sdn > (LONG_MAX - JULIAN_SDN_OFFSET * 4 + 1) / 4 || sdn < LONG_MIN / 4) {
     172             :                 goto fail;
     173             :         }
     174          89 :         temp = sdn * 4 + (JULIAN_SDN_OFFSET * 4 - 1);
     175             : 
     176             :         /* Calculate the year and day of year (1 <= dayOfYear <= 366). */
     177             :         {
     178          89 :                 long yearl = temp / DAYS_PER_4_YEARS;
     179          89 :                 if (yearl > INT_MAX || yearl < INT_MIN) {
     180             :                         goto fail;
     181             :                 }
     182          89 :                 year = (int) yearl;
     183             :         }
     184          89 :         dayOfYear = (temp % DAYS_PER_4_YEARS) / 4 + 1;
     185             : 
     186             :         /* Calculate the month and day of month. */
     187          89 :         temp = dayOfYear * 5 - 3;
     188          89 :         month = temp / DAYS_PER_5_MONTHS;
     189          89 :         day = (temp % DAYS_PER_5_MONTHS) / 5 + 1;
     190             : 
     191             :         /* Convert to the normal beginning of the year. */
     192          89 :         if (month < 10) {
     193          75 :                 month += 3;
     194             :         } else {
     195          14 :                 year += 1;
     196          14 :                 month -= 9;
     197             :         }
     198             : 
     199             :         /* Adjust to the B.C./A.D. type numbering. */
     200          89 :         year -= 4800;
     201          89 :         if (year <= 0)
     202           0 :                 year--;
     203             : 
     204          89 :         *pYear = year;
     205          89 :         *pMonth = month;
     206          89 :         *pDay = day;
     207          89 :         return;
     208             : 
     209             : fail:
     210           4 :         *pYear = 0;
     211           4 :         *pMonth = 0;
     212           4 :         *pDay = 0;
     213             : }
     214             : 
     215           9 : long int JulianToSdn(
     216             :                                                 int inputYear,
     217             :                                                 int inputMonth,
     218             :                                                 int inputDay)
     219             : {
     220             :         int year;
     221             :         int month;
     222             : 
     223             :         /* check for invalid dates */
     224           9 :         if (inputYear == 0 || inputYear < -4713 ||
     225             :                 inputMonth <= 0 || inputMonth > 12 ||
     226             :                 inputDay <= 0 || inputDay > 31) {
     227           2 :                 return (0);
     228             :         }
     229             :         /* check for dates before SDN 1 (Jan 2, 4713 B.C.) */
     230           7 :         if (inputYear == -4713) {
     231           0 :                 if (inputMonth == 1 && inputDay == 1) {
     232           0 :                         return (0);
     233             :                 }
     234             :         }
     235             :         /* Make year always a positive number. */
     236           7 :         if (inputYear < 0) {
     237           1 :                 year = inputYear + 4801;
     238             :         } else {
     239           6 :                 year = inputYear + 4800;
     240             :         }
     241             : 
     242             :         /* Adjust the start of the year. */
     243           7 :         if (inputMonth > 2) {
     244           3 :                 month = inputMonth - 3;
     245             :         } else {
     246           4 :                 month = inputMonth + 9;
     247           4 :                 year--;
     248             :         }
     249             : 
     250          14 :         return ((year * DAYS_PER_4_YEARS) / 4
     251           7 :                         + (month * DAYS_PER_5_MONTHS + 2) / 5
     252           7 :                         + inputDay
     253           7 :                         - JULIAN_SDN_OFFSET);
     254             : }
     255             : 
     256             : /*
     257             :  * Local variables:
     258             :  * tab-width: 4
     259             :  * c-basic-offset: 4
     260             :  * End:
     261             :  * vim600: sw=4 ts=4 fdm=marker
     262             :  * vim<600: sw=4 ts=4
     263             :  */

Generated by: LCOV version 1.10

Generated at Tue, 22 Jul 2014 01:33:07 +0000 (9 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.