| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137 |
- /*
- ** 2003 October 31
- **
- ** The author disclaims copyright to this source code. In place of
- ** a legal notice, here is a blessing:
- **
- ** May you do good and not evil.
- ** May you find forgiveness for yourself and forgive others.
- ** May you share freely, never taking more than you give.
- **
- *************************************************************************
- ** This file contains the C functions that implement date and time
- ** functions for SQLite.
- **
- ** There is only one exported symbol in this file - the function
- ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
- ** All other code has file scope.
- **
- ** SQLite processes all times and dates as Julian Day numbers. The
- ** dates and times are stored as the number of days since noon
- ** in Greenwich on November 24, 4714 B.C. according to the Gregorian
- ** calendar system.
- **
- ** 1970-01-01 00:00:00 is JD 2440587.5
- ** 2000-01-01 00:00:00 is JD 2451544.5
- **
- ** This implemention requires years to be expressed as a 4-digit number
- ** which means that only dates between 0000-01-01 and 9999-12-31 can
- ** be represented, even though julian day numbers allow a much wider
- ** range of dates.
- **
- ** The Gregorian calendar system is used for all dates and times,
- ** even those that predate the Gregorian calendar. Historians usually
- ** use the Julian calendar for dates prior to 1582-10-15 and for some
- ** dates afterwards, depending on locale. Beware of this difference.
- **
- ** The conversion algorithms are implemented based on descriptions
- ** in the following text:
- **
- ** Jean Meeus
- ** Astronomical Algorithms, 2nd Edition, 1998
- ** ISBM 0-943396-61-1
- ** Willmann-Bell, Inc
- ** Richmond, Virginia (USA)
- */
- #include "sqliteInt.h"
- #include <stdlib.h>
- #include <assert.h>
- #include <time.h>
- #ifndef SQLITE_OMIT_DATETIME_FUNCS
- /*
- ** A structure for holding a single date and time.
- */
- typedef struct DateTime DateTime;
- struct DateTime {
- sqlite3_int64 iJD; /* The julian day number times 86400000 */
- int Y, M, D; /* Year, month, and day */
- int h, m; /* Hour and minutes */
- int tz; /* Timezone offset in minutes */
- double s; /* Seconds */
- char validYMD; /* True (1) if Y,M,D are valid */
- char validHMS; /* True (1) if h,m,s are valid */
- char validJD; /* True (1) if iJD is valid */
- char validTZ; /* True (1) if tz is valid */
- };
- /*
- ** Convert zDate into one or more integers. Additional arguments
- ** come in groups of 5 as follows:
- **
- ** N number of digits in the integer
- ** min minimum allowed value of the integer
- ** max maximum allowed value of the integer
- ** nextC first character after the integer
- ** pVal where to write the integers value.
- **
- ** Conversions continue until one with nextC==0 is encountered.
- ** The function returns the number of successful conversions.
- */
- static int getDigits(const char *zDate, ...){
- va_list ap;
- int val;
- int N;
- int min;
- int max;
- int nextC;
- int *pVal;
- int cnt = 0;
- va_start(ap, zDate);
- do{
- N = va_arg(ap, int);
- min = va_arg(ap, int);
- max = va_arg(ap, int);
- nextC = va_arg(ap, int);
- pVal = va_arg(ap, int*);
- val = 0;
- while( N-- ){
- if( !sqlite3Isdigit(*zDate) ){
- goto end_getDigits;
- }
- val = val*10 + *zDate - '0';
- zDate++;
- }
- if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
- goto end_getDigits;
- }
- *pVal = val;
- zDate++;
- cnt++;
- }while( nextC );
- end_getDigits:
- va_end(ap);
- return cnt;
- }
- /*
- ** Parse a timezone extension on the end of a date-time.
- ** The extension is of the form:
- **
- ** (+/-)HH:MM
- **
- ** Or the "zulu" notation:
- **
- ** Z
- **
- ** If the parse is successful, write the number of minutes
- ** of change in p->tz and return 0. If a parser error occurs,
- ** return non-zero.
- **
- ** A missing specifier is not considered an error.
- */
- static int parseTimezone(const char *zDate, DateTime *p){
- int sgn = 0;
- int nHr, nMn;
- int c;
- while( sqlite3Isspace(*zDate) ){ zDate++; }
- p->tz = 0;
- c = *zDate;
- if( c=='-' ){
- sgn = -1;
- }else if( c=='+' ){
- sgn = +1;
- }else if( c=='Z' || c=='z' ){
- zDate++;
- goto zulu_time;
- }else{
- return c!=0;
- }
- zDate++;
- if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
- return 1;
- }
- zDate += 5;
- p->tz = sgn*(nMn + nHr*60);
- zulu_time:
- while( sqlite3Isspace(*zDate) ){ zDate++; }
- return *zDate!=0;
- }
- /*
- ** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
- ** The HH, MM, and SS must each be exactly 2 digits. The
- ** fractional seconds FFFF can be one or more digits.
- **
- ** Return 1 if there is a parsing error and 0 on success.
- */
- static int parseHhMmSs(const char *zDate, DateTime *p){
- int h, m, s;
- double ms = 0.0;
- if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){
- return 1;
- }
- zDate += 5;
- if( *zDate==':' ){
- zDate++;
- if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
- return 1;
- }
- zDate += 2;
- if( *zDate=='.' && sqlite3Isdigit(zDate[1]) ){
- double rScale = 1.0;
- zDate++;
- while( sqlite3Isdigit(*zDate) ){
- ms = ms*10.0 + *zDate - '0';
- rScale *= 10.0;
- zDate++;
- }
- ms /= rScale;
- }
- }else{
- s = 0;
- }
- p->validJD = 0;
- p->validHMS = 1;
- p->h = h;
- p->m = m;
- p->s = s + ms;
- if( parseTimezone(zDate, p) ) return 1;
- p->validTZ = (p->tz!=0)?1:0;
- return 0;
- }
- /*
- ** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume
- ** that the YYYY-MM-DD is according to the Gregorian calendar.
- **
- ** Reference: Meeus page 61
- */
- static void computeJD(DateTime *p){
- int Y, M, D, A, B, X1, X2;
- if( p->validJD ) return;
- if( p->validYMD ){
- Y = p->Y;
- M = p->M;
- D = p->D;
- }else{
- Y = 2000; /* If no YMD specified, assume 2000-Jan-01 */
- M = 1;
- D = 1;
- }
- if( M<=2 ){
- Y--;
- M += 12;
- }
- A = Y/100;
- B = 2 - A + (A/4);
- X1 = 36525*(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);
- if( p->validTZ ){
- p->iJD -= p->tz*60000;
- p->validYMD = 0;
- p->validHMS = 0;
- p->validTZ = 0;
- }
- }
- }
- /*
- ** Parse dates of the form
- **
- ** YYYY-MM-DD HH:MM:SS.FFF
- ** YYYY-MM-DD HH:MM:SS
- ** YYYY-MM-DD HH:MM
- ** YYYY-MM-DD
- **
- ** Write the result into the DateTime structure and return 0
- ** 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;
- if( zDate[0]=='-' ){
- zDate++;
- neg = 1;
- }else{
- neg = 0;
- }
- if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
- return 1;
- }
- zDate += 10;
- while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; }
- if( parseHhMmSs(zDate, p)==0 ){
- /* We got the time */
- }else if( *zDate==0 ){
- p->validHMS = 0;
- }else{
- return 1;
- }
- p->validJD = 0;
- p->validYMD = 1;
- p->Y = neg ? -Y : Y;
- p->M = M;
- p->D = D;
- if( p->validTZ ){
- computeJD(p);
- }
- return 0;
- }
- /*
- ** Set the time to the current time reported by the VFS.
- **
- ** Return the number of errors.
- */
- static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
- p->iJD = sqlite3StmtCurrentTime(context);
- if( p->iJD>0 ){
- p->validJD = 1;
- return 0;
- }else{
- return 1;
- }
- }
- /*
- ** Attempt to parse the given string into a Julian Day Number. Return
- ** the number of errors.
- **
- ** The following are acceptable forms for the input string:
- **
- ** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM
- ** DDDD.DD
- ** now
- **
- ** In the first form, the +/-HH:MM is always optional. The fractional
- ** seconds extension (the ".FFF") is optional. The seconds portion
- ** (":SS.FFF") is option. The year and date can be omitted as long
- ** as there is a time string. The time string can be omitted as long
- ** as there is a year and date.
- */
- static int parseDateOrTime(
- sqlite3_context *context,
- const char *zDate,
- DateTime *p
- ){
- double r;
- if( parseYyyyMmDd(zDate,p)==0 ){
- return 0;
- }else if( parseHhMmSs(zDate, p)==0 ){
- return 0;
- }else if( sqlite3StrICmp(zDate,"now")==0){
- return setDateTimeToCurrent(context, p);
- }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
- p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
- p->validJD = 1;
- return 0;
- }
- return 1;
- }
- /*
- ** Compute the Year, Month, and Day from the julian day number.
- */
- static void computeYMD(DateTime *p){
- int Z, A, B, C, D, E, X1;
- if( p->validYMD ) return;
- if( !p->validJD ){
- p->Y = 2000;
- p->M = 1;
- p->D = 1;
- }else{
- 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;
- 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;
- }
- p->validYMD = 1;
- }
- /*
- ** Compute the Hour, Minute, and Seconds from the julian day number.
- */
- static void computeHMS(DateTime *p){
- int s;
- if( p->validHMS ) return;
- computeJD(p);
- s = (int)((p->iJD + 43200000) % 86400000);
- p->s = s/1000.0;
- s = (int)p->s;
- p->s -= s;
- p->h = s/3600;
- s -= p->h*3600;
- p->m = s/60;
- p->s += s - p->m*60;
- p->validHMS = 1;
- }
- /*
- ** Compute both YMD and HMS
- */
- static void computeYMD_HMS(DateTime *p){
- computeYMD(p);
- computeHMS(p);
- }
- /*
- ** Clear the YMD and HMS and the TZ
- */
- static void clearYMD_HMS_TZ(DateTime *p){
- p->validYMD = 0;
- p->validHMS = 0;
- p->validTZ = 0;
- }
- /*
- ** On recent Windows platforms, the localtime_s() function is available
- ** as part of the "Secure CRT". It is essentially equivalent to
- ** localtime_r() available under most POSIX platforms, except that the
- ** order of the parameters is reversed.
- **
- ** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx.
- **
- ** If the user has not indicated to use localtime_r() or localtime_s()
- ** already, check for an MSVC build environment that provides
- ** localtime_s().
- */
- #if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \
- defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
- #define HAVE_LOCALTIME_S 1
- #endif
- #ifndef SQLITE_OMIT_LOCALTIME
- /*
- ** The following routine implements the rough equivalent of localtime_r()
- ** using whatever operating-system specific localtime facility that
- ** is available. This routine returns 0 on success and
- ** non-zero on any kind of error.
- **
- ** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
- ** routine will always fail.
- **
- ** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
- ** library function localtime_r() is used to assist in the calculation of
- ** local time.
- */
- static int osLocaltime(time_t *t, struct tm *pTm){
- int rc;
- #if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \
- && (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S)
- struct tm *pX;
- #if SQLITE_THREADSAFE>0
- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
- #endif
- sqlite3_mutex_enter(mutex);
- pX = localtime(t);
- #ifndef SQLITE_OMIT_BUILTIN_TEST
- if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
- #endif
- if( pX ) *pTm = *pX;
- sqlite3_mutex_leave(mutex);
- rc = pX==0;
- #else
- #ifndef SQLITE_OMIT_BUILTIN_TEST
- if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
- #endif
- #if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R
- rc = localtime_r(t, pTm)==0;
- #else
- rc = localtime_s(pTm, t);
- #endif /* HAVE_LOCALTIME_R */
- #endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */
- return rc;
- }
- #endif /* SQLITE_OMIT_LOCALTIME */
- #ifndef SQLITE_OMIT_LOCALTIME
- /*
- ** Compute the difference (in milliseconds) between localtime and UTC
- ** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs,
- ** return this value and set *pRc to SQLITE_OK.
- **
- ** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value
- ** is undefined in this case.
- */
- static sqlite3_int64 localtimeOffset(
- DateTime *p, /* Date at which to calculate offset */
- sqlite3_context *pCtx, /* Write error here if one occurs */
- int *pRc /* OUT: Error code. SQLITE_OK or ERROR */
- ){
- DateTime x, y;
- time_t t;
- struct tm sLocal;
- /* Initialize the contents of sLocal to avoid a compiler warning. */
- memset(&sLocal, 0, sizeof(sLocal));
- x = *p;
- computeYMD_HMS(&x);
- if( x.Y<1971 || x.Y>=2038 ){
- /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
- ** works for years between 1970 and 2037. For dates outside this range,
- ** SQLite attempts to map the year into an equivalent year within this
- ** range, do the calculation, then map the year back.
- */
- x.Y = 2000;
- x.M = 1;
- x.D = 1;
- x.h = 0;
- x.m = 0;
- x.s = 0.0;
- } else {
- int s = (int)(x.s + 0.5);
- x.s = s;
- }
- x.tz = 0;
- x.validJD = 0;
- computeJD(&x);
- t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
- if( osLocaltime(&t, &sLocal) ){
- sqlite3_result_error(pCtx, "local time unavailable", -1);
- *pRc = SQLITE_ERROR;
- return 0;
- }
- y.Y = sLocal.tm_year + 1900;
- y.M = sLocal.tm_mon + 1;
- y.D = sLocal.tm_mday;
- y.h = sLocal.tm_hour;
- y.m = sLocal.tm_min;
- y.s = sLocal.tm_sec;
- y.validYMD = 1;
- y.validHMS = 1;
- y.validJD = 0;
- y.validTZ = 0;
- computeJD(&y);
- *pRc = SQLITE_OK;
- return y.iJD - x.iJD;
- }
- #endif /* SQLITE_OMIT_LOCALTIME */
- /*
- ** Process a modifier to a date-time stamp. The modifiers are
- ** as follows:
- **
- ** NNN days
- ** NNN hours
- ** NNN minutes
- ** NNN.NNNN seconds
- ** NNN months
- ** NNN years
- ** start of month
- ** start of year
- ** start of week
- ** start of day
- ** weekday N
- ** unixepoch
- ** localtime
- ** utc
- **
- ** Return 0 on success and 1 if there is any kind of error. If the error
- ** is in a system call (i.e. localtime()), then an error message is written
- ** to context pCtx. If the error is an unrecognized modifier, no error is
- ** written to pCtx.
- */
- static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
- int rc = 1;
- int n;
- double r;
- char *z, zBuf[30];
- z = zBuf;
- for(n=0; n<ArraySize(zBuf)-1 && zMod[n]; n++){
- z[n] = (char)sqlite3UpperToLower[(u8)zMod[n]];
- }
- z[n] = 0;
- switch( z[0] ){
- #ifndef SQLITE_OMIT_LOCALTIME
- case 'l': {
- /* localtime
- **
- ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
- ** show local time.
- */
- if( strcmp(z, "localtime")==0 ){
- computeJD(p);
- p->iJD += localtimeOffset(p, pCtx, &rc);
- clearYMD_HMS_TZ(p);
- }
- 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 ){
- sqlite3_int64 c1;
- computeJD(p);
- c1 = localtimeOffset(p, pCtx, &rc);
- if( rc==SQLITE_OK ){
- p->iJD -= c1;
- clearYMD_HMS_TZ(p);
- p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
- }
- }
- #endif
- break;
- }
- case 'w': {
- /*
- ** weekday N
- **
- ** Move the date to the same time on the next occurrence of
- ** weekday N where 0==Sunday, 1==Monday, and so forth. If the
- ** date is already on the appropriate weekday, this is a no-op.
- */
- if( strncmp(z, "weekday ", 8)==0
- && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
- && (n=(int)r)==r && n>=0 && r<7 ){
- sqlite3_int64 Z;
- computeYMD_HMS(p);
- p->validTZ = 0;
- p->validJD = 0;
- computeJD(p);
- Z = ((p->iJD + 129600000)/86400000) % 7;
- if( Z>n ) Z -= 7;
- p->iJD += (n - Z)*86400000;
- clearYMD_HMS_TZ(p);
- rc = 0;
- }
- break;
- }
- case 's': {
- /*
- ** start of TTTTT
- **
- ** Move the date backwards to the beginning of the current day,
- ** or month or year.
- */
- if( strncmp(z, "start of ", 9)!=0 ) break;
- z += 9;
- computeYMD(p);
- p->validHMS = 1;
- p->h = p->m = 0;
- p->s = 0.0;
- p->validTZ = 0;
- p->validJD = 0;
- if( strcmp(z,"month")==0 ){
- p->D = 1;
- rc = 0;
- }else if( strcmp(z,"year")==0 ){
- computeYMD(p);
- p->M = 1;
- p->D = 1;
- rc = 0;
- }else if( strcmp(z,"day")==0 ){
- rc = 0;
- }
- break;
- }
- case '+':
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': {
- double rRounder;
- for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
- if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
- rc = 1;
- break;
- }
- if( z[n]==':' ){
- /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
- ** specified number of hours, minutes, seconds, and fractional seconds
- ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be
- ** omitted.
- */
- const char *z2 = z;
- DateTime tx;
- sqlite3_int64 day;
- if( !sqlite3Isdigit(*z2) ) z2++;
- memset(&tx, 0, sizeof(tx));
- if( parseHhMmSs(z2, &tx) ) break;
- computeJD(&tx);
- tx.iJD -= 43200000;
- day = tx.iJD/86400000;
- tx.iJD -= day*86400000;
- if( z[0]=='-' ) tx.iJD = -tx.iJD;
- computeJD(p);
- clearYMD_HMS_TZ(p);
- p->iJD += tx.iJD;
- rc = 0;
- break;
- }
- z += n;
- while( sqlite3Isspace(*z) ) z++;
- n = sqlite3Strlen30(z);
- if( n>10 || n<3 ) break;
- 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 + rRounder);
- }else if( n==4 && strcmp(z,"hour")==0 ){
- 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)) + rRounder);
- }else if( n==6 && strcmp(z,"second")==0 ){
- 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);
- p->M += (int)r;
- x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
- p->Y += x;
- p->M -= x*12;
- p->validJD = 0;
- computeJD(p);
- y = (int)r;
- if( y!=r ){
- 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 += y;
- p->validJD = 0;
- computeJD(p);
- if( y!=r ){
- p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder);
- }
- }else{
- rc = 1;
- }
- clearYMD_HMS_TZ(p);
- break;
- }
- default: {
- break;
- }
- }
- return rc;
- }
- /*
- ** Process time function arguments. argv[0] is a date-time stamp.
- ** argv[1] and following are modifiers. Parse them all and write
- ** the resulting time into the DateTime structure p. Return 0
- ** on success and 1 if there are any errors.
- **
- ** If there are zero parameters (if even argv[0] is undefined)
- ** then assume a default value of "now" for argv[0].
- */
- static int isDate(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv,
- DateTime *p
- ){
- int i;
- 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);
- p->validJD = 1;
- }else{
- z = sqlite3_value_text(argv[0]);
- if( !z || parseDateOrTime(context, (char*)z, p) ){
- return 1;
- }
- }
- for(i=1; i<argc; i++){
- z = sqlite3_value_text(argv[i]);
- if( z==0 || parseModifier(context, (char*)z, p) ) return 1;
- }
- return 0;
- }
- /*
- ** The following routines implement the various date and time functions
- ** of SQLite.
- */
- /*
- ** julianday( TIMESTRING, MOD, MOD, ...)
- **
- ** Return the julian day number of the date specified in the arguments
- */
- static void juliandayFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
- ){
- DateTime x;
- if( isDate(context, argc, argv, &x)==0 ){
- computeJD(&x);
- sqlite3_result_double(context, x.iJD/86400000.0);
- }
- }
- /*
- ** datetime( TIMESTRING, MOD, MOD, ...)
- **
- ** Return YYYY-MM-DD HH:MM:SS
- */
- static void datetimeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
- ){
- DateTime x;
- if( isDate(context, argc, argv, &x)==0 ){
- 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));
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
- }
- }
- /*
- ** time( TIMESTRING, MOD, MOD, ...)
- **
- ** Return HH:MM:SS
- */
- static void timeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
- ){
- DateTime x;
- if( isDate(context, argc, argv, &x)==0 ){
- char zBuf[100];
- computeHMS(&x);
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
- }
- }
- /*
- ** date( TIMESTRING, MOD, MOD, ...)
- **
- ** Return YYYY-MM-DD
- */
- static void dateFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
- ){
- DateTime x;
- if( isDate(context, argc, argv, &x)==0 ){
- char zBuf[100];
- computeYMD(&x);
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
- }
- }
- /*
- ** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
- **
- ** Return a string described by FORMAT. Conversions as follows:
- **
- ** %d day of month
- ** %f ** fractional seconds SS.SSS
- ** %H hour 00-24
- ** %j day of year 000-366
- ** %J ** Julian day number
- ** %m month 01-12
- ** %M minute 00-59
- ** %s seconds since 1970-01-01
- ** %S seconds 00-59
- ** %w day of week 0-6 sunday==0
- ** %W week of year 00-53
- ** %Y year 0000-9999
- ** %% %
- */
- static void strftimeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
- ){
- DateTime x;
- u64 n;
- size_t i,j;
- char *z;
- sqlite3 *db;
- const char *zFmt = (const char*)sqlite3_value_text(argv[0]);
- char zBuf[100];
- if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
- db = sqlite3_context_db_handle(context);
- for(i=0, n=1; zFmt[i]; i++, n++){
- if( zFmt[i]=='%' ){
- switch( zFmt[i+1] ){
- case 'd':
- case 'H':
- case 'm':
- case 'M':
- case 'S':
- case 'W':
- n++;
- /* fall thru */
- case 'w':
- case '%':
- break;
- case 'f':
- n += 8;
- break;
- case 'j':
- n += 3;
- break;
- case 'Y':
- n += 8;
- break;
- case 's':
- case 'J':
- n += 50;
- break;
- default:
- return; /* ERROR. return a NULL */
- }
- i++;
- }
- }
- testcase( n==sizeof(zBuf)-1 );
- testcase( n==sizeof(zBuf) );
- testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
- testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] );
- if( n<sizeof(zBuf) ){
- z = zBuf;
- }else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){
- sqlite3_result_error_toobig(context);
- return;
- }else{
- z = sqlite3DbMallocRaw(db, (int)n);
- if( z==0 ){
- sqlite3_result_error_nomem(context);
- return;
- }
- }
- computeJD(&x);
- computeYMD_HMS(&x);
- for(i=j=0; zFmt[i]; i++){
- if( zFmt[i]!='%' ){
- z[j++] = zFmt[i];
- }else{
- i++;
- switch( zFmt[i] ){
- case 'd': sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break;
- case 'f': {
- double s = x.s;
- if( s>59.999 ) s = 59.999;
- sqlite3_snprintf(7, &z[j],"%06.3f", s);
- j += sqlite3Strlen30(&z[j]);
- break;
- }
- case 'H': sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break;
- case 'W': /* Fall thru */
- case 'j': {
- int nDay; /* Number of days since 1st day of year */
- DateTime y = x;
- y.validJD = 0;
- y.M = 1;
- y.D = 1;
- computeJD(&y);
- nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
- if( zFmt[i]=='W' ){
- int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */
- wd = (int)(((x.iJD+43200000)/86400000)%7);
- sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7);
- j += 2;
- }else{
- sqlite3_snprintf(4, &z[j],"%03d",nDay+1);
- j += 3;
- }
- break;
- }
- case 'J': {
- sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0);
- j+=sqlite3Strlen30(&z[j]);
- break;
- }
- case 'm': sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break;
- case 'M': sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break;
- case 's': {
- sqlite3_snprintf(30,&z[j],"%lld",
- (i64)(x.iJD/1000 - 21086676*(i64)10000));
- j += sqlite3Strlen30(&z[j]);
- break;
- }
- case 'S': sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break;
- case 'w': {
- z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
- break;
- }
- case 'Y': {
- sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]);
- break;
- }
- default: z[j++] = '%'; break;
- }
- }
- }
- z[j] = 0;
- sqlite3_result_text(context, z, -1,
- z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC);
- }
- /*
- ** current_time()
- **
- ** This function returns the same value as time('now').
- */
- static void ctimeFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
- ){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- timeFunc(context, 0, 0);
- }
- /*
- ** current_date()
- **
- ** This function returns the same value as date('now').
- */
- static void cdateFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
- ){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- dateFunc(context, 0, 0);
- }
- /*
- ** current_timestamp()
- **
- ** This function returns the same value as datetime('now').
- */
- static void ctimestampFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
- ){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- datetimeFunc(context, 0, 0);
- }
- #endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */
- #ifdef SQLITE_OMIT_DATETIME_FUNCS
- /*
- ** If the library is compiled to omit the full-scale date and time
- ** handling (to get a smaller binary), the following minimal version
- ** of the functions current_time(), current_date() and current_timestamp()
- ** are included instead. This is to support column declarations that
- ** include "DEFAULT CURRENT_TIME" etc.
- **
- ** This function uses the C-library functions time(), gmtime()
- ** and strftime(). The format string to pass to strftime() is supplied
- ** as the user-data for the function.
- */
- static void currentTimeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
- ){
- time_t t;
- char *zFormat = (char *)sqlite3_user_data(context);
- sqlite3 *db;
- sqlite3_int64 iT;
- struct tm *pTm;
- struct tm sNow;
- char zBuf[20];
- UNUSED_PARAMETER(argc);
- UNUSED_PARAMETER(argv);
- iT = sqlite3StmtCurrentTime(context);
- if( iT<=0 ) return;
- t = iT/1000 - 10000*(sqlite3_int64)21086676;
- #ifdef HAVE_GMTIME_R
- pTm = gmtime_r(&t, &sNow);
- #else
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
- pTm = gmtime(&t);
- if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
- #endif
- if( pTm ){
- strftime(zBuf, 20, zFormat, &sNow);
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
- }
- }
- #endif
- /*
- ** This function registered all of the above C functions as SQL
- ** functions. This should be the only routine in this file with
- ** external linkage.
- */
- void sqlite3RegisterDateTimeFunctions(void){
- static SQLITE_WSD FuncDef aDateTimeFuncs[] = {
- #ifndef SQLITE_OMIT_DATETIME_FUNCS
- FUNCTION(julianday, -1, 0, 0, juliandayFunc ),
- FUNCTION(date, -1, 0, 0, dateFunc ),
- FUNCTION(time, -1, 0, 0, timeFunc ),
- FUNCTION(datetime, -1, 0, 0, datetimeFunc ),
- FUNCTION(strftime, -1, 0, 0, strftimeFunc ),
- FUNCTION(current_time, 0, 0, 0, ctimeFunc ),
- FUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
- FUNCTION(current_date, 0, 0, 0, cdateFunc ),
- #else
- STR_FUNCTION(current_time, 0, "%H:%M:%S", 0, currentTimeFunc),
- STR_FUNCTION(current_date, 0, "%Y-%m-%d", 0, currentTimeFunc),
- STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
- #endif
- };
- int i;
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs);
- for(i=0; i<ArraySize(aDateTimeFuncs); i++){
- sqlite3FuncDefInsert(pHash, &aFunc[i]);
- }
- }
|