>Description:
        The number of months between two dates is not calculated properly by the
timestampdiff function when the second date is the same month in a future
year but the same day or earlier within the month.
        Specifically, the number of months is obtained by calculating the 
number of
complete years between the two dates, multiplying by 12, and adding the
number of months that exist in the remainder of the year that is left.
However, the loop that counts the months exits when the 'start' and 'end'
month are the same, regardless of whether these months are in different
years.  In short, when the month of both dates are the same and the day of
the second date is less than or equal to that of the first date, the result
is just the number of years between the two dates multiplied by 12.

>How-To-Repeat:

This example works as expected, as the day component of the second date is
greater:
mysql> select timestampdiff(month,'2004-06-03 00:00:00','2005-06-04
00:00:00');
+------------------------------------------------------------------+
| timestampdiff(month,'2004-06-03 00:00:00','2005-06-04 00:00:00') |
+------------------------------------------------------------------+
|                                                               12 |
+------------------------------------------------------------------+
1 row in set (0.00 sec)

This example works as expected, as the month differs between the two dates:
mysql> select timestampdiff(month,'2004-06-03 00:00:00','2005-05-31
00:00:00');
+------------------------------------------------------------------+
| timestampdiff(month,'2004-06-03 00:00:00','2005-05-31 00:00:00') |
+------------------------------------------------------------------+
|                                                               11 |
+------------------------------------------------------------------+
1 row in set (0.00 sec)

These 4 examples demonstrate what happens when this is not the case:
mysql> select timestampdiff(month,'2004-06-03 00:00:00','2005-06-03
00:00:00');
+------------------------------------------------------------------+
| timestampdiff(month,'2004-06-03 00:00:00','2005-06-03 00:00:00') |
+------------------------------------------------------------------+
|                                                                0 |
+------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select timestampdiff(month,'2004-06-03 00:00:00','2005-06-02
00:00:00');
+------------------------------------------------------------------+
| timestampdiff(month,'2004-06-03 00:00:00','2005-06-02 00:00:00') |
+------------------------------------------------------------------+
|                                                                0 |
+------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select timestampdiff(month,'2004-06-03 00:00:00','2005-06-01
00:00:00');
+------------------------------------------------------------------+
| timestampdiff(month,'2004-06-03 00:00:00','2005-06-01 00:00:00') |
+------------------------------------------------------------------+
|                                                                0 |
+------------------------------------------------------------------+
1 row in set (0.01 sec)

mysql> select timestampdiff(month,'2004-06-03 00:00:00','2006-06-01
00:00:00');
+------------------------------------------------------------------+
| timestampdiff(month,'2004-06-03 00:00:00','2006-06-01 00:00:00') |
+------------------------------------------------------------------+
|                                                               12 |
+------------------------------------------------------------------+
1 row in set (0.01 sec)


>Fix:
Applying the following patch corrects the problem for the system described
below:

--- sql/item_timefunc.cc~       Fri Jun 10 21:30:43 2005
+++ sql/item_timefunc.cc        Sun Jul  3 16:26:19 2005
@@ -2686,7 +2686,7 @@
     month_end--;

     months= 12*diff_years;
-    while (month_beg != month_end)
+    while (month_beg != month_end || year != year_end)
     {
       uint m_days= (uint) days_in_month[month_beg];
       if (month_beg == 1)


>Submitter-Id:  Travis Hillenbrand
>Originator:    Travis Hillenbrand
>Organization:
>MySQL support: none
>Synopsis:      timestampdiff func miscalculation (month only)
>Severity:      serious
>Priority:      medium
>Category:      mysql
>Class:         sw-bug
>Release:       mysql-5.0.7-beta (FreeBSD port: mysql-client-5.0.7)

>C compiler:    2.95.4
>C++ compiler:  2.95.4
>Environment:
System: FreeBSD GunSmoke 4.10-RELEASE-p16 FreeBSD 4.10-RELEASE-p16 #12: Sun
Jul  3 02:14:08 EDT 2005     [EMAIL PROTECTED]:/usr/obj/usr/src/sys/GUNSMOKE
i386


Some paths:  /bin/perl /usr/bin/make /usr/local/bin/gmake /usr/bin/gcc
/usr/bin/cc
GCC: Using builtin specs.
gcc version 2.95.4 20020320 [FreeBSD]
Compilation info: CC='cc'
 CFLAGS='-O -pipe -march=pentiumpro -D_THREAD_SAFE'  CXX='cc'
 CXXFLAGS=' -O -pipe -march=pentiumpro -D_THREAD_SAFE -O -pipe -march=pentiu
mpro -D_THREAD_SAFE -felide-constructors -fno-rtti -fno-exceptions'
LDFLAGS=' -L/usr/local/lib'  ASFLAGS=''
LIBC:
-r--r--r--  1 root  wheel  1233782 May 14 07:04 /usr/lib/libc.a
lrwxr-xr-x  1 root  wheel  9 May 14 07:04 /usr/lib/libc.so -> libc.so.4
lrwxr-xr-x  1 root  wheel  18 May  2  2004 /usr/lib/libc.so.3 ->
/usr/lib/libc.so.4
-r--r--r--  1 root  wheel  590108 May 14 07:04 /usr/lib/libc.so.4
Configure command: ./configure '--localstatedir=/var/db/mysql'
'--without-debug' '--without-readline' '--without-libedit' '--without-bench'
'--without-extra-tools' '--with-libwrap' '--with-mysqlfs'
'--with-low-memory' '--with-comment=FreeBSD port: mysql-client-5.0.7'
'--enable-thread-safe-client' '--enable-assembler' '--with-berkeley-db'
'--with-named-thread-libs=-pthread' '--without-server' '--prefix=/usr/local'
'--build=i386-portbld-freebsd4.10' 'LDFLAGS= -L/usr/local/lib'
'CFLAGS=-O -pipe -march=pentiumpro -D_THREAD_SAFE'
'CPPFLAGS=-I/usr/local/include' 'CXX=cc'
'build_alias=i386-portbld-freebsd4.10' 'CC=cc'
'CXXFLAGS= -O -pipe -march=pentiumpro -D_THREAD_SAFE -O -pipe -march=pentium
pro -D_THREAD_SAFE -felide-constructors -fno-rtti -fno-exceptions'


-- 
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:    http://lists.mysql.com/[EMAIL PROTECTED]

Reply via email to