Bug #52744 [NEW]: cal_days_in_month

From: Date: Mon, 30 Aug 2010 16:16:53 +0000
Subject: Bug #52744 [NEW]: cal_days_in_month
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-153934@lists.php.net to get a copy of this message
From:             
Operating system: all
PHP version:      5.3SVN-2010-08-30 (snap)
Package:          Calendar related
Bug Type:         Bug
Bug description:cal_days_in_month

Description:
------------
Function cal_days_in_month returns wrong result for December 1 BCE:

echo cal_days_in_month(CAL_GREGORIAN, 12, -1) returns -1721395
echo cal_days_in_month(CAL_JULIAN, 12, -1) returns -1721393

The function uses julian day count internally to calculate the day count 
difference between the 1st day of the supplied month and the 1st day of the
next 
month. The next month of December 1 BCE (year -1) is January 1 CE (year 1,
there 
is no year zero).

But when cal_days_in_month calculates the next year as year+1, it does not
check 
for year zero, so it tries to calculate the julian day for 1st January 0,
which 
returns 0 and consequently the wrong result of days in December 1 BCE is 
returned.

actual function code taken from latest svn snapshot php5.3-201008301230 
(/ext/calendar.c):

-----------------------
PHP_FUNCTION(cal_days_in_month)
{
        long cal, month, year;
        struct cal_entry_t *calendar;
        long sdn_start, sdn_next;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &cal, 
&month, &year) == FAILURE) {
                RETURN_FALSE;
        }

        if (cal < 0 || cal >= CAL_NUM_CALS) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid
calendar ID 
%ld.", cal);
                RETURN_FALSE;
        }

        calendar = &cal_conversion_table[cal];

        sdn_start = calendar->to_jd(year, month, 1);

        if (sdn_start == 0) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid
date.");
                RETURN_FALSE;
        }

        sdn_next = calendar->to_jd(year, 1 + month, 1);

        if (sdn_next == 0) {
/* if invalid, try first month of the next year... */
                sdn_next = calendar->to_jd(year + 1, 1, 1);
        }

        RETURN_LONG(sdn_next - sdn_start);
}
-----------------------

The following correction is proposed:

-----------------------
 	if (sdn_next == 0) {
 /* if invalid, try first month of the next year... */
-		sdn_next = calendar->to_jd(year + 1, 1, 1);
+		if (year == -1) {
+			sdn_next = calendar->to_jd(1, 1, 1);
+		} else {
+			sdn_next = calendar->to_jd(year + 1, 1, 1);
+		}
 	}
-----------------------

Test script:
---------------
<?php
// returns -1721395 instead of 31
echo cal_days_in_month(CAL_GREGORIAN, 12, -1);

// returns -1721393 instead of 31
echo cal_days_in_month(CAL_JULIAN, 12, -1);
?>

Expected result:
----------------
31
31

Actual result:
--------------
-1721395
-1721393

-- 
Edit bug report at http://bugs.php.net/bug.php?id=52744&edit=1
-- 
Try a snapshot (PHP 5.2):            http://bugs.php.net/fix.php?id=52744&r=trysnapshot52
Try a snapshot (PHP 5.3):            http://bugs.php.net/fix.php?id=52744&r=trysnapshot53
Try a snapshot (trunk):              http://bugs.php.net/fix.php?id=52744&r=trysnapshottrunk
Fixed in SVN:                        http://bugs.php.net/fix.php?id=52744&r=fixed
Fixed in SVN and need be documented: http://bugs.php.net/fix.php?id=52744&r=needdocs
Fixed in release:                    http://bugs.php.net/fix.php?id=52744&r=alreadyfixed
Need backtrace:                      http://bugs.php.net/fix.php?id=52744&r=needtrace
Need Reproduce Script:               http://bugs.php.net/fix.php?id=52744&r=needscript
Try newer version:                   http://bugs.php.net/fix.php?id=52744&r=oldversion
Not developer issue:                 http://bugs.php.net/fix.php?id=52744&r=support
Expected behavior:                   http://bugs.php.net/fix.php?id=52744&r=notwrong
Not enough info:                     http://bugs.php.net/fix.php?id=52744&r=notenoughinfo
Submitted twice:                     http://bugs.php.net/fix.php?id=52744&r=submittedtwice
register_globals:                    http://bugs.php.net/fix.php?id=52744&r=globals
PHP 4 support discontinued:          http://bugs.php.net/fix.php?id=52744&r=php4
Daylight Savings:                    http://bugs.php.net/fix.php?id=52744&r=dst
IIS Stability:                       http://bugs.php.net/fix.php?id=52744&r=isapi
Install GNU Sed:                     http://bugs.php.net/fix.php?id=52744&r=gnused
Floating point limitations:          http://bugs.php.net/fix.php?id=52744&r=float
No Zend Extensions:                  http://bugs.php.net/fix.php?id=52744&r=nozend
MySQL Configuration Error:           http://bugs.php.net/fix.php?id=52744&r=mysqlcfg



Thread (3 messages)

« previous php.bugs (#153934) next »