diff options
Diffstat (limited to 'src/date.c')
-rw-r--r-- | src/date.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/src/date.c b/src/date.c index 026d83391..d4c3afdd3 100644 --- a/src/date.c +++ b/src/date.c @@ -630,12 +630,14 @@ static const struct { float rLimit; /* Maximum NNN value for this transform */ float rXform; /* Constant used for this transform */ } aXformType[] = { - { 6, "second", 4.6427e+14, 1.0 }, - { 6, "minute", 7.7379e+12, 60.0 }, - { 4, "hour", 1.2897e+11, 3600.0 }, - { 3, "day", 5373485.0, 86400.0 }, - { 5, "month", 176546.0, 2592000.0 }, - { 4, "year", 14713.0, 31536000.0 }, + /* 0 */ { 6, "second", 4.6427e+14, 1.0 }, + /* 1 */ { 6, "minute", 7.7379e+12, 60.0 }, + /* 2 */ { 4, "hour", 1.2897e+11, 3600.0 }, + /* 3 */ { 3, "day", 5373485.0, 86400.0 }, + /* 4 */ { 5, "month", 176546.0, 30.0*86400.0 }, + /* 5 */ { 4, "mnth", 176546.0, 30.0*86400.0 }, + /* 6 */ { 4, "year", 14713.0, 365.0*86400.0 }, + /* 7 */ { 2, "yr", 14713.0, 365.0*86400.0 }, }; /* @@ -956,7 +958,7 @@ static int parseModifier( z += n; while( sqlite3Isspace(*z) ) z++; n = sqlite3Strlen30(z); - if( n>10 || n<3 ) break; + if( n>10 || n<2 ) break; if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; computeJD(p); assert( rc==1 ); @@ -966,22 +968,31 @@ static int parseModifier( && sqlite3_strnicmp(aXformType[i].zName, z, n)==0 && r>-aXformType[i].rLimit && r<aXformType[i].rLimit ){ + int targetMonth = 0; switch( i ){ - case 4: { /* Special processing to add months */ - assert( strcmp(aXformType[i].zName,"month")==0 ); + case 4: + case 5: { /* Special processing to add months */ + assert( strcmp(aXformType[4].zName,"month")==0 ); + assert( strcmp(aXformType[5].zName,"mnth")==0 ); computeYMD_HMS(p); p->M += (int)r; x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; p->Y += x; p->M -= x*12; + assert( p->M>=1 && p->M<=12 ); + if( i==5 ) targetMonth = p->M; p->validJD = 0; r -= (int)r; break; } - case 5: { /* Special processing to add years */ + case 6: + case 7: { /* Special processing to add years */ int y = (int)r; - assert( strcmp(aXformType[i].zName,"year")==0 ); + assert( strcmp(aXformType[6].zName,"year")==0 ); + assert( strcmp(aXformType[7].zName,"yr")==0 ); computeYMD_HMS(p); + assert( p->M>=1 && p->M<=12 ); + if( i==7 ) targetMonth = p->M; p->Y += y; p->validJD = 0; r -= (int)r; @@ -989,6 +1000,12 @@ static int parseModifier( } } computeJD(p); + if( targetMonth>0 ){ + p->validYMD = 0; + computeYMD(p); + if( p->M==targetMonth+1 ) p->iJD -= p->D*86400000; + p->validYMD = 0; + } p->iJD += (sqlite3_int64)(r*1000.0*aXformType[i].rXform + rRounder); rc = 0; break; |