17014aff3Sdrh /*
27014aff3Sdrh ** 2003 October 31
37014aff3Sdrh **
47014aff3Sdrh ** The author disclaims copyright to this source code. In place of
57014aff3Sdrh ** a legal notice, here is a blessing:
67014aff3Sdrh **
77014aff3Sdrh ** May you do good and not evil.
87014aff3Sdrh ** May you find forgiveness for yourself and forgive others.
97014aff3Sdrh ** May you share freely, never taking more than you give.
107014aff3Sdrh **
117014aff3Sdrh *************************************************************************
127014aff3Sdrh ** This file contains the C functions that implement date and time
137014aff3Sdrh ** functions for SQLite.
147014aff3Sdrh **
157014aff3Sdrh ** There is only one exported symbol in this file - the function
164adee20fSdanielk1977 ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
177014aff3Sdrh ** All other code has file scope.
187014aff3Sdrh **
1986a11b8aSdrh ** SQLite processes all times and dates as julian day numbers. The
207014aff3Sdrh ** dates and times are stored as the number of days since noon
217014aff3Sdrh ** in Greenwich on November 24, 4714 B.C. according to the Gregorian
227014aff3Sdrh ** calendar system.
237014aff3Sdrh **
247014aff3Sdrh ** 1970-01-01 00:00:00 is JD 2440587.5
257014aff3Sdrh ** 2000-01-01 00:00:00 is JD 2451544.5
267014aff3Sdrh **
2760ec914cSpeter.d.reid ** This implementation requires years to be expressed as a 4-digit number
287014aff3Sdrh ** which means that only dates between 0000-01-01 and 9999-12-31 can
297014aff3Sdrh ** be represented, even though julian day numbers allow a much wider
307014aff3Sdrh ** range of dates.
317014aff3Sdrh **
327014aff3Sdrh ** The Gregorian calendar system is used for all dates and times,
337014aff3Sdrh ** even those that predate the Gregorian calendar. Historians usually
3486a11b8aSdrh ** use the julian calendar for dates prior to 1582-10-15 and for some
357014aff3Sdrh ** dates afterwards, depending on locale. Beware of this difference.
367014aff3Sdrh **
377014aff3Sdrh ** The conversion algorithms are implemented based on descriptions
387014aff3Sdrh ** in the following text:
397014aff3Sdrh **
407014aff3Sdrh ** Jean Meeus
417014aff3Sdrh ** Astronomical Algorithms, 2nd Edition, 1998
42a0951d87Smistachkin ** ISBN 0-943396-61-1
437014aff3Sdrh ** Willmann-Bell, Inc
447014aff3Sdrh ** Richmond, Virginia (USA)
457014aff3Sdrh */
46ae53418dSdougcurrie #include "sqliteInt.h"
477014aff3Sdrh #include <stdlib.h>
487014aff3Sdrh #include <assert.h>
497091cb05Sdrh #include <time.h>
507014aff3Sdrh
514bc05859Sdrh #ifndef SQLITE_OMIT_DATETIME_FUNCS
524bc05859Sdrh
530cedb963Smistachkin /*
548366ddf2Smistachkin ** The MSVC CRT on Windows CE may not have a localtime() function.
558366ddf2Smistachkin ** So declare a substitute. The substitute function itself is
568366ddf2Smistachkin ** defined in "os_win.c".
570cedb963Smistachkin */
580cedb963Smistachkin #if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
590cedb963Smistachkin (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
600cedb963Smistachkin struct tm *__cdecl localtime(const time_t *);
610cedb963Smistachkin #endif
62b8109ad3Sshane
63b8109ad3Sshane /*
647014aff3Sdrh ** A structure for holding a single date and time.
657014aff3Sdrh */
667014aff3Sdrh typedef struct DateTime DateTime;
677014aff3Sdrh struct DateTime {
68b5489b88Sdrh sqlite3_int64 iJD; /* The julian day number times 86400000 */
697014aff3Sdrh int Y, M, D; /* Year, month, and day */
707014aff3Sdrh int h, m; /* Hour and minutes */
717014aff3Sdrh int tz; /* Timezone offset in minutes */
727014aff3Sdrh double s; /* Seconds */
73861a5682Sdrh char validJD; /* True (1) if iJD is valid */
74861a5682Sdrh char rawS; /* Raw numeric value stored in s */
75aef3af54Sshane char validYMD; /* True (1) if Y,M,D are valid */
76aef3af54Sshane char validHMS; /* True (1) if h,m,s are valid */
77aef3af54Sshane char validTZ; /* True (1) if tz is valid */
78caeca516Sdrh char tzSet; /* Timezone was set explicitly */
793edb157eSdrh char isError; /* An overflow has occurred */
807014aff3Sdrh };
817014aff3Sdrh
827014aff3Sdrh
837014aff3Sdrh /*
843349620eSdrh ** Convert zDate into one or more integers according to the conversion
853349620eSdrh ** specifier zFormat.
86eb9a9e88Sdrh **
873349620eSdrh ** zFormat[] contains 4 characters for each integer converted, except for
883349620eSdrh ** the last integer which is specified by three characters. The meaning
893349620eSdrh ** of a four-character format specifiers ABCD is:
90eb9a9e88Sdrh **
913349620eSdrh ** A: number of digits to convert. Always "2" or "4".
923349620eSdrh ** B: minimum value. Always "0" or "1".
933349620eSdrh ** C: maximum value, decoded as:
943349620eSdrh ** a: 12
953349620eSdrh ** b: 14
963349620eSdrh ** c: 24
973349620eSdrh ** d: 31
983349620eSdrh ** e: 59
993349620eSdrh ** f: 9999
1003349620eSdrh ** D: the separator character, or \000 to indicate this is the
1013349620eSdrh ** last number to convert.
1023349620eSdrh **
1033349620eSdrh ** Example: To translate an ISO-8601 date YYYY-MM-DD, the format would
1043349620eSdrh ** be "40f-21a-20c". The "40f-" indicates the 4-digit year followed by "-".
1053349620eSdrh ** The "21a-" indicates the 2-digit month followed by "-". The "20c" indicates
1063349620eSdrh ** the 2-digit day which is the last integer in the set.
1073349620eSdrh **
108eb9a9e88Sdrh ** The function returns the number of successful conversions.
1097014aff3Sdrh */
getDigits(const char * zDate,const char * zFormat,...)1103349620eSdrh static int getDigits(const char *zDate, const char *zFormat, ...){
1113349620eSdrh /* The aMx[] array translates the 3rd character of each format
1123349620eSdrh ** spec into a max size: a b c d e f */
1133349620eSdrh static const u16 aMx[] = { 12, 14, 24, 31, 59, 9999 };
114eb9a9e88Sdrh va_list ap;
115eb9a9e88Sdrh int cnt = 0;
1163349620eSdrh char nextC;
1173349620eSdrh va_start(ap, zFormat);
118eb9a9e88Sdrh do{
1193349620eSdrh char N = zFormat[0] - '0';
1203349620eSdrh char min = zFormat[1] - '0';
1213349620eSdrh int val = 0;
1223349620eSdrh u16 max;
1233349620eSdrh
1243349620eSdrh assert( zFormat[2]>='a' && zFormat[2]<='f' );
1253349620eSdrh max = aMx[zFormat[2] - 'a'];
1263349620eSdrh nextC = zFormat[3];
127eb9a9e88Sdrh val = 0;
1287014aff3Sdrh while( N-- ){
12978ca0e7eSdanielk1977 if( !sqlite3Isdigit(*zDate) ){
130029b44bdSdrh goto end_getDigits;
131eb9a9e88Sdrh }
1327014aff3Sdrh val = val*10 + *zDate - '0';
1337014aff3Sdrh zDate++;
1347014aff3Sdrh }
1353349620eSdrh if( val<(int)min || val>(int)max || (nextC!=0 && nextC!=*zDate) ){
136029b44bdSdrh goto end_getDigits;
137eb9a9e88Sdrh }
1383349620eSdrh *va_arg(ap,int*) = val;
139eb9a9e88Sdrh zDate++;
140eb9a9e88Sdrh cnt++;
1413349620eSdrh zFormat += 4;
142eb9a9e88Sdrh }while( nextC );
143029b44bdSdrh end_getDigits:
14415b9a15aSdrh va_end(ap);
145eb9a9e88Sdrh return cnt;
1467014aff3Sdrh }
1477014aff3Sdrh
1487014aff3Sdrh /*
1497014aff3Sdrh ** Parse a timezone extension on the end of a date-time.
1507014aff3Sdrh ** The extension is of the form:
1517014aff3Sdrh **
1527014aff3Sdrh ** (+/-)HH:MM
1537014aff3Sdrh **
1541cfdc90bSdrh ** Or the "zulu" notation:
1551cfdc90bSdrh **
1561cfdc90bSdrh ** Z
1571cfdc90bSdrh **
1587014aff3Sdrh ** If the parse is successful, write the number of minutes
1591cfdc90bSdrh ** of change in p->tz and return 0. If a parser error occurs,
1601cfdc90bSdrh ** return non-zero.
1617014aff3Sdrh **
1627014aff3Sdrh ** A missing specifier is not considered an error.
1637014aff3Sdrh */
parseTimezone(const char * zDate,DateTime * p)1647014aff3Sdrh static int parseTimezone(const char *zDate, DateTime *p){
1657014aff3Sdrh int sgn = 0;
1667014aff3Sdrh int nHr, nMn;
1671cfdc90bSdrh int c;
16878ca0e7eSdanielk1977 while( sqlite3Isspace(*zDate) ){ zDate++; }
1697014aff3Sdrh p->tz = 0;
1701cfdc90bSdrh c = *zDate;
1711cfdc90bSdrh if( c=='-' ){
1727014aff3Sdrh sgn = -1;
1731cfdc90bSdrh }else if( c=='+' ){
1747014aff3Sdrh sgn = +1;
1751cfdc90bSdrh }else if( c=='Z' || c=='z' ){
1761cfdc90bSdrh zDate++;
1771cfdc90bSdrh goto zulu_time;
1787014aff3Sdrh }else{
1791cfdc90bSdrh return c!=0;
1807014aff3Sdrh }
1817014aff3Sdrh zDate++;
1823349620eSdrh if( getDigits(zDate, "20b:20e", &nHr, &nMn)!=2 ){
183eb9a9e88Sdrh return 1;
184eb9a9e88Sdrh }
185eb9a9e88Sdrh zDate += 5;
1867014aff3Sdrh p->tz = sgn*(nMn + nHr*60);
1871cfdc90bSdrh zulu_time:
18878ca0e7eSdanielk1977 while( sqlite3Isspace(*zDate) ){ zDate++; }
189caeca516Sdrh p->tzSet = 1;
1907014aff3Sdrh return *zDate!=0;
1917014aff3Sdrh }
1927014aff3Sdrh
1937014aff3Sdrh /*
1947014aff3Sdrh ** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
1957014aff3Sdrh ** The HH, MM, and SS must each be exactly 2 digits. The
1967014aff3Sdrh ** fractional seconds FFFF can be one or more digits.
1977014aff3Sdrh **
1987014aff3Sdrh ** Return 1 if there is a parsing error and 0 on success.
1997014aff3Sdrh */
parseHhMmSs(const char * zDate,DateTime * p)2007014aff3Sdrh static int parseHhMmSs(const char *zDate, DateTime *p){
2017014aff3Sdrh int h, m, s;
2027014aff3Sdrh double ms = 0.0;
2033349620eSdrh if( getDigits(zDate, "20c:20e", &h, &m)!=2 ){
204eb9a9e88Sdrh return 1;
205eb9a9e88Sdrh }
206eb9a9e88Sdrh zDate += 5;
2077014aff3Sdrh if( *zDate==':' ){
208eb9a9e88Sdrh zDate++;
2093349620eSdrh if( getDigits(zDate, "20e", &s)!=1 ){
210eb9a9e88Sdrh return 1;
211eb9a9e88Sdrh }
212eb9a9e88Sdrh zDate += 2;
21378ca0e7eSdanielk1977 if( *zDate=='.' && sqlite3Isdigit(zDate[1]) ){
2147014aff3Sdrh double rScale = 1.0;
2157014aff3Sdrh zDate++;
21678ca0e7eSdanielk1977 while( sqlite3Isdigit(*zDate) ){
2177014aff3Sdrh ms = ms*10.0 + *zDate - '0';
2187014aff3Sdrh rScale *= 10.0;
2197014aff3Sdrh zDate++;
2207014aff3Sdrh }
2217014aff3Sdrh ms /= rScale;
2227014aff3Sdrh }
2237014aff3Sdrh }else{
2247014aff3Sdrh s = 0;
2257014aff3Sdrh }
2267014aff3Sdrh p->validJD = 0;
227861a5682Sdrh p->rawS = 0;
2287014aff3Sdrh p->validHMS = 1;
2297014aff3Sdrh p->h = h;
2307014aff3Sdrh p->m = m;
2317014aff3Sdrh p->s = s + ms;
2327014aff3Sdrh if( parseTimezone(zDate, p) ) return 1;
233aef3af54Sshane p->validTZ = (p->tz!=0)?1:0;
2347014aff3Sdrh return 0;
2357014aff3Sdrh }
2367014aff3Sdrh
2377014aff3Sdrh /*
238d76a902cSdrh ** Put the DateTime object into its error state.
239d76a902cSdrh */
datetimeError(DateTime * p)240d76a902cSdrh static void datetimeError(DateTime *p){
241d76a902cSdrh memset(p, 0, sizeof(*p));
242d76a902cSdrh p->isError = 1;
243d76a902cSdrh }
244d76a902cSdrh
245d76a902cSdrh /*
2467014aff3Sdrh ** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume
2477014aff3Sdrh ** that the YYYY-MM-DD is according to the Gregorian calendar.
2487014aff3Sdrh **
2497014aff3Sdrh ** Reference: Meeus page 61
2507014aff3Sdrh */
computeJD(DateTime * p)2517014aff3Sdrh static void computeJD(DateTime *p){
2527014aff3Sdrh int Y, M, D, A, B, X1, X2;
2537014aff3Sdrh
2547014aff3Sdrh if( p->validJD ) return;
2557014aff3Sdrh if( p->validYMD ){
2567014aff3Sdrh Y = p->Y;
2577014aff3Sdrh M = p->M;
2587014aff3Sdrh D = p->D;
2597014aff3Sdrh }else{
260ba21256fSdrh Y = 2000; /* If no YMD specified, assume 2000-Jan-01 */
2617014aff3Sdrh M = 1;
2627014aff3Sdrh D = 1;
2637014aff3Sdrh }
264861a5682Sdrh if( Y<-4713 || Y>9999 || p->rawS ){
265d76a902cSdrh datetimeError(p);
266d76a902cSdrh return;
267d76a902cSdrh }
2687014aff3Sdrh if( M<=2 ){
2697014aff3Sdrh Y--;
2707014aff3Sdrh M += 12;
2717014aff3Sdrh }
2727014aff3Sdrh A = Y/100;
2737014aff3Sdrh B = 2 - A + (A/4);
274aef3af54Sshane X1 = 36525*(Y+4716)/100;
275aef3af54Sshane X2 = 306001*(M+1)/10000;
276aef3af54Sshane p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000);
2777014aff3Sdrh p->validJD = 1;
2787014aff3Sdrh if( p->validHMS ){
279a5cc6924Slarrybr p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5);
2807014aff3Sdrh if( p->validTZ ){
28185f477a1Sdrh p->iJD -= p->tz*60000;
282f11c34dfSdrh p->validYMD = 0;
2837014aff3Sdrh p->validHMS = 0;
2847014aff3Sdrh p->validTZ = 0;
2857014aff3Sdrh }
2867014aff3Sdrh }
2877014aff3Sdrh }
2887014aff3Sdrh
2897014aff3Sdrh /*
2907014aff3Sdrh ** Parse dates of the form
2917014aff3Sdrh **
2927014aff3Sdrh ** YYYY-MM-DD HH:MM:SS.FFF
2937014aff3Sdrh ** YYYY-MM-DD HH:MM:SS
2947014aff3Sdrh ** YYYY-MM-DD HH:MM
2957014aff3Sdrh ** YYYY-MM-DD
2967014aff3Sdrh **
2977014aff3Sdrh ** Write the result into the DateTime structure and return 0
2987014aff3Sdrh ** on success and 1 if the input string is not a well-formed
2997014aff3Sdrh ** date.
3007014aff3Sdrh */
parseYyyyMmDd(const char * zDate,DateTime * p)3017014aff3Sdrh static int parseYyyyMmDd(const char *zDate, DateTime *p){
3028eb2cce5Sdrh int Y, M, D, neg;
3037014aff3Sdrh
3048eb2cce5Sdrh if( zDate[0]=='-' ){
3058eb2cce5Sdrh zDate++;
3068eb2cce5Sdrh neg = 1;
3078eb2cce5Sdrh }else{
3088eb2cce5Sdrh neg = 0;
3098eb2cce5Sdrh }
3103349620eSdrh if( getDigits(zDate, "40f-21a-21d", &Y, &M, &D)!=3 ){
311eb9a9e88Sdrh return 1;
312eb9a9e88Sdrh }
313eb9a9e88Sdrh zDate += 10;
31478ca0e7eSdanielk1977 while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; }
315eb9a9e88Sdrh if( parseHhMmSs(zDate, p)==0 ){
316eb9a9e88Sdrh /* We got the time */
3177014aff3Sdrh }else if( *zDate==0 ){
3187014aff3Sdrh p->validHMS = 0;
3197014aff3Sdrh }else{
3207014aff3Sdrh return 1;
3217014aff3Sdrh }
3227014aff3Sdrh p->validJD = 0;
3237014aff3Sdrh p->validYMD = 1;
3248eb2cce5Sdrh p->Y = neg ? -Y : Y;
3257014aff3Sdrh p->M = M;
3267014aff3Sdrh p->D = D;
3277014aff3Sdrh if( p->validTZ ){
3287014aff3Sdrh computeJD(p);
3297014aff3Sdrh }
3307014aff3Sdrh return 0;
3317014aff3Sdrh }
3327014aff3Sdrh
3337014aff3Sdrh /*
3343170225fSdrh ** Set the time to the current time reported by the VFS.
3353170225fSdrh **
3363170225fSdrh ** Return the number of errors.
3373af5d685Sdrh */
setDateTimeToCurrent(sqlite3_context * context,DateTime * p)3383170225fSdrh static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
33995a7b3e3Sdrh p->iJD = sqlite3StmtCurrentTime(context);
34095a7b3e3Sdrh if( p->iJD>0 ){
3413af5d685Sdrh p->validJD = 1;
3423170225fSdrh return 0;
3433170225fSdrh }else{
3443170225fSdrh return 1;
3453170225fSdrh }
3463af5d685Sdrh }
3473af5d685Sdrh
3483af5d685Sdrh /*
349861a5682Sdrh ** Input "r" is a numeric quantity which might be a julian day number,
350861a5682Sdrh ** or the number of seconds since 1970. If the value if r is within
351861a5682Sdrh ** range of a julian day number, install it as such and set validJD.
352861a5682Sdrh ** If the value is a valid unix timestamp, put it in p->s and set p->rawS.
353861a5682Sdrh */
setRawDateNumber(DateTime * p,double r)354861a5682Sdrh static void setRawDateNumber(DateTime *p, double r){
355861a5682Sdrh p->s = r;
356861a5682Sdrh p->rawS = 1;
357861a5682Sdrh if( r>=0.0 && r<5373484.5 ){
358861a5682Sdrh p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
359861a5682Sdrh p->validJD = 1;
360861a5682Sdrh }
361861a5682Sdrh }
362861a5682Sdrh
363861a5682Sdrh /*
36486a11b8aSdrh ** Attempt to parse the given string into a julian day number. Return
3657014aff3Sdrh ** the number of errors.
3667014aff3Sdrh **
3677014aff3Sdrh ** The following are acceptable forms for the input string:
3687014aff3Sdrh **
3697014aff3Sdrh ** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM
3707014aff3Sdrh ** DDDD.DD
3717014aff3Sdrh ** now
3727014aff3Sdrh **
3737014aff3Sdrh ** In the first form, the +/-HH:MM is always optional. The fractional
3747014aff3Sdrh ** seconds extension (the ".FFF") is optional. The seconds portion
3757014aff3Sdrh ** (":SS.FFF") is option. The year and date can be omitted as long
3767014aff3Sdrh ** as there is a time string. The time string can be omitted as long
3777014aff3Sdrh ** as there is a year and date.
3787014aff3Sdrh */
parseDateOrTime(sqlite3_context * context,const char * zDate,DateTime * p)379fee2d25aSdanielk1977 static int parseDateOrTime(
380fee2d25aSdanielk1977 sqlite3_context *context,
381fee2d25aSdanielk1977 const char *zDate,
382fee2d25aSdanielk1977 DateTime *p
383fee2d25aSdanielk1977 ){
3849339da1fSdrh double r;
3858eb2cce5Sdrh if( parseYyyyMmDd(zDate,p)==0 ){
3867014aff3Sdrh return 0;
3878eb2cce5Sdrh }else if( parseHhMmSs(zDate, p)==0 ){
3888eb2cce5Sdrh return 0;
3896e97f8ecSdrh }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){
3903170225fSdrh return setDateTimeToCurrent(context, p);
3919a278229Sdrh }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){
392861a5682Sdrh setRawDateNumber(p, r);
3937014aff3Sdrh return 0;
3947014aff3Sdrh }
3957014aff3Sdrh return 1;
3967014aff3Sdrh }
3977014aff3Sdrh
398fb4e3a3bSdrh /* The julian day number for 9999-12-31 23:59:59.999 is 5373484.4999999.
399fb4e3a3bSdrh ** Multiplying this by 86400000 gives 464269060799999 as the maximum value
400fb4e3a3bSdrh ** for DateTime.iJD.
401fb4e3a3bSdrh **
402fb4e3a3bSdrh ** But some older compilers (ex: gcc 4.2.1 on older Macs) cannot deal with
403fb4e3a3bSdrh ** such a large integer literal, so we have to encode it.
404fb4e3a3bSdrh */
405fb4e3a3bSdrh #define INT_464269060799999 ((((i64)0x1a640)<<32)|0x1072fdff)
406fb4e3a3bSdrh
4077014aff3Sdrh /*
4083edb157eSdrh ** Return TRUE if the given julian day number is within range.
4093edb157eSdrh **
4103edb157eSdrh ** The input is the JulianDay times 86400000.
4113edb157eSdrh */
validJulianDay(sqlite3_int64 iJD)4123edb157eSdrh static int validJulianDay(sqlite3_int64 iJD){
413fb4e3a3bSdrh return iJD>=0 && iJD<=INT_464269060799999;
4143edb157eSdrh }
4153edb157eSdrh
4163edb157eSdrh /*
4177014aff3Sdrh ** Compute the Year, Month, and Day from the julian day number.
4187014aff3Sdrh */
computeYMD(DateTime * p)4197014aff3Sdrh static void computeYMD(DateTime *p){
4207014aff3Sdrh int Z, A, B, C, D, E, X1;
4217014aff3Sdrh if( p->validYMD ) return;
42233a9ad2fSdrh if( !p->validJD ){
42333a9ad2fSdrh p->Y = 2000;
42433a9ad2fSdrh p->M = 1;
42533a9ad2fSdrh p->D = 1;
4260c3233beSdrh }else if( !validJulianDay(p->iJD) ){
4270c3233beSdrh datetimeError(p);
4280c3233beSdrh return;
42933a9ad2fSdrh }else{
430aef3af54Sshane Z = (int)((p->iJD + 43200000)/86400000);
431aef3af54Sshane A = (int)((Z - 1867216.25)/36524.25);
4327014aff3Sdrh A = Z + 1 + A - (A/4);
4337014aff3Sdrh B = A + 1524;
434aef3af54Sshane C = (int)((B - 122.1)/365.25);
435618ee61eSdrh D = (36525*(C&32767))/100;
436aef3af54Sshane E = (int)((B-D)/30.6001);
437aef3af54Sshane X1 = (int)(30.6001*E);
4387014aff3Sdrh p->D = B - D - X1;
4397014aff3Sdrh p->M = E<14 ? E-1 : E-13;
4407014aff3Sdrh p->Y = p->M>2 ? C - 4716 : C - 4715;
44133a9ad2fSdrh }
4427014aff3Sdrh p->validYMD = 1;
4437014aff3Sdrh }
4447014aff3Sdrh
4457014aff3Sdrh /*
4467014aff3Sdrh ** Compute the Hour, Minute, and Seconds from the julian day number.
4477014aff3Sdrh */
computeHMS(DateTime * p)4487014aff3Sdrh static void computeHMS(DateTime *p){
44985f477a1Sdrh int s;
4507014aff3Sdrh if( p->validHMS ) return;
451f11c34dfSdrh computeJD(p);
452aef3af54Sshane s = (int)((p->iJD + 43200000) % 86400000);
45385f477a1Sdrh p->s = s/1000.0;
454aef3af54Sshane s = (int)p->s;
4557014aff3Sdrh p->s -= s;
4567014aff3Sdrh p->h = s/3600;
4577014aff3Sdrh s -= p->h*3600;
4587014aff3Sdrh p->m = s/60;
4597014aff3Sdrh p->s += s - p->m*60;
460861a5682Sdrh p->rawS = 0;
4617014aff3Sdrh p->validHMS = 1;
4627014aff3Sdrh }
4637014aff3Sdrh
4647014aff3Sdrh /*
465ba21256fSdrh ** Compute both YMD and HMS
466ba21256fSdrh */
computeYMD_HMS(DateTime * p)467ba21256fSdrh static void computeYMD_HMS(DateTime *p){
468ba21256fSdrh computeYMD(p);
469ba21256fSdrh computeHMS(p);
470ba21256fSdrh }
471ba21256fSdrh
472ba21256fSdrh /*
473ba21256fSdrh ** Clear the YMD and HMS and the TZ
474ba21256fSdrh */
clearYMD_HMS_TZ(DateTime * p)475ba21256fSdrh static void clearYMD_HMS_TZ(DateTime *p){
476ba21256fSdrh p->validYMD = 0;
477ba21256fSdrh p->validHMS = 0;
478ba21256fSdrh p->validTZ = 0;
479ba21256fSdrh }
480ba21256fSdrh
4816cc16fc0Smistachkin #ifndef SQLITE_OMIT_LOCALTIME
482a924acadSdrh /*
483a924acadSdrh ** On recent Windows platforms, the localtime_s() function is available
484a924acadSdrh ** as part of the "Secure CRT". It is essentially equivalent to
485a924acadSdrh ** localtime_r() available under most POSIX platforms, except that the
486a924acadSdrh ** order of the parameters is reversed.
487a924acadSdrh **
488a924acadSdrh ** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx.
489a924acadSdrh **
490a924acadSdrh ** If the user has not indicated to use localtime_r() or localtime_s()
491a924acadSdrh ** already, check for an MSVC build environment that provides
492a924acadSdrh ** localtime_s().
493a924acadSdrh */
4940ede9ebeSdrh #if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S \
4950ede9ebeSdrh && defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
4960ede9ebeSdrh #undef HAVE_LOCALTIME_S
497a924acadSdrh #define HAVE_LOCALTIME_S 1
498a924acadSdrh #endif
499a924acadSdrh
500ba21256fSdrh /*
5018720aeb5Sdrh ** The following routine implements the rough equivalent of localtime_r()
5028720aeb5Sdrh ** using whatever operating-system specific localtime facility that
5038720aeb5Sdrh ** is available. This routine returns 0 on success and
5048720aeb5Sdrh ** non-zero on any kind of error.
505c17d696cSdan **
506d7e185ceSdrh ** If the sqlite3GlobalConfig.bLocaltimeFault variable is non-zero then this
507d7e185ceSdrh ** routine will always fail. If bLocaltimeFault is nonzero and
508d7e185ceSdrh ** sqlite3GlobalConfig.xAltLocaltime is not NULL, then xAltLocaltime() is
509d7e185ceSdrh ** invoked in place of the OS-defined localtime() function.
510e4bf4f08Sdrh **
511e4bf4f08Sdrh ** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
512e4bf4f08Sdrh ** library function localtime_r() is used to assist in the calculation of
513e4bf4f08Sdrh ** local time.
5147091cb05Sdrh */
osLocaltime(time_t * t,struct tm * pTm)5151f93a080Sdrh static int osLocaltime(time_t *t, struct tm *pTm){
5168720aeb5Sdrh int rc;
5170ede9ebeSdrh #if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S
5188720aeb5Sdrh struct tm *pX;
519df3aa16eSdrh #if SQLITE_THREADSAFE>0
520ccb2113aSdrh sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
521df3aa16eSdrh #endif
5228720aeb5Sdrh sqlite3_mutex_enter(mutex);
5238720aeb5Sdrh pX = localtime(t);
524d12602a9Sdrh #ifndef SQLITE_UNTESTABLE
525d7e185ceSdrh if( sqlite3GlobalConfig.bLocaltimeFault ){
526b30af022Sdrh if( sqlite3GlobalConfig.xAltLocaltime!=0
527b30af022Sdrh && 0==sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm)
528b30af022Sdrh ){
529b30af022Sdrh pX = pTm;
530d7e185ceSdrh }else{
531d7e185ceSdrh pX = 0;
532d7e185ceSdrh }
533d7e185ceSdrh }
534a924acadSdrh #endif
5358720aeb5Sdrh if( pX ) *pTm = *pX;
536969c4648Slarrybr #if SQLITE_THREADSAFE>0
5378720aeb5Sdrh sqlite3_mutex_leave(mutex);
538969c4648Slarrybr #endif
5398720aeb5Sdrh rc = pX==0;
540a924acadSdrh #else
541d12602a9Sdrh #ifndef SQLITE_UNTESTABLE
542d7e185ceSdrh if( sqlite3GlobalConfig.bLocaltimeFault ){
543d7e185ceSdrh if( sqlite3GlobalConfig.xAltLocaltime!=0 ){
544d7e185ceSdrh return sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm);
545d7e185ceSdrh }else{
546d7e185ceSdrh return 1;
547d7e185ceSdrh }
548d7e185ceSdrh }
549c17d696cSdan #endif
5500ede9ebeSdrh #if HAVE_LOCALTIME_R
551a924acadSdrh rc = localtime_r(t, pTm)==0;
552a924acadSdrh #else
553a924acadSdrh rc = localtime_s(pTm, t);
554a924acadSdrh #endif /* HAVE_LOCALTIME_R */
555a924acadSdrh #endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */
5568720aeb5Sdrh return rc;
5578720aeb5Sdrh }
5588720aeb5Sdrh #endif /* SQLITE_OMIT_LOCALTIME */
559c17d696cSdan
560c17d696cSdan
5618720aeb5Sdrh #ifndef SQLITE_OMIT_LOCALTIME
562c17d696cSdan /*
563eadccaa9Sdrh ** Assuming the input DateTime is UTC, move it to its localtime equivalent.
564c17d696cSdan */
toLocaltime(DateTime * p,sqlite3_context * pCtx)565eadccaa9Sdrh static int toLocaltime(
566c17d696cSdan DateTime *p, /* Date at which to calculate offset */
567eadccaa9Sdrh sqlite3_context *pCtx /* Write error here if one occurs */
568c17d696cSdan ){
5697091cb05Sdrh time_t t;
5708720aeb5Sdrh struct tm sLocal;
571eadccaa9Sdrh int iYearDiff;
5728720aeb5Sdrh
5730d37f581Sdan /* Initialize the contents of sLocal to avoid a compiler warning. */
5740d37f581Sdan memset(&sLocal, 0, sizeof(sLocal));
5750d37f581Sdan
576eadccaa9Sdrh computeJD(p);
57716f56e84Sdrh if( p->iJD<2108667600*(i64)100000 /* 1970-01-01 */
57816f56e84Sdrh || p->iJD>2130141456*(i64)100000 /* 2038-01-18 */
579eadccaa9Sdrh ){
580e4bf4f08Sdrh /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
581e4bf4f08Sdrh ** works for years between 1970 and 2037. For dates outside this range,
582e4bf4f08Sdrh ** SQLite attempts to map the year into an equivalent year within this
583e4bf4f08Sdrh ** range, do the calculation, then map the year back.
584e4bf4f08Sdrh */
585eadccaa9Sdrh DateTime x = *p;
586eadccaa9Sdrh computeYMD_HMS(&x);
587eadccaa9Sdrh iYearDiff = (2000 + x.Y%4) - x.Y;
588eadccaa9Sdrh x.Y += iYearDiff;
5897091cb05Sdrh x.validJD = 0;
5907091cb05Sdrh computeJD(&x);
59111bb41f8Sshane t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
592eadccaa9Sdrh }else{
593eadccaa9Sdrh iYearDiff = 0;
594eadccaa9Sdrh t = (time_t)(p->iJD/1000 - 21086676*(i64)10000);
595eadccaa9Sdrh }
5968720aeb5Sdrh if( osLocaltime(&t, &sLocal) ){
5977c8b355eSdan sqlite3_result_error(pCtx, "local time unavailable", -1);
598eadccaa9Sdrh return SQLITE_ERROR;
599c17d696cSdan }
600eadccaa9Sdrh p->Y = sLocal.tm_year + 1900 - iYearDiff;
601eadccaa9Sdrh p->M = sLocal.tm_mon + 1;
602eadccaa9Sdrh p->D = sLocal.tm_mday;
603eadccaa9Sdrh p->h = sLocal.tm_hour;
604eadccaa9Sdrh p->m = sLocal.tm_min;
605ea840117Sdrh p->s = sLocal.tm_sec + (p->iJD%1000)*0.001;
606eadccaa9Sdrh p->validYMD = 1;
607eadccaa9Sdrh p->validHMS = 1;
608eadccaa9Sdrh p->validJD = 0;
609eadccaa9Sdrh p->rawS = 0;
610eadccaa9Sdrh p->validTZ = 0;
611eadccaa9Sdrh p->isError = 0;
612eadccaa9Sdrh return SQLITE_OK;
6137091cb05Sdrh }
61466147c97Sdrh #endif /* SQLITE_OMIT_LOCALTIME */
6157091cb05Sdrh
6167091cb05Sdrh /*
6176d4e9c3dSdrh ** The following table defines various date transformations of the form
6186d4e9c3dSdrh **
6196d4e9c3dSdrh ** 'NNN days'
6206d4e9c3dSdrh **
6216d4e9c3dSdrh ** Where NNN is an arbitrary floating-point number and "days" can be one
6226d4e9c3dSdrh ** of several units of time.
6236d4e9c3dSdrh */
6246d4e9c3dSdrh static const struct {
625b131bf70Sdrh u8 nName; /* Length of the name */
626b131bf70Sdrh char zName[7]; /* Name of the transformation */
627b131bf70Sdrh float rLimit; /* Maximum NNN value for this transform */
628b131bf70Sdrh float rXform; /* Constant used for this transform */
6296d4e9c3dSdrh } aXformType[] = {
630b131bf70Sdrh { 6, "second", 4.6427e+14, 1.0 },
631b131bf70Sdrh { 6, "minute", 7.7379e+12, 60.0 },
632b131bf70Sdrh { 4, "hour", 1.2897e+11, 3600.0 },
633b131bf70Sdrh { 3, "day", 5373485.0, 86400.0 },
634b131bf70Sdrh { 5, "month", 176546.0, 2592000.0 },
635b131bf70Sdrh { 4, "year", 14713.0, 31536000.0 },
6366d4e9c3dSdrh };
6376d4e9c3dSdrh
6386d4e9c3dSdrh /*
6397014aff3Sdrh ** Process a modifier to a date-time stamp. The modifiers are
6407014aff3Sdrh ** as follows:
6417014aff3Sdrh **
6427014aff3Sdrh ** NNN days
6437014aff3Sdrh ** NNN hours
6447014aff3Sdrh ** NNN minutes
6457014aff3Sdrh ** NNN.NNNN seconds
6467014aff3Sdrh ** NNN months
6477014aff3Sdrh ** NNN years
6487014aff3Sdrh ** start of month
6497014aff3Sdrh ** start of year
6507014aff3Sdrh ** start of week
6517014aff3Sdrh ** start of day
6527014aff3Sdrh ** weekday N
6537014aff3Sdrh ** unixepoch
6547091cb05Sdrh ** localtime
6557091cb05Sdrh ** utc
6567014aff3Sdrh **
657c17d696cSdan ** Return 0 on success and 1 if there is any kind of error. If the error
658c17d696cSdan ** is in a system call (i.e. localtime()), then an error message is written
659c17d696cSdan ** to context pCtx. If the error is an unrecognized modifier, no error is
660c17d696cSdan ** written to pCtx.
6617014aff3Sdrh */
parseModifier(sqlite3_context * pCtx,const char * z,int n,DateTime * p,int idx)6626d4e9c3dSdrh static int parseModifier(
6636d4e9c3dSdrh sqlite3_context *pCtx, /* Function context */
6646d4e9c3dSdrh const char *z, /* The text of the modifier */
6656d4e9c3dSdrh int n, /* Length of zMod in bytes */
666a1c8151bSdrh DateTime *p, /* The date/time value to be modified */
667a1c8151bSdrh int idx /* Parameter index of the modifier */
6686d4e9c3dSdrh ){
6697014aff3Sdrh int rc = 1;
6707014aff3Sdrh double r;
6716d4e9c3dSdrh switch(sqlite3UpperToLower[(u8)z[0]] ){
6721312a9c9Sdrh case 'a': {
6731312a9c9Sdrh /*
6741312a9c9Sdrh ** auto
6751312a9c9Sdrh **
6761312a9c9Sdrh ** If rawS is available, then interpret as a julian day number, or
6771312a9c9Sdrh ** a unix timestamp, depending on its magnitude.
6781312a9c9Sdrh */
6791312a9c9Sdrh if( sqlite3_stricmp(z, "auto")==0 ){
680a1c8151bSdrh if( idx>1 ) return 1; /* IMP: R-33611-57934 */
6811312a9c9Sdrh if( !p->rawS || p->validJD ){
6821312a9c9Sdrh rc = 0;
6831312a9c9Sdrh p->rawS = 0;
68416f56e84Sdrh }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */
68516f56e84Sdrh && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */
68616f56e84Sdrh ){
6871312a9c9Sdrh r = p->s*1000.0 + 210866760000000.0;
6881312a9c9Sdrh clearYMD_HMS_TZ(p);
6891312a9c9Sdrh p->iJD = (sqlite3_int64)(r + 0.5);
6901312a9c9Sdrh p->validJD = 1;
6911312a9c9Sdrh p->rawS = 0;
6921312a9c9Sdrh rc = 0;
6931312a9c9Sdrh }
6941312a9c9Sdrh }
6951312a9c9Sdrh break;
6961312a9c9Sdrh }
6971312a9c9Sdrh case 'j': {
6981312a9c9Sdrh /*
6991312a9c9Sdrh ** julianday
7001312a9c9Sdrh **
7011312a9c9Sdrh ** Always interpret the prior number as a julian-day value. If this
7021312a9c9Sdrh ** is not the first modifier, or if the prior argument is not a numeric
7031312a9c9Sdrh ** value in the allowed range of julian day numbers understood by
7041312a9c9Sdrh ** SQLite (0..5373484.5) then the result will be NULL.
7051312a9c9Sdrh */
7061312a9c9Sdrh if( sqlite3_stricmp(z, "julianday")==0 ){
7074b51e8bdSdrh if( idx>1 ) return 1; /* IMP: R-31176-64601 */
7081312a9c9Sdrh if( p->validJD && p->rawS ){
7091312a9c9Sdrh rc = 0;
7101312a9c9Sdrh p->rawS = 0;
7111312a9c9Sdrh }
7121312a9c9Sdrh }
7131312a9c9Sdrh break;
7141312a9c9Sdrh }
71566147c97Sdrh #ifndef SQLITE_OMIT_LOCALTIME
7167091cb05Sdrh case 'l': {
7177091cb05Sdrh /* localtime
7187091cb05Sdrh **
7197091cb05Sdrh ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
7207091cb05Sdrh ** show local time.
7217091cb05Sdrh */
7226e97f8ecSdrh if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
723eadccaa9Sdrh rc = toLocaltime(p, pCtx);
7247091cb05Sdrh }
7257091cb05Sdrh break;
7267091cb05Sdrh }
72766147c97Sdrh #endif
7287014aff3Sdrh case 'u': {
7297014aff3Sdrh /*
7307014aff3Sdrh ** unixepoch
7317014aff3Sdrh **
732861a5682Sdrh ** Treat the current value of p->s as the number of
7337014aff3Sdrh ** seconds since 1970. Convert to a real julian day number.
7347014aff3Sdrh */
7356d4e9c3dSdrh if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
7364b51e8bdSdrh if( idx>1 ) return 1; /* IMP: R-49255-55373 */
737e6ad1717Sdrh r = p->s*1000.0 + 210866760000000.0;
738861a5682Sdrh if( r>=0.0 && r<464269060800000.0 ){
739ba21256fSdrh clearYMD_HMS_TZ(p);
740915530dcSdrh p->iJD = (sqlite3_int64)(r + 0.5);
741861a5682Sdrh p->validJD = 1;
742861a5682Sdrh p->rawS = 0;
7437014aff3Sdrh rc = 0;
74466cccd9bSdrh }
745861a5682Sdrh }
74666cccd9bSdrh #ifndef SQLITE_OMIT_LOCALTIME
7476e97f8ecSdrh else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
748caeca516Sdrh if( p->tzSet==0 ){
749eadccaa9Sdrh i64 iOrigJD; /* Original localtime */
750eadccaa9Sdrh i64 iGuess; /* Guess at the corresponding utc time */
751eadccaa9Sdrh int cnt = 0; /* Safety to prevent infinite loop */
752eadccaa9Sdrh int iErr; /* Guess is off by this much */
753eadccaa9Sdrh
7547091cb05Sdrh computeJD(p);
755eadccaa9Sdrh iGuess = iOrigJD = p->iJD;
756eadccaa9Sdrh iErr = 0;
757eadccaa9Sdrh do{
758eadccaa9Sdrh DateTime new;
759eadccaa9Sdrh memset(&new, 0, sizeof(new));
760eadccaa9Sdrh iGuess -= iErr;
761eadccaa9Sdrh new.iJD = iGuess;
762eadccaa9Sdrh new.validJD = 1;
763eadccaa9Sdrh rc = toLocaltime(&new, pCtx);
764eadccaa9Sdrh if( rc ) return rc;
765eadccaa9Sdrh computeJD(&new);
766eadccaa9Sdrh iErr = new.iJD - iOrigJD;
767eadccaa9Sdrh }while( iErr && cnt++<3 );
768eadccaa9Sdrh memset(p, 0, sizeof(*p));
769eadccaa9Sdrh p->iJD = iGuess;
770eadccaa9Sdrh p->validJD = 1;
771caeca516Sdrh p->tzSet = 1;
772caeca516Sdrh }
773eadccaa9Sdrh rc = SQLITE_OK;
7747014aff3Sdrh }
77566cccd9bSdrh #endif
7767014aff3Sdrh break;
7777014aff3Sdrh }
7787014aff3Sdrh case 'w': {
7797014aff3Sdrh /*
7807014aff3Sdrh ** weekday N
7817014aff3Sdrh **
782181fc993Sdrh ** Move the date to the same time on the next occurrence of
7837014aff3Sdrh ** weekday N where 0==Sunday, 1==Monday, and so forth. If the
784c5dd9fa8Sdrh ** date is already on the appropriate weekday, this is a no-op.
7857014aff3Sdrh */
7866d4e9c3dSdrh if( sqlite3_strnicmp(z, "weekday ", 8)==0
7879a278229Sdrh && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0
788*26e817f6Sdrh && r>=0.0 && r<7.0 && (n=(int)r)==r ){
78985f477a1Sdrh sqlite3_int64 Z;
790ba21256fSdrh computeYMD_HMS(p);
7917014aff3Sdrh p->validTZ = 0;
7927014aff3Sdrh p->validJD = 0;
7937014aff3Sdrh computeJD(p);
79485f477a1Sdrh Z = ((p->iJD + 129600000)/86400000) % 7;
7957014aff3Sdrh if( Z>n ) Z -= 7;
79685f477a1Sdrh p->iJD += (n - Z)*86400000;
797ba21256fSdrh clearYMD_HMS_TZ(p);
7987014aff3Sdrh rc = 0;
7997014aff3Sdrh }
8007014aff3Sdrh break;
8017014aff3Sdrh }
8027014aff3Sdrh case 's': {
8037014aff3Sdrh /*
8047014aff3Sdrh ** start of TTTTT
8057014aff3Sdrh **
8067014aff3Sdrh ** Move the date backwards to the beginning of the current day,
8077014aff3Sdrh ** or month or year.
8087014aff3Sdrh */
8096d4e9c3dSdrh if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break;
81035a0925aSdrh if( !p->validJD && !p->validYMD && !p->validHMS ) break;
8114d5b8365Sdrh z += 9;
8127014aff3Sdrh computeYMD(p);
8137014aff3Sdrh p->validHMS = 1;
8147014aff3Sdrh p->h = p->m = 0;
8157014aff3Sdrh p->s = 0.0;
8169715f7f0Sdrh p->rawS = 0;
8177014aff3Sdrh p->validTZ = 0;
8187014aff3Sdrh p->validJD = 0;
8196d4e9c3dSdrh if( sqlite3_stricmp(z,"month")==0 ){
8207014aff3Sdrh p->D = 1;
8217014aff3Sdrh rc = 0;
8226d4e9c3dSdrh }else if( sqlite3_stricmp(z,"year")==0 ){
8237014aff3Sdrh p->M = 1;
8247014aff3Sdrh p->D = 1;
8257014aff3Sdrh rc = 0;
8266d4e9c3dSdrh }else if( sqlite3_stricmp(z,"day")==0 ){
8277014aff3Sdrh rc = 0;
8287014aff3Sdrh }
8297014aff3Sdrh break;
8307014aff3Sdrh }
8317014aff3Sdrh case '+':
8327014aff3Sdrh case '-':
8337014aff3Sdrh case '0':
8347014aff3Sdrh case '1':
8357014aff3Sdrh case '2':
8367014aff3Sdrh case '3':
8377014aff3Sdrh case '4':
8387014aff3Sdrh case '5':
8397014aff3Sdrh case '6':
8407014aff3Sdrh case '7':
8417014aff3Sdrh case '8':
8427014aff3Sdrh case '9': {
843c531a223Sdrh double rRounder;
8446d4e9c3dSdrh int i;
8459339da1fSdrh for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
8469a278229Sdrh if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){
8479339da1fSdrh rc = 1;
8489339da1fSdrh break;
8499339da1fSdrh }
85033a9ad2fSdrh if( z[n]==':' ){
85133a9ad2fSdrh /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
85233a9ad2fSdrh ** specified number of hours, minutes, seconds, and fractional seconds
85333a9ad2fSdrh ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be
85433a9ad2fSdrh ** omitted.
85533a9ad2fSdrh */
85633a9ad2fSdrh const char *z2 = z;
85733a9ad2fSdrh DateTime tx;
85885f477a1Sdrh sqlite3_int64 day;
85978ca0e7eSdanielk1977 if( !sqlite3Isdigit(*z2) ) z2++;
86033a9ad2fSdrh memset(&tx, 0, sizeof(tx));
86133a9ad2fSdrh if( parseHhMmSs(z2, &tx) ) break;
86233a9ad2fSdrh computeJD(&tx);
86385f477a1Sdrh tx.iJD -= 43200000;
86485f477a1Sdrh day = tx.iJD/86400000;
86585f477a1Sdrh tx.iJD -= day*86400000;
86685f477a1Sdrh if( z[0]=='-' ) tx.iJD = -tx.iJD;
8670d131ab7Sdrh computeJD(p);
8680d131ab7Sdrh clearYMD_HMS_TZ(p);
86985f477a1Sdrh p->iJD += tx.iJD;
87033a9ad2fSdrh rc = 0;
87133a9ad2fSdrh break;
87233a9ad2fSdrh }
8736d4e9c3dSdrh
8746d4e9c3dSdrh /* If control reaches this point, it means the transformation is
8756d4e9c3dSdrh ** one of the forms like "+NNN days". */
8764d5b8365Sdrh z += n;
87778ca0e7eSdanielk1977 while( sqlite3Isspace(*z) ) z++;
878ea678832Sdrh n = sqlite3Strlen30(z);
8797014aff3Sdrh if( n>10 || n<3 ) break;
8806d4e9c3dSdrh if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--;
8817014aff3Sdrh computeJD(p);
8826d4e9c3dSdrh rc = 1;
883c531a223Sdrh rRounder = r<0 ? -0.5 : +0.5;
8846d4e9c3dSdrh for(i=0; i<ArraySize(aXformType); i++){
8856d4e9c3dSdrh if( aXformType[i].nName==n
8866d4e9c3dSdrh && sqlite3_strnicmp(aXformType[i].zName, z, n)==0
8876d4e9c3dSdrh && r>-aXformType[i].rLimit && r<aXformType[i].rLimit
8886d4e9c3dSdrh ){
889b131bf70Sdrh switch( i ){
890b131bf70Sdrh case 4: { /* Special processing to add months */
8916d4e9c3dSdrh int x;
892b131bf70Sdrh assert( strcmp(aXformType[i].zName,"month")==0 );
893ba21256fSdrh computeYMD_HMS(p);
894aef3af54Sshane p->M += (int)r;
8957014aff3Sdrh x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
8967014aff3Sdrh p->Y += x;
8977014aff3Sdrh p->M -= x*12;
8987014aff3Sdrh p->validJD = 0;
8996d4e9c3dSdrh r -= (int)r;
9006d4e9c3dSdrh break;
9017014aff3Sdrh }
902b131bf70Sdrh case 5: { /* Special processing to add years */
903c531a223Sdrh int y = (int)r;
904b131bf70Sdrh assert( strcmp(aXformType[i].zName,"year")==0 );
905ba21256fSdrh computeYMD_HMS(p);
906c531a223Sdrh p->Y += y;
9077014aff3Sdrh p->validJD = 0;
9086d4e9c3dSdrh r -= (int)r;
9096d4e9c3dSdrh break;
910c531a223Sdrh }
9116d4e9c3dSdrh }
9126d4e9c3dSdrh computeJD(p);
913b131bf70Sdrh p->iJD += (sqlite3_int64)(r*1000.0*aXformType[i].rXform + rRounder);
9146d4e9c3dSdrh rc = 0;
9156d4e9c3dSdrh break;
9166d4e9c3dSdrh }
9177014aff3Sdrh }
918ba21256fSdrh clearYMD_HMS_TZ(p);
9197014aff3Sdrh break;
9207014aff3Sdrh }
9217014aff3Sdrh default: {
9227014aff3Sdrh break;
9237014aff3Sdrh }
9247014aff3Sdrh }
9257014aff3Sdrh return rc;
9267014aff3Sdrh }
9277014aff3Sdrh
9287014aff3Sdrh /*
9297014aff3Sdrh ** Process time function arguments. argv[0] is a date-time stamp.
9307014aff3Sdrh ** argv[1] and following are modifiers. Parse them all and write
9317014aff3Sdrh ** the resulting time into the DateTime structure p. Return 0
9327014aff3Sdrh ** on success and 1 if there are any errors.
933008e476cSdrh **
934008e476cSdrh ** If there are zero parameters (if even argv[0] is undefined)
935008e476cSdrh ** then assume a default value of "now" for argv[0].
9367014aff3Sdrh */
isDate(sqlite3_context * context,int argc,sqlite3_value ** argv,DateTime * p)937fee2d25aSdanielk1977 static int isDate(
938fee2d25aSdanielk1977 sqlite3_context *context,
939fee2d25aSdanielk1977 int argc,
940fee2d25aSdanielk1977 sqlite3_value **argv,
941fee2d25aSdanielk1977 DateTime *p
942fee2d25aSdanielk1977 ){
9436d4e9c3dSdrh int i, n;
9447a521cfbSdrh const unsigned char *z;
94585f477a1Sdrh int eType;
9463af5d685Sdrh memset(p, 0, sizeof(*p));
947008e476cSdrh if( argc==0 ){
948a7d8d4a0Sdrh if( !sqlite3NotPureFunc(context) ) return 1;
9493170225fSdrh return setDateTimeToCurrent(context, p);
9503170225fSdrh }
9513170225fSdrh if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
95285f477a1Sdrh || eType==SQLITE_INTEGER ){
953861a5682Sdrh setRawDateNumber(p, sqlite3_value_double(argv[0]));
954008e476cSdrh }else{
955fee2d25aSdanielk1977 z = sqlite3_value_text(argv[0]);
956fee2d25aSdanielk1977 if( !z || parseDateOrTime(context, (char*)z, p) ){
9577a521cfbSdrh return 1;
9587a521cfbSdrh }
9593af5d685Sdrh }
9607014aff3Sdrh for(i=1; i<argc; i++){
961c17d696cSdan z = sqlite3_value_text(argv[i]);
9626d4e9c3dSdrh n = sqlite3_value_bytes(argv[i]);
963a1c8151bSdrh if( z==0 || parseModifier(context, (char*)z, n, p, i) ) return 1;
9647014aff3Sdrh }
965b5489b88Sdrh computeJD(p);
966b5489b88Sdrh if( p->isError || !validJulianDay(p->iJD) ) return 1;
9677014aff3Sdrh return 0;
9687014aff3Sdrh }
9697014aff3Sdrh
9707014aff3Sdrh
9717014aff3Sdrh /*
9727014aff3Sdrh ** The following routines implement the various date and time functions
9737014aff3Sdrh ** of SQLite.
9747014aff3Sdrh */
9757014aff3Sdrh
9767014aff3Sdrh /*
9777014aff3Sdrh ** julianday( TIMESTRING, MOD, MOD, ...)
9787014aff3Sdrh **
9797014aff3Sdrh ** Return the julian day number of the date specified in the arguments
9807014aff3Sdrh */
juliandayFunc(sqlite3_context * context,int argc,sqlite3_value ** argv)981f9b596ebSdrh static void juliandayFunc(
982f9b596ebSdrh sqlite3_context *context,
983f9b596ebSdrh int argc,
984f9b596ebSdrh sqlite3_value **argv
985f9b596ebSdrh ){
9867014aff3Sdrh DateTime x;
987fee2d25aSdanielk1977 if( isDate(context, argc, argv, &x)==0 ){
9887014aff3Sdrh computeJD(&x);
98985f477a1Sdrh sqlite3_result_double(context, x.iJD/86400000.0);
9907014aff3Sdrh }
9917014aff3Sdrh }
9927014aff3Sdrh
9937014aff3Sdrh /*
9941312a9c9Sdrh ** unixepoch( TIMESTRING, MOD, MOD, ...)
9951312a9c9Sdrh **
9961312a9c9Sdrh ** Return the number of seconds (including fractional seconds) since
9971312a9c9Sdrh ** the unix epoch of 1970-01-01 00:00:00 GMT.
9981312a9c9Sdrh */
unixepochFunc(sqlite3_context * context,int argc,sqlite3_value ** argv)9991312a9c9Sdrh static void unixepochFunc(
10001312a9c9Sdrh sqlite3_context *context,
10011312a9c9Sdrh int argc,
10021312a9c9Sdrh sqlite3_value **argv
10031312a9c9Sdrh ){
10041312a9c9Sdrh DateTime x;
10051312a9c9Sdrh if( isDate(context, argc, argv, &x)==0 ){
10061312a9c9Sdrh computeJD(&x);
10071312a9c9Sdrh sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000);
10081312a9c9Sdrh }
10091312a9c9Sdrh }
10101312a9c9Sdrh
10111312a9c9Sdrh /*
10127014aff3Sdrh ** datetime( TIMESTRING, MOD, MOD, ...)
10137014aff3Sdrh **
10147014aff3Sdrh ** Return YYYY-MM-DD HH:MM:SS
10157014aff3Sdrh */
datetimeFunc(sqlite3_context * context,int argc,sqlite3_value ** argv)1016f9b596ebSdrh static void datetimeFunc(
1017f9b596ebSdrh sqlite3_context *context,
1018f9b596ebSdrh int argc,
1019f9b596ebSdrh sqlite3_value **argv
1020f9b596ebSdrh ){
10217014aff3Sdrh DateTime x;
1022fee2d25aSdanielk1977 if( isDate(context, argc, argv, &x)==0 ){
1023522608d3Sdrh int Y, s;
1024522608d3Sdrh char zBuf[24];
1025ba21256fSdrh computeYMD_HMS(&x);
1026522608d3Sdrh Y = x.Y;
1027522608d3Sdrh if( Y<0 ) Y = -Y;
1028522608d3Sdrh zBuf[1] = '0' + (Y/1000)%10;
1029522608d3Sdrh zBuf[2] = '0' + (Y/100)%10;
1030522608d3Sdrh zBuf[3] = '0' + (Y/10)%10;
1031522608d3Sdrh zBuf[4] = '0' + (Y)%10;
1032522608d3Sdrh zBuf[5] = '-';
1033522608d3Sdrh zBuf[6] = '0' + (x.M/10)%10;
1034522608d3Sdrh zBuf[7] = '0' + (x.M)%10;
1035522608d3Sdrh zBuf[8] = '-';
1036522608d3Sdrh zBuf[9] = '0' + (x.D/10)%10;
1037522608d3Sdrh zBuf[10] = '0' + (x.D)%10;
1038522608d3Sdrh zBuf[11] = ' ';
1039522608d3Sdrh zBuf[12] = '0' + (x.h/10)%10;
1040522608d3Sdrh zBuf[13] = '0' + (x.h)%10;
1041522608d3Sdrh zBuf[14] = ':';
1042522608d3Sdrh zBuf[15] = '0' + (x.m/10)%10;
1043522608d3Sdrh zBuf[16] = '0' + (x.m)%10;
1044522608d3Sdrh zBuf[17] = ':';
1045522608d3Sdrh s = (int)x.s;
1046522608d3Sdrh zBuf[18] = '0' + (s/10)%10;
1047522608d3Sdrh zBuf[19] = '0' + (s)%10;
1048522608d3Sdrh zBuf[20] = 0;
1049522608d3Sdrh if( x.Y<0 ){
1050522608d3Sdrh zBuf[0] = '-';
1051522608d3Sdrh sqlite3_result_text(context, zBuf, 20, SQLITE_TRANSIENT);
1052522608d3Sdrh }else{
1053522608d3Sdrh sqlite3_result_text(context, &zBuf[1], 19, SQLITE_TRANSIENT);
1054522608d3Sdrh }
10557014aff3Sdrh }
10567014aff3Sdrh }
10577014aff3Sdrh
10587014aff3Sdrh /*
10597014aff3Sdrh ** time( TIMESTRING, MOD, MOD, ...)
10607014aff3Sdrh **
10617014aff3Sdrh ** Return HH:MM:SS
10627014aff3Sdrh */
timeFunc(sqlite3_context * context,int argc,sqlite3_value ** argv)1063f9b596ebSdrh static void timeFunc(
1064f9b596ebSdrh sqlite3_context *context,
1065f9b596ebSdrh int argc,
1066f9b596ebSdrh sqlite3_value **argv
1067f9b596ebSdrh ){
10687014aff3Sdrh DateTime x;
1069fee2d25aSdanielk1977 if( isDate(context, argc, argv, &x)==0 ){
1070522608d3Sdrh int s;
1071522608d3Sdrh char zBuf[16];
10727014aff3Sdrh computeHMS(&x);
1073522608d3Sdrh zBuf[0] = '0' + (x.h/10)%10;
1074522608d3Sdrh zBuf[1] = '0' + (x.h)%10;
1075522608d3Sdrh zBuf[2] = ':';
1076522608d3Sdrh zBuf[3] = '0' + (x.m/10)%10;
1077522608d3Sdrh zBuf[4] = '0' + (x.m)%10;
1078522608d3Sdrh zBuf[5] = ':';
1079522608d3Sdrh s = (int)x.s;
1080522608d3Sdrh zBuf[6] = '0' + (s/10)%10;
1081522608d3Sdrh zBuf[7] = '0' + (s)%10;
1082522608d3Sdrh zBuf[8] = 0;
1083522608d3Sdrh sqlite3_result_text(context, zBuf, 8, SQLITE_TRANSIENT);
10847014aff3Sdrh }
10857014aff3Sdrh }
10867014aff3Sdrh
10877014aff3Sdrh /*
10887014aff3Sdrh ** date( TIMESTRING, MOD, MOD, ...)
10897014aff3Sdrh **
10907014aff3Sdrh ** Return YYYY-MM-DD
10917014aff3Sdrh */
dateFunc(sqlite3_context * context,int argc,sqlite3_value ** argv)1092f9b596ebSdrh static void dateFunc(
1093f9b596ebSdrh sqlite3_context *context,
1094f9b596ebSdrh int argc,
1095f9b596ebSdrh sqlite3_value **argv
1096f9b596ebSdrh ){
10977014aff3Sdrh DateTime x;
1098fee2d25aSdanielk1977 if( isDate(context, argc, argv, &x)==0 ){
1099522608d3Sdrh int Y;
1100522608d3Sdrh char zBuf[16];
11017014aff3Sdrh computeYMD(&x);
1102522608d3Sdrh Y = x.Y;
1103522608d3Sdrh if( Y<0 ) Y = -Y;
1104522608d3Sdrh zBuf[1] = '0' + (Y/1000)%10;
1105522608d3Sdrh zBuf[2] = '0' + (Y/100)%10;
1106522608d3Sdrh zBuf[3] = '0' + (Y/10)%10;
1107522608d3Sdrh zBuf[4] = '0' + (Y)%10;
1108522608d3Sdrh zBuf[5] = '-';
1109522608d3Sdrh zBuf[6] = '0' + (x.M/10)%10;
1110522608d3Sdrh zBuf[7] = '0' + (x.M)%10;
1111522608d3Sdrh zBuf[8] = '-';
1112522608d3Sdrh zBuf[9] = '0' + (x.D/10)%10;
1113522608d3Sdrh zBuf[10] = '0' + (x.D)%10;
1114522608d3Sdrh zBuf[11] = 0;
1115522608d3Sdrh if( x.Y<0 ){
1116522608d3Sdrh zBuf[0] = '-';
1117522608d3Sdrh sqlite3_result_text(context, zBuf, 11, SQLITE_TRANSIENT);
1118522608d3Sdrh }else{
1119522608d3Sdrh sqlite3_result_text(context, &zBuf[1], 10, SQLITE_TRANSIENT);
1120522608d3Sdrh }
11217014aff3Sdrh }
11227014aff3Sdrh }
11237014aff3Sdrh
11247014aff3Sdrh /*
11257014aff3Sdrh ** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
11267014aff3Sdrh **
11277014aff3Sdrh ** Return a string described by FORMAT. Conversions as follows:
11287014aff3Sdrh **
11297014aff3Sdrh ** %d day of month
11307014aff3Sdrh ** %f ** fractional seconds SS.SSS
11317014aff3Sdrh ** %H hour 00-24
11327014aff3Sdrh ** %j day of year 000-366
113386a11b8aSdrh ** %J ** julian day number
11347014aff3Sdrh ** %m month 01-12
11357014aff3Sdrh ** %M minute 00-59
11367014aff3Sdrh ** %s seconds since 1970-01-01
11377014aff3Sdrh ** %S seconds 00-59
11387014aff3Sdrh ** %w day of week 0-6 sunday==0
11397014aff3Sdrh ** %W week of year 00-53
11407014aff3Sdrh ** %Y year 0000-9999
11417014aff3Sdrh ** %% %
11427014aff3Sdrh */
strftimeFunc(sqlite3_context * context,int argc,sqlite3_value ** argv)1143f9b596ebSdrh static void strftimeFunc(
1144f9b596ebSdrh sqlite3_context *context,
1145f9b596ebSdrh int argc,
1146f9b596ebSdrh sqlite3_value **argv
1147f9b596ebSdrh ){
11487014aff3Sdrh DateTime x;
1149aef3af54Sshane size_t i,j;
1150633e6d57Sdrh sqlite3 *db;
1151655814d2Sdrh const char *zFmt;
11525bf4715eSdrh sqlite3_str sRes;
11535bf4715eSdrh
11545bf4715eSdrh
1155655814d2Sdrh if( argc==0 ) return;
1156655814d2Sdrh zFmt = (const char*)sqlite3_value_text(argv[0]);
1157fee2d25aSdanielk1977 if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
1158633e6d57Sdrh db = sqlite3_context_db_handle(context);
11595bf4715eSdrh sqlite3StrAccumInit(&sRes, 0, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
11605bf4715eSdrh
11617014aff3Sdrh computeJD(&x);
1162ba21256fSdrh computeYMD_HMS(&x);
11637014aff3Sdrh for(i=j=0; zFmt[i]; i++){
11645bf4715eSdrh if( zFmt[i]!='%' ) continue;
116513ca72d0Sdrh if( j<i ) sqlite3_str_append(&sRes, zFmt+j, (int)(i-j));
11667014aff3Sdrh i++;
11675bf4715eSdrh j = i + 1;
11687014aff3Sdrh switch( zFmt[i] ){
11695bf4715eSdrh case 'd': {
11705bf4715eSdrh sqlite3_str_appendf(&sRes, "%02d", x.D);
11715bf4715eSdrh break;
11725bf4715eSdrh }
11737014aff3Sdrh case 'f': {
1174b1f1e6ebSdrh double s = x.s;
1175b1f1e6ebSdrh if( s>59.999 ) s = 59.999;
11765bf4715eSdrh sqlite3_str_appendf(&sRes, "%06.3f", s);
11777014aff3Sdrh break;
11787014aff3Sdrh }
11795bf4715eSdrh case 'H': {
11805bf4715eSdrh sqlite3_str_appendf(&sRes, "%02d", x.h);
11815bf4715eSdrh break;
11825bf4715eSdrh }
11837014aff3Sdrh case 'W': /* Fall thru */
11847014aff3Sdrh case 'j': {
1185f0113000Sdanielk1977 int nDay; /* Number of days since 1st day of year */
11867014aff3Sdrh DateTime y = x;
11877014aff3Sdrh y.validJD = 0;
11887014aff3Sdrh y.M = 1;
11897014aff3Sdrh y.D = 1;
11907014aff3Sdrh computeJD(&y);
1191aef3af54Sshane nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
11927014aff3Sdrh if( zFmt[i]=='W' ){
11931020d49aSdrh int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */
1194aef3af54Sshane wd = (int)(((x.iJD+43200000)/86400000)%7);
11955bf4715eSdrh sqlite3_str_appendf(&sRes,"%02d",(nDay+7-wd)/7);
11967014aff3Sdrh }else{
11975bf4715eSdrh sqlite3_str_appendf(&sRes,"%03d",nDay+1);
11987014aff3Sdrh }
11997014aff3Sdrh break;
12007014aff3Sdrh }
12015bb3eb9bSdrh case 'J': {
12025bf4715eSdrh sqlite3_str_appendf(&sRes,"%.16g",x.iJD/86400000.0);
12037014aff3Sdrh break;
12047014aff3Sdrh }
12055bf4715eSdrh case 'm': {
12065bf4715eSdrh sqlite3_str_appendf(&sRes,"%02d",x.M);
12075bf4715eSdrh break;
12085bf4715eSdrh }
12095bf4715eSdrh case 'M': {
12105bf4715eSdrh sqlite3_str_appendf(&sRes,"%02d",x.m);
12115bf4715eSdrh break;
12125bf4715eSdrh }
12135bb3eb9bSdrh case 's': {
121482b0f106Sdrh i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000);
12155bf4715eSdrh sqlite3_str_appendf(&sRes,"%lld",iS);
12165bb3eb9bSdrh break;
12175bb3eb9bSdrh }
12185bf4715eSdrh case 'S': {
12195bf4715eSdrh sqlite3_str_appendf(&sRes,"%02d",(int)x.s);
12205bf4715eSdrh break;
12215bf4715eSdrh }
1222ea678832Sdrh case 'w': {
12235bf4715eSdrh sqlite3_str_appendchar(&sRes, 1,
12245bf4715eSdrh (char)(((x.iJD+129600000)/86400000) % 7) + '0');
1225ea678832Sdrh break;
1226ea678832Sdrh }
1227ea678832Sdrh case 'Y': {
12285bf4715eSdrh sqlite3_str_appendf(&sRes,"%04d",x.Y);
1229ea678832Sdrh break;
1230ea678832Sdrh }
12315bf4715eSdrh case '%': {
12325bf4715eSdrh sqlite3_str_appendchar(&sRes, 1, '%');
12335bf4715eSdrh break;
12345bf4715eSdrh }
12355bf4715eSdrh default: {
12365bf4715eSdrh sqlite3_str_reset(&sRes);
12375bf4715eSdrh return;
12387014aff3Sdrh }
12397014aff3Sdrh }
12407014aff3Sdrh }
124113ca72d0Sdrh if( j<i ) sqlite3_str_append(&sRes, zFmt+j, (int)(i-j));
12425bf4715eSdrh sqlite3ResultStrAccum(context, &sRes);
12437014aff3Sdrh }
12447014aff3Sdrh
12457977a17fSdanielk1977 /*
12467977a17fSdanielk1977 ** current_time()
12477977a17fSdanielk1977 **
12487977a17fSdanielk1977 ** This function returns the same value as time('now').
12497977a17fSdanielk1977 */
ctimeFunc(sqlite3_context * context,int NotUsed,sqlite3_value ** NotUsed2)12507977a17fSdanielk1977 static void ctimeFunc(
12517977a17fSdanielk1977 sqlite3_context *context,
125262c14b34Sdanielk1977 int NotUsed,
125362c14b34Sdanielk1977 sqlite3_value **NotUsed2
12547977a17fSdanielk1977 ){
125562c14b34Sdanielk1977 UNUSED_PARAMETER2(NotUsed, NotUsed2);
1256008e476cSdrh timeFunc(context, 0, 0);
12577977a17fSdanielk1977 }
12587014aff3Sdrh
12597977a17fSdanielk1977 /*
12607977a17fSdanielk1977 ** current_date()
12617977a17fSdanielk1977 **
12627977a17fSdanielk1977 ** This function returns the same value as date('now').
12637977a17fSdanielk1977 */
cdateFunc(sqlite3_context * context,int NotUsed,sqlite3_value ** NotUsed2)12647977a17fSdanielk1977 static void cdateFunc(
12657977a17fSdanielk1977 sqlite3_context *context,
126662c14b34Sdanielk1977 int NotUsed,
126762c14b34Sdanielk1977 sqlite3_value **NotUsed2
12687977a17fSdanielk1977 ){
126962c14b34Sdanielk1977 UNUSED_PARAMETER2(NotUsed, NotUsed2);
1270008e476cSdrh dateFunc(context, 0, 0);
12717977a17fSdanielk1977 }
12727977a17fSdanielk1977
12737977a17fSdanielk1977 /*
12747977a17fSdanielk1977 ** current_timestamp()
12757977a17fSdanielk1977 **
12767977a17fSdanielk1977 ** This function returns the same value as datetime('now').
12777977a17fSdanielk1977 */
ctimestampFunc(sqlite3_context * context,int NotUsed,sqlite3_value ** NotUsed2)12787977a17fSdanielk1977 static void ctimestampFunc(
12797977a17fSdanielk1977 sqlite3_context *context,
128062c14b34Sdanielk1977 int NotUsed,
128162c14b34Sdanielk1977 sqlite3_value **NotUsed2
12827977a17fSdanielk1977 ){
128362c14b34Sdanielk1977 UNUSED_PARAMETER2(NotUsed, NotUsed2);
1284008e476cSdrh datetimeFunc(context, 0, 0);
12857977a17fSdanielk1977 }
12867014aff3Sdrh #endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */
12877014aff3Sdrh
1288752e679aSdanielk1977 #ifdef SQLITE_OMIT_DATETIME_FUNCS
1289752e679aSdanielk1977 /*
1290752e679aSdanielk1977 ** If the library is compiled to omit the full-scale date and time
1291752e679aSdanielk1977 ** handling (to get a smaller binary), the following minimal version
1292752e679aSdanielk1977 ** of the functions current_time(), current_date() and current_timestamp()
1293752e679aSdanielk1977 ** are included instead. This is to support column declarations that
1294752e679aSdanielk1977 ** include "DEFAULT CURRENT_TIME" etc.
1295752e679aSdanielk1977 **
12962df9fabfSdanielk1977 ** This function uses the C-library functions time(), gmtime()
1297752e679aSdanielk1977 ** and strftime(). The format string to pass to strftime() is supplied
1298752e679aSdanielk1977 ** as the user-data for the function.
1299752e679aSdanielk1977 */
currentTimeFunc(sqlite3_context * context,int argc,sqlite3_value ** argv)1300752e679aSdanielk1977 static void currentTimeFunc(
1301752e679aSdanielk1977 sqlite3_context *context,
1302752e679aSdanielk1977 int argc,
1303752e679aSdanielk1977 sqlite3_value **argv
1304752e679aSdanielk1977 ){
1305752e679aSdanielk1977 time_t t;
1306752e679aSdanielk1977 char *zFormat = (char *)sqlite3_user_data(context);
1307b7e8ea20Sdrh sqlite3_int64 iT;
13083170225fSdrh struct tm *pTm;
13093170225fSdrh struct tm sNow;
1310752e679aSdanielk1977 char zBuf[20];
1311752e679aSdanielk1977
1312fbd60f82Sshane UNUSED_PARAMETER(argc);
1313fbd60f82Sshane UNUSED_PARAMETER(argv);
1314fbd60f82Sshane
131595a7b3e3Sdrh iT = sqlite3StmtCurrentTime(context);
131695a7b3e3Sdrh if( iT<=0 ) return;
1317d5e6e400Sdrh t = iT/1000 - 10000*(sqlite3_int64)21086676;
13180ede9ebeSdrh #if HAVE_GMTIME_R
13193170225fSdrh pTm = gmtime_r(&t, &sNow);
132087595765Sdrh #else
1321ccb2113aSdrh sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN));
132287595765Sdrh pTm = gmtime(&t);
13233170225fSdrh if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
1324ccb2113aSdrh sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN));
132587595765Sdrh #endif
13263170225fSdrh if( pTm ){
13273170225fSdrh strftime(zBuf, 20, zFormat, &sNow);
1328752e679aSdanielk1977 sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
1329752e679aSdanielk1977 }
13303170225fSdrh }
1331752e679aSdanielk1977 #endif
1332752e679aSdanielk1977
13337014aff3Sdrh /*
13347014aff3Sdrh ** This function registered all of the above C functions as SQL
13357014aff3Sdrh ** functions. This should be the only routine in this file with
13367014aff3Sdrh ** external linkage.
13377014aff3Sdrh */
sqlite3RegisterDateTimeFunctions(void)1338777c5386Sdrh void sqlite3RegisterDateTimeFunctions(void){
133980738d9cSdrh static FuncDef aDateTimeFuncs[] = {
1340fd1f394aSdrh #ifndef SQLITE_OMIT_DATETIME_FUNCS
13413e34eabcSdrh PURE_DATE(julianday, -1, 0, 0, juliandayFunc ),
13421312a9c9Sdrh PURE_DATE(unixepoch, -1, 0, 0, unixepochFunc ),
13433e34eabcSdrh PURE_DATE(date, -1, 0, 0, dateFunc ),
13443e34eabcSdrh PURE_DATE(time, -1, 0, 0, timeFunc ),
13453e34eabcSdrh PURE_DATE(datetime, -1, 0, 0, datetimeFunc ),
13463e34eabcSdrh PURE_DATE(strftime, -1, 0, 0, strftimeFunc ),
13471d85e405Sdrh DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
13481d85e405Sdrh DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
13491d85e405Sdrh DFUNCTION(current_date, 0, 0, 0, cdateFunc ),
1350752e679aSdanielk1977 #else
135121717ed6Sdrh STR_FUNCTION(current_time, 0, "%H:%M:%S", 0, currentTimeFunc),
13522b1e690fSdrh STR_FUNCTION(current_date, 0, "%Y-%m-%d", 0, currentTimeFunc),
13532b1e690fSdrh STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
1354777c5386Sdrh #endif
1355752e679aSdanielk1977 };
135680738d9cSdrh sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs));
13577014aff3Sdrh }
1358