Index: src/date.c ================================================================== --- src/date.c +++ src/date.c @@ -227,11 +227,11 @@ Y--; M += 12; } A = Y/100; B = 2 - A + (A/4); - X1 = 36525*(Y+4716)/100; + X1 = 365*(Y+4716) + 25*(Y+4716)/100; X2 = 306001*(M+1)/10000; p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); p->validJD = 1; if( p->validHMS ){ p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000); @@ -256,22 +256,27 @@ ** on success and 1 if the input string is not a well-formed ** date. */ static int parseYyyyMmDd(const char *zDate, DateTime *p){ int Y, M, D, neg; + char c; if( zDate[0]=='-' ){ zDate++; neg = 1; }else{ neg = 0; + if( zDate[0]=='+' ) zDate++; } - if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){ + if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)==3 ){ + zDate += 10; + }else if( getDigits(zDate,5,0,99999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)==3 ){ + zDate += 11; + }else{ return 1; } - zDate += 10; - while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; } + while( (c = zDate[0])=='T' || c=='t' || sqlite3Isspace(c) ){ zDate++; } if( parseHhMmSs(zDate, p)==0 ){ /* We got the time */ }else if( *zDate==0 ){ p->validHMS = 0; }else{ @@ -353,11 +358,11 @@ Z = (int)((p->iJD + 43200000)/86400000); A = (int)((Z - 1867216.25)/36524.25); A = Z + 1 + A - (A/4); B = A + 1524; C = (int)((B - 122.1)/365.25); - D = (36525*C)/100; + D = 365*C + (25*C)/100; E = (int)((B-D)/30.6001); X1 = (int)(30.6001*E); p->D = B - D - X1; p->M = E<14 ? E-1 : E-13; p->Y = p->M>2 ? C - 4716 : C - 4715; @@ -575,23 +580,12 @@ } break; } #endif case 'u': { - /* - ** unixepoch - ** - ** Treat the current value of p->iJD as the number of - ** seconds since 1970. Convert to a real julian day number. - */ - if( strcmp(z, "unixepoch")==0 && p->validJD ){ - p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000; - clearYMD_HMS_TZ(p); - rc = 0; - } #ifndef SQLITE_OMIT_LOCALTIME - else if( strcmp(z, "utc")==0 ){ + if( strcmp(z, "utc")==0 ){ sqlite3_int64 c1; computeJD(p); c1 = localtimeOffset(p, pCtx, &rc); if( rc==SQLITE_OK ){ p->iJD -= c1; @@ -759,29 +753,36 @@ sqlite3_context *context, int argc, sqlite3_value **argv, DateTime *p ){ - int i; + int i = 1; const unsigned char *z; int eType; memset(p, 0, sizeof(*p)); if( argc==0 ){ return setDateTimeToCurrent(context, p); } if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT || eType==SQLITE_INTEGER ){ - p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5); + if( argc>=2 && sqlite3_value_type(argv[1])==SQLITE_TEXT + && strcmp((const char*)sqlite3_value_text(argv[1]),"unixepoch")==0 ){ + i = 2; + p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*1000.0) + + 21086676*(i64)10000000; + }else{ + p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5); + } p->validJD = 1; }else{ z = sqlite3_value_text(argv[0]); if( !z || parseDateOrTime(context, (char*)z, p) ){ return 1; } } - for(i=1; i=10000 ? "%+05d" : "%04d", Y); + return sqlite3Strlen30(zBuf); +} /* ** datetime( TIMESTRING, MOD, MOD, ...) ** -** Return YYYY-MM-DD HH:MM:SS +** Return YYYY-MM-DD HH:MM:SS. The YYYY might be +YYYYY or -YYYY or -YYYYY +** depending on the year. */ static void datetimeFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ DateTime x; if( isDate(context, argc, argv, &x)==0 ){ + int i; char zBuf[100]; computeYMD_HMS(&x); - sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d %02d:%02d:%02d", - x.Y, x.M, x.D, x.h, x.m, (int)(x.s)); + i = renderYear(zBuf, x.Y); + sqlite3_snprintf(sizeof(zBuf)-i, zBuf+i, "-%02d-%02d %02d:%02d:%02d", + x.M, x.D, x.h, x.m, (int)(x.s)); sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); } } /* @@ -848,22 +868,27 @@ } /* ** date( TIMESTRING, MOD, MOD, ...) ** -** Return YYYY-MM-DD +** Return YYYY-MM-DD +** or +YYYYY-MM-DD +** or -YYYY-MM-DD +** or -YYYYY-MM-DD */ static void dateFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ DateTime x; if( isDate(context, argc, argv, &x)==0 ){ + int i; char zBuf[100]; computeYMD(&x); - sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D); + i = renderYear(zBuf, x.Y); + sqlite3_snprintf(sizeof(zBuf)-i, zBuf+i, "-%02d-%02d", x.M, x.D); sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); } } /*