Fix a round-off error when moving dates by negative modifier amounts.

Ticket #3618.  Enhance the "NNN years" modifier to accept fractional
years. (CVS 6220)

FossilOrigin-Name: 86be908c5e77ba2b9ac98e394fa987b443d790f8
This commit is contained in:
drh 2009-01-30 17:27:44 +00:00
parent 1a38964b50
commit c531a22377
4 changed files with 45 additions and 17 deletions

View File

@ -1,5 +1,5 @@
C Made\scode\sto\sremove\sunused\sparameter\swarning\spart\sof\sthe\sconditional.\s\sTicket\s#3610.\s(CVS\s6219)
D 2009-01-30T16:09:23
C Fix\sa\sround-off\serror\swhen\smoving\sdates\sby\snegative\smodifier\samounts.\nTicket\s#3618.\s\sEnhance\sthe\s"NNN\syears"\smodifier\sto\saccept\sfractional\nyears.\s(CVS\s6220)
D 2009-01-30T17:27:44
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 3871d308188cefcb7c5ab20da4c7b6aad023bc52
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -109,7 +109,7 @@ F src/btreeInt.h 44bcbfe387ba99a3a9f2527bd12fa1bb8bc574b3
F src/build.c c8bf5dcef4d5889bc57eecdb8b3dba178e5e06a8
F src/callback.c bee8949d619b1b7b1e4dfac8a19c5116ae1dd12a
F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
F src/date.c b4db68e6cd7f3c7b437c440fca5863692b8cd026
F src/date.c 870770dde3fb56772ab247dfb6a6eda44d16cfbc
F src/delete.c 6249005bdd8f85db6ec5f31ddb5c07de023693cc
F src/expr.c 76dc3dc83b56ab8db50a772714fac49def8bbf12
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
@ -291,7 +291,7 @@ F test/crash8.test 5b32966fcb58fd616d24ce94303420351d076eb9
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/createtab.test 199cf68f44e5d9e87a0b8afc7130fdeb4def3272
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
F test/date.test 4ea54e26feea7c24dfc7fad1b2b87da21ff12380
F test/date.test bb2cc648333c04d09e8e23cfc0cddc398c334a92
F test/default.test 252298e42a680146b1dd64f563b95bdf088d94fb
F test/delete.test f171c1011395a8dd63169438fe1d8cc625eb7442
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
@ -693,7 +693,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P 0a2c7f740397c5c6373434c75d73c2714f14dd32
R 649046167725b542f7b218aebaf5f5d8
U shane
Z 487e1bd5693e1aade7bfd1bf63c7b518
P c5dca1146de72071ed2e5fdf6890f41682272587
R 6a74041552de27456797035382a955bb
U drh
Z 4f589fc1347644d84b8da190a4ca5065

View File

@ -1 +1 @@
c5dca1146de72071ed2e5fdf6890f41682272587
86be908c5e77ba2b9ac98e394fa987b443d790f8

View File

@ -16,7 +16,7 @@
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: date.c,v 1.101 2009/01/28 02:55:29 drh Exp $
** $Id: date.c,v 1.102 2009/01/30 17:27:44 drh Exp $
**
** SQLite processes all times and dates as Julian Day numbers. The
** dates and times are stored as the number of days since noon
@ -629,6 +629,7 @@ static int parseModifier(const char *zMod, DateTime *p){
case '7':
case '8':
case '9': {
double rRounder;
n = getValue(z, &r);
assert( n>=1 );
if( z[n]==':' ){
@ -661,14 +662,15 @@ static int parseModifier(const char *zMod, DateTime *p){
if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
computeJD(p);
rc = 0;
rRounder = r<0 ? -0.5 : +0.5;
if( n==3 && strcmp(z,"day")==0 ){
p->iJD += (sqlite3_int64)(r*86400000.0 + 0.5);
p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder);
}else if( n==4 && strcmp(z,"hour")==0 ){
p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + 0.5);
p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder);
}else if( n==6 && strcmp(z,"minute")==0 ){
p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + 0.5);
p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder);
}else if( n==6 && strcmp(z,"second")==0 ){
p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + 0.5);
p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder);
}else if( n==5 && strcmp(z,"month")==0 ){
int x, y;
computeYMD_HMS(p);
@ -680,13 +682,17 @@ static int parseModifier(const char *zMod, DateTime *p){
computeJD(p);
y = (int)r;
if( y!=r ){
p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + 0.5);
p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder);
}
}else if( n==4 && strcmp(z,"year")==0 ){
int y = (int)r;
computeYMD_HMS(p);
p->Y += (int)r;
p->Y += y;
p->validJD = 0;
computeJD(p);
if( y!=r ){
p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder);
}
}else{
rc = 1;
}

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing date and time functions.
#
# $Id: date.test,v 1.31 2008/07/08 02:12:37 drh Exp $
# $Id: date.test,v 1.32 2009/01/30 17:27:44 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -454,6 +454,28 @@ datetest 13.6 {strftime('%Y-%m-%d %H:%M:%S', '2007-01-01 23:59:59.6')} \
datetest 13.7 {strftime('%Y-%m-%d %H:%M:%f', '2007-01-01 23:59:59.6')} \
{2007-01-01 23:59:59.600}
# Ticket #3618
datetest 13.11 {julianday(2454832.5,'-1 day')} {2454831.5}
datetest 13.12 {julianday(2454832.5,'+1 day')} {2454833.5}
datetest 13.13 {julianday(2454832.5,'-1.5 day')} {2454831.0}
datetest 13.14 {julianday(2454832.5,'+1.5 day')} {2454834.0}
datetest 13.15 {julianday(2454832.5,'-3 hours')} {2454832.375}
datetest 13.16 {julianday(2454832.5,'+3 hours')} {2454832.625}
datetest 13.17 {julianday(2454832.5,'-45 minutes')} {2454832.46875}
datetest 13.18 {julianday(2454832.5,'+45 minutes')} {2454832.53125}
datetest 13.19 {julianday(2454832.5,'-675 seconds')} {2454832.4921875}
datetest 13.20 {julianday(2454832.5,'+675 seconds')} {2454832.5078125}
datetest 13.21 {julianday(2454832.5,'-1.5 months')} {2454786.5}
datetest 13.22 {julianday(2454832.5,'+1.5 months')} {2454878.5}
datetest 13.23 {julianday(2454832.5,'-1.5 years')} {2454284.0}
datetest 13.24 {julianday(2454832.5,'+1.5 years')} {2455380.0}
datetest 13.30 {date('2000-01-01','+1.5 years')} {2001-07-02}
datetest 13.31 {date('2001-01-01','+1.5 years')} {2002-07-02}
datetest 13.32 {date('2002-01-01','+1.5 years')} {2003-07-02}
datetest 13.33 {date('2002-01-01','-1.5 years')} {2000-07-02}
datetest 13.34 {date('2001-01-01','-1.5 years')} {1999-07-02}
# Test for issues reported by BareFeet (list.sql at tandb.com.au)
# on mailing list on 2008-06-12.
#