xref: /titanic_53/usr/src/lib/libsqlite/src/date.c (revision c5c4113dfcabb1eed3d4bdf7609de5170027a794)
1*c5c4113dSnw141292 
2*c5c4113dSnw141292 #pragma ident	"%Z%%M%	%I%	%E% SMI"
3*c5c4113dSnw141292 
4*c5c4113dSnw141292 /*
5*c5c4113dSnw141292 ** 2003 October 31
6*c5c4113dSnw141292 **
7*c5c4113dSnw141292 ** The author disclaims copyright to this source code.  In place of
8*c5c4113dSnw141292 ** a legal notice, here is a blessing:
9*c5c4113dSnw141292 **
10*c5c4113dSnw141292 **    May you do good and not evil.
11*c5c4113dSnw141292 **    May you find forgiveness for yourself and forgive others.
12*c5c4113dSnw141292 **    May you share freely, never taking more than you give.
13*c5c4113dSnw141292 **
14*c5c4113dSnw141292 *************************************************************************
15*c5c4113dSnw141292 ** This file contains the C functions that implement date and time
16*c5c4113dSnw141292 ** functions for SQLite.
17*c5c4113dSnw141292 **
18*c5c4113dSnw141292 ** There is only one exported symbol in this file - the function
19*c5c4113dSnw141292 ** sqliteRegisterDateTimeFunctions() found at the bottom of the file.
20*c5c4113dSnw141292 ** All other code has file scope.
21*c5c4113dSnw141292 **
22*c5c4113dSnw141292 ** $Id: date.c,v 1.16.2.2 2004/07/20 00:40:01 drh Exp $
23*c5c4113dSnw141292 **
24*c5c4113dSnw141292 ** NOTES:
25*c5c4113dSnw141292 **
26*c5c4113dSnw141292 ** SQLite processes all times and dates as Julian Day numbers.  The
27*c5c4113dSnw141292 ** dates and times are stored as the number of days since noon
28*c5c4113dSnw141292 ** in Greenwich on November 24, 4714 B.C. according to the Gregorian
29*c5c4113dSnw141292 ** calendar system.
30*c5c4113dSnw141292 **
31*c5c4113dSnw141292 ** 1970-01-01 00:00:00 is JD 2440587.5
32*c5c4113dSnw141292 ** 2000-01-01 00:00:00 is JD 2451544.5
33*c5c4113dSnw141292 **
34*c5c4113dSnw141292 ** This implemention requires years to be expressed as a 4-digit number
35*c5c4113dSnw141292 ** which means that only dates between 0000-01-01 and 9999-12-31 can
36*c5c4113dSnw141292 ** be represented, even though julian day numbers allow a much wider
37*c5c4113dSnw141292 ** range of dates.
38*c5c4113dSnw141292 **
39*c5c4113dSnw141292 ** The Gregorian calendar system is used for all dates and times,
40*c5c4113dSnw141292 ** even those that predate the Gregorian calendar.  Historians usually
41*c5c4113dSnw141292 ** use the Julian calendar for dates prior to 1582-10-15 and for some
42*c5c4113dSnw141292 ** dates afterwards, depending on locale.  Beware of this difference.
43*c5c4113dSnw141292 **
44*c5c4113dSnw141292 ** The conversion algorithms are implemented based on descriptions
45*c5c4113dSnw141292 ** in the following text:
46*c5c4113dSnw141292 **
47*c5c4113dSnw141292 **      Jean Meeus
48*c5c4113dSnw141292 **      Astronomical Algorithms, 2nd Edition, 1998
49*c5c4113dSnw141292 **      ISBM 0-943396-61-1
50*c5c4113dSnw141292 **      Willmann-Bell, Inc
51*c5c4113dSnw141292 **      Richmond, Virginia (USA)
52*c5c4113dSnw141292 */
53*c5c4113dSnw141292 #include "os.h"
54*c5c4113dSnw141292 #include "sqliteInt.h"
55*c5c4113dSnw141292 #include <ctype.h>
56*c5c4113dSnw141292 #include <stdlib.h>
57*c5c4113dSnw141292 #include <assert.h>
58*c5c4113dSnw141292 #include <time.h>
59*c5c4113dSnw141292 
60*c5c4113dSnw141292 #ifndef SQLITE_OMIT_DATETIME_FUNCS
61*c5c4113dSnw141292 
62*c5c4113dSnw141292 /*
63*c5c4113dSnw141292 ** A structure for holding a single date and time.
64*c5c4113dSnw141292 */
65*c5c4113dSnw141292 typedef struct DateTime DateTime;
66*c5c4113dSnw141292 struct DateTime {
67*c5c4113dSnw141292   double rJD;      /* The julian day number */
68*c5c4113dSnw141292   int Y, M, D;     /* Year, month, and day */
69*c5c4113dSnw141292   int h, m;        /* Hour and minutes */
70*c5c4113dSnw141292   int tz;          /* Timezone offset in minutes */
71*c5c4113dSnw141292   double s;        /* Seconds */
72*c5c4113dSnw141292   char validYMD;   /* True if Y,M,D are valid */
73*c5c4113dSnw141292   char validHMS;   /* True if h,m,s are valid */
74*c5c4113dSnw141292   char validJD;    /* True if rJD is valid */
75*c5c4113dSnw141292   char validTZ;    /* True if tz is valid */
76*c5c4113dSnw141292 };
77*c5c4113dSnw141292 
78*c5c4113dSnw141292 
79*c5c4113dSnw141292 /*
80*c5c4113dSnw141292 ** Convert zDate into one or more integers.  Additional arguments
81*c5c4113dSnw141292 ** come in groups of 5 as follows:
82*c5c4113dSnw141292 **
83*c5c4113dSnw141292 **       N       number of digits in the integer
84*c5c4113dSnw141292 **       min     minimum allowed value of the integer
85*c5c4113dSnw141292 **       max     maximum allowed value of the integer
86*c5c4113dSnw141292 **       nextC   first character after the integer
87*c5c4113dSnw141292 **       pVal    where to write the integers value.
88*c5c4113dSnw141292 **
89*c5c4113dSnw141292 ** Conversions continue until one with nextC==0 is encountered.
90*c5c4113dSnw141292 ** The function returns the number of successful conversions.
91*c5c4113dSnw141292 */
getDigits(const char * zDate,...)92*c5c4113dSnw141292 static int getDigits(const char *zDate, ...){
93*c5c4113dSnw141292   va_list ap;
94*c5c4113dSnw141292   int val;
95*c5c4113dSnw141292   int N;
96*c5c4113dSnw141292   int min;
97*c5c4113dSnw141292   int max;
98*c5c4113dSnw141292   int nextC;
99*c5c4113dSnw141292   int *pVal;
100*c5c4113dSnw141292   int cnt = 0;
101*c5c4113dSnw141292   va_start(ap, zDate);
102*c5c4113dSnw141292   do{
103*c5c4113dSnw141292     N = va_arg(ap, int);
104*c5c4113dSnw141292     min = va_arg(ap, int);
105*c5c4113dSnw141292     max = va_arg(ap, int);
106*c5c4113dSnw141292     nextC = va_arg(ap, int);
107*c5c4113dSnw141292     pVal = va_arg(ap, int*);
108*c5c4113dSnw141292     val = 0;
109*c5c4113dSnw141292     while( N-- ){
110*c5c4113dSnw141292       if( !isdigit(*zDate) ){
111*c5c4113dSnw141292         return cnt;
112*c5c4113dSnw141292       }
113*c5c4113dSnw141292       val = val*10 + *zDate - '0';
114*c5c4113dSnw141292       zDate++;
115*c5c4113dSnw141292     }
116*c5c4113dSnw141292     if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
117*c5c4113dSnw141292       return cnt;
118*c5c4113dSnw141292     }
119*c5c4113dSnw141292     *pVal = val;
120*c5c4113dSnw141292     zDate++;
121*c5c4113dSnw141292     cnt++;
122*c5c4113dSnw141292   }while( nextC );
123*c5c4113dSnw141292   return cnt;
124*c5c4113dSnw141292 }
125*c5c4113dSnw141292 
126*c5c4113dSnw141292 /*
127*c5c4113dSnw141292 ** Read text from z[] and convert into a floating point number.  Return
128*c5c4113dSnw141292 ** the number of digits converted.
129*c5c4113dSnw141292 */
getValue(const char * z,double * pR)130*c5c4113dSnw141292 static int getValue(const char *z, double *pR){
131*c5c4113dSnw141292   const char *zEnd;
132*c5c4113dSnw141292   *pR = sqliteAtoF(z, &zEnd);
133*c5c4113dSnw141292   return zEnd - z;
134*c5c4113dSnw141292 }
135*c5c4113dSnw141292 
136*c5c4113dSnw141292 /*
137*c5c4113dSnw141292 ** Parse a timezone extension on the end of a date-time.
138*c5c4113dSnw141292 ** The extension is of the form:
139*c5c4113dSnw141292 **
140*c5c4113dSnw141292 **        (+/-)HH:MM
141*c5c4113dSnw141292 **
142*c5c4113dSnw141292 ** If the parse is successful, write the number of minutes
143*c5c4113dSnw141292 ** of change in *pnMin and return 0.  If a parser error occurs,
144*c5c4113dSnw141292 ** return 0.
145*c5c4113dSnw141292 **
146*c5c4113dSnw141292 ** A missing specifier is not considered an error.
147*c5c4113dSnw141292 */
parseTimezone(const char * zDate,DateTime * p)148*c5c4113dSnw141292 static int parseTimezone(const char *zDate, DateTime *p){
149*c5c4113dSnw141292   int sgn = 0;
150*c5c4113dSnw141292   int nHr, nMn;
151*c5c4113dSnw141292   while( isspace(*zDate) ){ zDate++; }
152*c5c4113dSnw141292   p->tz = 0;
153*c5c4113dSnw141292   if( *zDate=='-' ){
154*c5c4113dSnw141292     sgn = -1;
155*c5c4113dSnw141292   }else if( *zDate=='+' ){
156*c5c4113dSnw141292     sgn = +1;
157*c5c4113dSnw141292   }else{
158*c5c4113dSnw141292     return *zDate!=0;
159*c5c4113dSnw141292   }
160*c5c4113dSnw141292   zDate++;
161*c5c4113dSnw141292   if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
162*c5c4113dSnw141292     return 1;
163*c5c4113dSnw141292   }
164*c5c4113dSnw141292   zDate += 5;
165*c5c4113dSnw141292   p->tz = sgn*(nMn + nHr*60);
166*c5c4113dSnw141292   while( isspace(*zDate) ){ zDate++; }
167*c5c4113dSnw141292   return *zDate!=0;
168*c5c4113dSnw141292 }
169*c5c4113dSnw141292 
170*c5c4113dSnw141292 /*
171*c5c4113dSnw141292 ** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
172*c5c4113dSnw141292 ** The HH, MM, and SS must each be exactly 2 digits.  The
173*c5c4113dSnw141292 ** fractional seconds FFFF can be one or more digits.
174*c5c4113dSnw141292 **
175*c5c4113dSnw141292 ** Return 1 if there is a parsing error and 0 on success.
176*c5c4113dSnw141292 */
parseHhMmSs(const char * zDate,DateTime * p)177*c5c4113dSnw141292 static int parseHhMmSs(const char *zDate, DateTime *p){
178*c5c4113dSnw141292   int h, m, s;
179*c5c4113dSnw141292   double ms = 0.0;
180*c5c4113dSnw141292   if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){
181*c5c4113dSnw141292     return 1;
182*c5c4113dSnw141292   }
183*c5c4113dSnw141292   zDate += 5;
184*c5c4113dSnw141292   if( *zDate==':' ){
185*c5c4113dSnw141292     zDate++;
186*c5c4113dSnw141292     if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
187*c5c4113dSnw141292       return 1;
188*c5c4113dSnw141292     }
189*c5c4113dSnw141292     zDate += 2;
190*c5c4113dSnw141292     if( *zDate=='.' && isdigit(zDate[1]) ){
191*c5c4113dSnw141292       double rScale = 1.0;
192*c5c4113dSnw141292       zDate++;
193*c5c4113dSnw141292       while( isdigit(*zDate) ){
194*c5c4113dSnw141292         ms = ms*10.0 + *zDate - '0';
195*c5c4113dSnw141292         rScale *= 10.0;
196*c5c4113dSnw141292         zDate++;
197*c5c4113dSnw141292       }
198*c5c4113dSnw141292       ms /= rScale;
199*c5c4113dSnw141292     }
200*c5c4113dSnw141292   }else{
201*c5c4113dSnw141292     s = 0;
202*c5c4113dSnw141292   }
203*c5c4113dSnw141292   p->validJD = 0;
204*c5c4113dSnw141292   p->validHMS = 1;
205*c5c4113dSnw141292   p->h = h;
206*c5c4113dSnw141292   p->m = m;
207*c5c4113dSnw141292   p->s = s + ms;
208*c5c4113dSnw141292   if( parseTimezone(zDate, p) ) return 1;
209*c5c4113dSnw141292   p->validTZ = p->tz!=0;
210*c5c4113dSnw141292   return 0;
211*c5c4113dSnw141292 }
212*c5c4113dSnw141292 
213*c5c4113dSnw141292 /*
214*c5c4113dSnw141292 ** Convert from YYYY-MM-DD HH:MM:SS to julian day.  We always assume
215*c5c4113dSnw141292 ** that the YYYY-MM-DD is according to the Gregorian calendar.
216*c5c4113dSnw141292 **
217*c5c4113dSnw141292 ** Reference:  Meeus page 61
218*c5c4113dSnw141292 */
computeJD(DateTime * p)219*c5c4113dSnw141292 static void computeJD(DateTime *p){
220*c5c4113dSnw141292   int Y, M, D, A, B, X1, X2;
221*c5c4113dSnw141292 
222*c5c4113dSnw141292   if( p->validJD ) return;
223*c5c4113dSnw141292   if( p->validYMD ){
224*c5c4113dSnw141292     Y = p->Y;
225*c5c4113dSnw141292     M = p->M;
226*c5c4113dSnw141292     D = p->D;
227*c5c4113dSnw141292   }else{
228*c5c4113dSnw141292     Y = 2000;  /* If no YMD specified, assume 2000-Jan-01 */
229*c5c4113dSnw141292     M = 1;
230*c5c4113dSnw141292     D = 1;
231*c5c4113dSnw141292   }
232*c5c4113dSnw141292   if( M<=2 ){
233*c5c4113dSnw141292     Y--;
234*c5c4113dSnw141292     M += 12;
235*c5c4113dSnw141292   }
236*c5c4113dSnw141292   A = Y/100;
237*c5c4113dSnw141292   B = 2 - A + (A/4);
238*c5c4113dSnw141292   X1 = 365.25*(Y+4716);
239*c5c4113dSnw141292   X2 = 30.6001*(M+1);
240*c5c4113dSnw141292   p->rJD = X1 + X2 + D + B - 1524.5;
241*c5c4113dSnw141292   p->validJD = 1;
242*c5c4113dSnw141292   p->validYMD = 0;
243*c5c4113dSnw141292   if( p->validHMS ){
244*c5c4113dSnw141292     p->rJD += (p->h*3600.0 + p->m*60.0 + p->s)/86400.0;
245*c5c4113dSnw141292     if( p->validTZ ){
246*c5c4113dSnw141292       p->rJD += p->tz*60/86400.0;
247*c5c4113dSnw141292       p->validHMS = 0;
248*c5c4113dSnw141292       p->validTZ = 0;
249*c5c4113dSnw141292     }
250*c5c4113dSnw141292   }
251*c5c4113dSnw141292 }
252*c5c4113dSnw141292 
253*c5c4113dSnw141292 /*
254*c5c4113dSnw141292 ** Parse dates of the form
255*c5c4113dSnw141292 **
256*c5c4113dSnw141292 **     YYYY-MM-DD HH:MM:SS.FFF
257*c5c4113dSnw141292 **     YYYY-MM-DD HH:MM:SS
258*c5c4113dSnw141292 **     YYYY-MM-DD HH:MM
259*c5c4113dSnw141292 **     YYYY-MM-DD
260*c5c4113dSnw141292 **
261*c5c4113dSnw141292 ** Write the result into the DateTime structure and return 0
262*c5c4113dSnw141292 ** on success and 1 if the input string is not a well-formed
263*c5c4113dSnw141292 ** date.
264*c5c4113dSnw141292 */
parseYyyyMmDd(const char * zDate,DateTime * p)265*c5c4113dSnw141292 static int parseYyyyMmDd(const char *zDate, DateTime *p){
266*c5c4113dSnw141292   int Y, M, D, neg;
267*c5c4113dSnw141292 
268*c5c4113dSnw141292   if( zDate[0]=='-' ){
269*c5c4113dSnw141292     zDate++;
270*c5c4113dSnw141292     neg = 1;
271*c5c4113dSnw141292   }else{
272*c5c4113dSnw141292     neg = 0;
273*c5c4113dSnw141292   }
274*c5c4113dSnw141292   if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
275*c5c4113dSnw141292     return 1;
276*c5c4113dSnw141292   }
277*c5c4113dSnw141292   zDate += 10;
278*c5c4113dSnw141292   while( isspace(*zDate) ){ zDate++; }
279*c5c4113dSnw141292   if( parseHhMmSs(zDate, p)==0 ){
280*c5c4113dSnw141292     /* We got the time */
281*c5c4113dSnw141292   }else if( *zDate==0 ){
282*c5c4113dSnw141292     p->validHMS = 0;
283*c5c4113dSnw141292   }else{
284*c5c4113dSnw141292     return 1;
285*c5c4113dSnw141292   }
286*c5c4113dSnw141292   p->validJD = 0;
287*c5c4113dSnw141292   p->validYMD = 1;
288*c5c4113dSnw141292   p->Y = neg ? -Y : Y;
289*c5c4113dSnw141292   p->M = M;
290*c5c4113dSnw141292   p->D = D;
291*c5c4113dSnw141292   if( p->validTZ ){
292*c5c4113dSnw141292     computeJD(p);
293*c5c4113dSnw141292   }
294*c5c4113dSnw141292   return 0;
295*c5c4113dSnw141292 }
296*c5c4113dSnw141292 
297*c5c4113dSnw141292 /*
298*c5c4113dSnw141292 ** Attempt to parse the given string into a Julian Day Number.  Return
299*c5c4113dSnw141292 ** the number of errors.
300*c5c4113dSnw141292 **
301*c5c4113dSnw141292 ** The following are acceptable forms for the input string:
302*c5c4113dSnw141292 **
303*c5c4113dSnw141292 **      YYYY-MM-DD HH:MM:SS.FFF  +/-HH:MM
304*c5c4113dSnw141292 **      DDDD.DD
305*c5c4113dSnw141292 **      now
306*c5c4113dSnw141292 **
307*c5c4113dSnw141292 ** In the first form, the +/-HH:MM is always optional.  The fractional
308*c5c4113dSnw141292 ** seconds extension (the ".FFF") is optional.  The seconds portion
309*c5c4113dSnw141292 ** (":SS.FFF") is option.  The year and date can be omitted as long
310*c5c4113dSnw141292 ** as there is a time string.  The time string can be omitted as long
311*c5c4113dSnw141292 ** as there is a year and date.
312*c5c4113dSnw141292 */
parseDateOrTime(const char * zDate,DateTime * p)313*c5c4113dSnw141292 static int parseDateOrTime(const char *zDate, DateTime *p){
314*c5c4113dSnw141292   memset(p, 0, sizeof(*p));
315*c5c4113dSnw141292   if( parseYyyyMmDd(zDate,p)==0 ){
316*c5c4113dSnw141292     return 0;
317*c5c4113dSnw141292   }else if( parseHhMmSs(zDate, p)==0 ){
318*c5c4113dSnw141292     return 0;
319*c5c4113dSnw141292   }else if( sqliteStrICmp(zDate,"now")==0){
320*c5c4113dSnw141292     double r;
321*c5c4113dSnw141292     if( sqliteOsCurrentTime(&r)==0 ){
322*c5c4113dSnw141292       p->rJD = r;
323*c5c4113dSnw141292       p->validJD = 1;
324*c5c4113dSnw141292       return 0;
325*c5c4113dSnw141292     }
326*c5c4113dSnw141292     return 1;
327*c5c4113dSnw141292   }else if( sqliteIsNumber(zDate) ){
328*c5c4113dSnw141292     p->rJD = sqliteAtoF(zDate, 0);
329*c5c4113dSnw141292     p->validJD = 1;
330*c5c4113dSnw141292     return 0;
331*c5c4113dSnw141292   }
332*c5c4113dSnw141292   return 1;
333*c5c4113dSnw141292 }
334*c5c4113dSnw141292 
335*c5c4113dSnw141292 /*
336*c5c4113dSnw141292 ** Compute the Year, Month, and Day from the julian day number.
337*c5c4113dSnw141292 */
computeYMD(DateTime * p)338*c5c4113dSnw141292 static void computeYMD(DateTime *p){
339*c5c4113dSnw141292   int Z, A, B, C, D, E, X1;
340*c5c4113dSnw141292   if( p->validYMD ) return;
341*c5c4113dSnw141292   if( !p->validJD ){
342*c5c4113dSnw141292     p->Y = 2000;
343*c5c4113dSnw141292     p->M = 1;
344*c5c4113dSnw141292     p->D = 1;
345*c5c4113dSnw141292   }else{
346*c5c4113dSnw141292     Z = p->rJD + 0.5;
347*c5c4113dSnw141292     A = (Z - 1867216.25)/36524.25;
348*c5c4113dSnw141292     A = Z + 1 + A - (A/4);
349*c5c4113dSnw141292     B = A + 1524;
350*c5c4113dSnw141292     C = (B - 122.1)/365.25;
351*c5c4113dSnw141292     D = 365.25*C;
352*c5c4113dSnw141292     E = (B-D)/30.6001;
353*c5c4113dSnw141292     X1 = 30.6001*E;
354*c5c4113dSnw141292     p->D = B - D - X1;
355*c5c4113dSnw141292     p->M = E<14 ? E-1 : E-13;
356*c5c4113dSnw141292     p->Y = p->M>2 ? C - 4716 : C - 4715;
357*c5c4113dSnw141292   }
358*c5c4113dSnw141292   p->validYMD = 1;
359*c5c4113dSnw141292 }
360*c5c4113dSnw141292 
361*c5c4113dSnw141292 /*
362*c5c4113dSnw141292 ** Compute the Hour, Minute, and Seconds from the julian day number.
363*c5c4113dSnw141292 */
computeHMS(DateTime * p)364*c5c4113dSnw141292 static void computeHMS(DateTime *p){
365*c5c4113dSnw141292   int Z, s;
366*c5c4113dSnw141292   if( p->validHMS ) return;
367*c5c4113dSnw141292   Z = p->rJD + 0.5;
368*c5c4113dSnw141292   s = (p->rJD + 0.5 - Z)*86400000.0 + 0.5;
369*c5c4113dSnw141292   p->s = 0.001*s;
370*c5c4113dSnw141292   s = p->s;
371*c5c4113dSnw141292   p->s -= s;
372*c5c4113dSnw141292   p->h = s/3600;
373*c5c4113dSnw141292   s -= p->h*3600;
374*c5c4113dSnw141292   p->m = s/60;
375*c5c4113dSnw141292   p->s += s - p->m*60;
376*c5c4113dSnw141292   p->validHMS = 1;
377*c5c4113dSnw141292 }
378*c5c4113dSnw141292 
379*c5c4113dSnw141292 /*
380*c5c4113dSnw141292 ** Compute both YMD and HMS
381*c5c4113dSnw141292 */
computeYMD_HMS(DateTime * p)382*c5c4113dSnw141292 static void computeYMD_HMS(DateTime *p){
383*c5c4113dSnw141292   computeYMD(p);
384*c5c4113dSnw141292   computeHMS(p);
385*c5c4113dSnw141292 }
386*c5c4113dSnw141292 
387*c5c4113dSnw141292 /*
388*c5c4113dSnw141292 ** Clear the YMD and HMS and the TZ
389*c5c4113dSnw141292 */
clearYMD_HMS_TZ(DateTime * p)390*c5c4113dSnw141292 static void clearYMD_HMS_TZ(DateTime *p){
391*c5c4113dSnw141292   p->validYMD = 0;
392*c5c4113dSnw141292   p->validHMS = 0;
393*c5c4113dSnw141292   p->validTZ = 0;
394*c5c4113dSnw141292 }
395*c5c4113dSnw141292 
396*c5c4113dSnw141292 /*
397*c5c4113dSnw141292 ** Compute the difference (in days) between localtime and UTC (a.k.a. GMT)
398*c5c4113dSnw141292 ** for the time value p where p is in UTC.
399*c5c4113dSnw141292 */
localtimeOffset(DateTime * p)400*c5c4113dSnw141292 static double localtimeOffset(DateTime *p){
401*c5c4113dSnw141292   DateTime x, y;
402*c5c4113dSnw141292   time_t t;
403*c5c4113dSnw141292   struct tm *pTm;
404*c5c4113dSnw141292   x = *p;
405*c5c4113dSnw141292   computeYMD_HMS(&x);
406*c5c4113dSnw141292   if( x.Y<1971 || x.Y>=2038 ){
407*c5c4113dSnw141292     x.Y = 2000;
408*c5c4113dSnw141292     x.M = 1;
409*c5c4113dSnw141292     x.D = 1;
410*c5c4113dSnw141292     x.h = 0;
411*c5c4113dSnw141292     x.m = 0;
412*c5c4113dSnw141292     x.s = 0.0;
413*c5c4113dSnw141292   } else {
414*c5c4113dSnw141292     int s = x.s + 0.5;
415*c5c4113dSnw141292     x.s = s;
416*c5c4113dSnw141292   }
417*c5c4113dSnw141292   x.tz = 0;
418*c5c4113dSnw141292   x.validJD = 0;
419*c5c4113dSnw141292   computeJD(&x);
420*c5c4113dSnw141292   t = (x.rJD-2440587.5)*86400.0 + 0.5;
421*c5c4113dSnw141292   sqliteOsEnterMutex();
422*c5c4113dSnw141292   pTm = localtime(&t);
423*c5c4113dSnw141292   y.Y = pTm->tm_year + 1900;
424*c5c4113dSnw141292   y.M = pTm->tm_mon + 1;
425*c5c4113dSnw141292   y.D = pTm->tm_mday;
426*c5c4113dSnw141292   y.h = pTm->tm_hour;
427*c5c4113dSnw141292   y.m = pTm->tm_min;
428*c5c4113dSnw141292   y.s = pTm->tm_sec;
429*c5c4113dSnw141292   sqliteOsLeaveMutex();
430*c5c4113dSnw141292   y.validYMD = 1;
431*c5c4113dSnw141292   y.validHMS = 1;
432*c5c4113dSnw141292   y.validJD = 0;
433*c5c4113dSnw141292   y.validTZ = 0;
434*c5c4113dSnw141292   computeJD(&y);
435*c5c4113dSnw141292   return y.rJD - x.rJD;
436*c5c4113dSnw141292 }
437*c5c4113dSnw141292 
438*c5c4113dSnw141292 /*
439*c5c4113dSnw141292 ** Process a modifier to a date-time stamp.  The modifiers are
440*c5c4113dSnw141292 ** as follows:
441*c5c4113dSnw141292 **
442*c5c4113dSnw141292 **     NNN days
443*c5c4113dSnw141292 **     NNN hours
444*c5c4113dSnw141292 **     NNN minutes
445*c5c4113dSnw141292 **     NNN.NNNN seconds
446*c5c4113dSnw141292 **     NNN months
447*c5c4113dSnw141292 **     NNN years
448*c5c4113dSnw141292 **     start of month
449*c5c4113dSnw141292 **     start of year
450*c5c4113dSnw141292 **     start of week
451*c5c4113dSnw141292 **     start of day
452*c5c4113dSnw141292 **     weekday N
453*c5c4113dSnw141292 **     unixepoch
454*c5c4113dSnw141292 **     localtime
455*c5c4113dSnw141292 **     utc
456*c5c4113dSnw141292 **
457*c5c4113dSnw141292 ** Return 0 on success and 1 if there is any kind of error.
458*c5c4113dSnw141292 */
parseModifier(const char * zMod,DateTime * p)459*c5c4113dSnw141292 static int parseModifier(const char *zMod, DateTime *p){
460*c5c4113dSnw141292   int rc = 1;
461*c5c4113dSnw141292   int n;
462*c5c4113dSnw141292   double r;
463*c5c4113dSnw141292   char *z, zBuf[30];
464*c5c4113dSnw141292   z = zBuf;
465*c5c4113dSnw141292   for(n=0; n<sizeof(zBuf)-1 && zMod[n]; n++){
466*c5c4113dSnw141292     z[n] = tolower(zMod[n]);
467*c5c4113dSnw141292   }
468*c5c4113dSnw141292   z[n] = 0;
469*c5c4113dSnw141292   switch( z[0] ){
470*c5c4113dSnw141292     case 'l': {
471*c5c4113dSnw141292       /*    localtime
472*c5c4113dSnw141292       **
473*c5c4113dSnw141292       ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
474*c5c4113dSnw141292       ** show local time.
475*c5c4113dSnw141292       */
476*c5c4113dSnw141292       if( strcmp(z, "localtime")==0 ){
477*c5c4113dSnw141292         computeJD(p);
478*c5c4113dSnw141292         p->rJD += localtimeOffset(p);
479*c5c4113dSnw141292         clearYMD_HMS_TZ(p);
480*c5c4113dSnw141292         rc = 0;
481*c5c4113dSnw141292       }
482*c5c4113dSnw141292       break;
483*c5c4113dSnw141292     }
484*c5c4113dSnw141292     case 'u': {
485*c5c4113dSnw141292       /*
486*c5c4113dSnw141292       **    unixepoch
487*c5c4113dSnw141292       **
488*c5c4113dSnw141292       ** Treat the current value of p->rJD as the number of
489*c5c4113dSnw141292       ** seconds since 1970.  Convert to a real julian day number.
490*c5c4113dSnw141292       */
491*c5c4113dSnw141292       if( strcmp(z, "unixepoch")==0 && p->validJD ){
492*c5c4113dSnw141292         p->rJD = p->rJD/86400.0 + 2440587.5;
493*c5c4113dSnw141292         clearYMD_HMS_TZ(p);
494*c5c4113dSnw141292         rc = 0;
495*c5c4113dSnw141292       }else if( strcmp(z, "utc")==0 ){
496*c5c4113dSnw141292         double c1;
497*c5c4113dSnw141292         computeJD(p);
498*c5c4113dSnw141292         c1 = localtimeOffset(p);
499*c5c4113dSnw141292         p->rJD -= c1;
500*c5c4113dSnw141292         clearYMD_HMS_TZ(p);
501*c5c4113dSnw141292         p->rJD += c1 - localtimeOffset(p);
502*c5c4113dSnw141292         rc = 0;
503*c5c4113dSnw141292       }
504*c5c4113dSnw141292       break;
505*c5c4113dSnw141292     }
506*c5c4113dSnw141292     case 'w': {
507*c5c4113dSnw141292       /*
508*c5c4113dSnw141292       **    weekday N
509*c5c4113dSnw141292       **
510*c5c4113dSnw141292       ** Move the date to the same time on the next occurrance of
511*c5c4113dSnw141292       ** weekday N where 0==Sunday, 1==Monday, and so forth.  If the
512*c5c4113dSnw141292       ** date is already on the appropriate weekday, this is a no-op.
513*c5c4113dSnw141292       */
514*c5c4113dSnw141292       if( strncmp(z, "weekday ", 8)==0 && getValue(&z[8],&r)>0
515*c5c4113dSnw141292                  && (n=r)==r && n>=0 && r<7 ){
516*c5c4113dSnw141292         int Z;
517*c5c4113dSnw141292         computeYMD_HMS(p);
518*c5c4113dSnw141292         p->validTZ = 0;
519*c5c4113dSnw141292         p->validJD = 0;
520*c5c4113dSnw141292         computeJD(p);
521*c5c4113dSnw141292         Z = p->rJD + 1.5;
522*c5c4113dSnw141292         Z %= 7;
523*c5c4113dSnw141292         if( Z>n ) Z -= 7;
524*c5c4113dSnw141292         p->rJD += n - Z;
525*c5c4113dSnw141292         clearYMD_HMS_TZ(p);
526*c5c4113dSnw141292         rc = 0;
527*c5c4113dSnw141292       }
528*c5c4113dSnw141292       break;
529*c5c4113dSnw141292     }
530*c5c4113dSnw141292     case 's': {
531*c5c4113dSnw141292       /*
532*c5c4113dSnw141292       **    start of TTTTT
533*c5c4113dSnw141292       **
534*c5c4113dSnw141292       ** Move the date backwards to the beginning of the current day,
535*c5c4113dSnw141292       ** or month or year.
536*c5c4113dSnw141292       */
537*c5c4113dSnw141292       if( strncmp(z, "start of ", 9)!=0 ) break;
538*c5c4113dSnw141292       z += 9;
539*c5c4113dSnw141292       computeYMD(p);
540*c5c4113dSnw141292       p->validHMS = 1;
541*c5c4113dSnw141292       p->h = p->m = 0;
542*c5c4113dSnw141292       p->s = 0.0;
543*c5c4113dSnw141292       p->validTZ = 0;
544*c5c4113dSnw141292       p->validJD = 0;
545*c5c4113dSnw141292       if( strcmp(z,"month")==0 ){
546*c5c4113dSnw141292         p->D = 1;
547*c5c4113dSnw141292         rc = 0;
548*c5c4113dSnw141292       }else if( strcmp(z,"year")==0 ){
549*c5c4113dSnw141292         computeYMD(p);
550*c5c4113dSnw141292         p->M = 1;
551*c5c4113dSnw141292         p->D = 1;
552*c5c4113dSnw141292         rc = 0;
553*c5c4113dSnw141292       }else if( strcmp(z,"day")==0 ){
554*c5c4113dSnw141292         rc = 0;
555*c5c4113dSnw141292       }
556*c5c4113dSnw141292       break;
557*c5c4113dSnw141292     }
558*c5c4113dSnw141292     case '+':
559*c5c4113dSnw141292     case '-':
560*c5c4113dSnw141292     case '0':
561*c5c4113dSnw141292     case '1':
562*c5c4113dSnw141292     case '2':
563*c5c4113dSnw141292     case '3':
564*c5c4113dSnw141292     case '4':
565*c5c4113dSnw141292     case '5':
566*c5c4113dSnw141292     case '6':
567*c5c4113dSnw141292     case '7':
568*c5c4113dSnw141292     case '8':
569*c5c4113dSnw141292     case '9': {
570*c5c4113dSnw141292       n = getValue(z, &r);
571*c5c4113dSnw141292       if( n<=0 ) break;
572*c5c4113dSnw141292       if( z[n]==':' ){
573*c5c4113dSnw141292         /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
574*c5c4113dSnw141292         ** specified number of hours, minutes, seconds, and fractional seconds
575*c5c4113dSnw141292         ** to the time.  The ".FFF" may be omitted.  The ":SS.FFF" may be
576*c5c4113dSnw141292         ** omitted.
577*c5c4113dSnw141292         */
578*c5c4113dSnw141292         const char *z2 = z;
579*c5c4113dSnw141292         DateTime tx;
580*c5c4113dSnw141292         int day;
581*c5c4113dSnw141292         if( !isdigit(*z2) ) z2++;
582*c5c4113dSnw141292         memset(&tx, 0, sizeof(tx));
583*c5c4113dSnw141292         if( parseHhMmSs(z2, &tx) ) break;
584*c5c4113dSnw141292         computeJD(&tx);
585*c5c4113dSnw141292         tx.rJD -= 0.5;
586*c5c4113dSnw141292         day = (int)tx.rJD;
587*c5c4113dSnw141292         tx.rJD -= day;
588*c5c4113dSnw141292         if( z[0]=='-' ) tx.rJD = -tx.rJD;
589*c5c4113dSnw141292         computeJD(p);
590*c5c4113dSnw141292         clearYMD_HMS_TZ(p);
591*c5c4113dSnw141292        p->rJD += tx.rJD;
592*c5c4113dSnw141292         rc = 0;
593*c5c4113dSnw141292         break;
594*c5c4113dSnw141292       }
595*c5c4113dSnw141292       z += n;
596*c5c4113dSnw141292       while( isspace(z[0]) ) z++;
597*c5c4113dSnw141292       n = strlen(z);
598*c5c4113dSnw141292       if( n>10 || n<3 ) break;
599*c5c4113dSnw141292       if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
600*c5c4113dSnw141292       computeJD(p);
601*c5c4113dSnw141292       rc = 0;
602*c5c4113dSnw141292       if( n==3 && strcmp(z,"day")==0 ){
603*c5c4113dSnw141292         p->rJD += r;
604*c5c4113dSnw141292       }else if( n==4 && strcmp(z,"hour")==0 ){
605*c5c4113dSnw141292         p->rJD += r/24.0;
606*c5c4113dSnw141292       }else if( n==6 && strcmp(z,"minute")==0 ){
607*c5c4113dSnw141292         p->rJD += r/(24.0*60.0);
608*c5c4113dSnw141292       }else if( n==6 && strcmp(z,"second")==0 ){
609*c5c4113dSnw141292         p->rJD += r/(24.0*60.0*60.0);
610*c5c4113dSnw141292       }else if( n==5 && strcmp(z,"month")==0 ){
611*c5c4113dSnw141292         int x, y;
612*c5c4113dSnw141292         computeYMD_HMS(p);
613*c5c4113dSnw141292         p->M += r;
614*c5c4113dSnw141292         x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
615*c5c4113dSnw141292         p->Y += x;
616*c5c4113dSnw141292         p->M -= x*12;
617*c5c4113dSnw141292         p->validJD = 0;
618*c5c4113dSnw141292         computeJD(p);
619*c5c4113dSnw141292         y = r;
620*c5c4113dSnw141292         if( y!=r ){
621*c5c4113dSnw141292           p->rJD += (r - y)*30.0;
622*c5c4113dSnw141292         }
623*c5c4113dSnw141292       }else if( n==4 && strcmp(z,"year")==0 ){
624*c5c4113dSnw141292         computeYMD_HMS(p);
625*c5c4113dSnw141292         p->Y += r;
626*c5c4113dSnw141292         p->validJD = 0;
627*c5c4113dSnw141292         computeJD(p);
628*c5c4113dSnw141292       }else{
629*c5c4113dSnw141292         rc = 1;
630*c5c4113dSnw141292       }
631*c5c4113dSnw141292       clearYMD_HMS_TZ(p);
632*c5c4113dSnw141292       break;
633*c5c4113dSnw141292     }
634*c5c4113dSnw141292     default: {
635*c5c4113dSnw141292       break;
636*c5c4113dSnw141292     }
637*c5c4113dSnw141292   }
638*c5c4113dSnw141292   return rc;
639*c5c4113dSnw141292 }
640*c5c4113dSnw141292 
641*c5c4113dSnw141292 /*
642*c5c4113dSnw141292 ** Process time function arguments.  argv[0] is a date-time stamp.
643*c5c4113dSnw141292 ** argv[1] and following are modifiers.  Parse them all and write
644*c5c4113dSnw141292 ** the resulting time into the DateTime structure p.  Return 0
645*c5c4113dSnw141292 ** on success and 1 if there are any errors.
646*c5c4113dSnw141292 */
isDate(int argc,const char ** argv,DateTime * p)647*c5c4113dSnw141292 static int isDate(int argc, const char **argv, DateTime *p){
648*c5c4113dSnw141292   int i;
649*c5c4113dSnw141292   if( argc==0 ) return 1;
650*c5c4113dSnw141292   if( argv[0]==0 || parseDateOrTime(argv[0], p) ) return 1;
651*c5c4113dSnw141292   for(i=1; i<argc; i++){
652*c5c4113dSnw141292     if( argv[i]==0 || parseModifier(argv[i], p) ) return 1;
653*c5c4113dSnw141292   }
654*c5c4113dSnw141292   return 0;
655*c5c4113dSnw141292 }
656*c5c4113dSnw141292 
657*c5c4113dSnw141292 
658*c5c4113dSnw141292 /*
659*c5c4113dSnw141292 ** The following routines implement the various date and time functions
660*c5c4113dSnw141292 ** of SQLite.
661*c5c4113dSnw141292 */
662*c5c4113dSnw141292 
663*c5c4113dSnw141292 /*
664*c5c4113dSnw141292 **    julianday( TIMESTRING, MOD, MOD, ...)
665*c5c4113dSnw141292 **
666*c5c4113dSnw141292 ** Return the julian day number of the date specified in the arguments
667*c5c4113dSnw141292 */
juliandayFunc(sqlite_func * context,int argc,const char ** argv)668*c5c4113dSnw141292 static void juliandayFunc(sqlite_func *context, int argc, const char **argv){
669*c5c4113dSnw141292   DateTime x;
670*c5c4113dSnw141292   if( isDate(argc, argv, &x)==0 ){
671*c5c4113dSnw141292     computeJD(&x);
672*c5c4113dSnw141292     sqlite_set_result_double(context, x.rJD);
673*c5c4113dSnw141292   }
674*c5c4113dSnw141292 }
675*c5c4113dSnw141292 
676*c5c4113dSnw141292 /*
677*c5c4113dSnw141292 **    datetime( TIMESTRING, MOD, MOD, ...)
678*c5c4113dSnw141292 **
679*c5c4113dSnw141292 ** Return YYYY-MM-DD HH:MM:SS
680*c5c4113dSnw141292 */
datetimeFunc(sqlite_func * context,int argc,const char ** argv)681*c5c4113dSnw141292 static void datetimeFunc(sqlite_func *context, int argc, const char **argv){
682*c5c4113dSnw141292   DateTime x;
683*c5c4113dSnw141292   if( isDate(argc, argv, &x)==0 ){
684*c5c4113dSnw141292     char zBuf[100];
685*c5c4113dSnw141292     computeYMD_HMS(&x);
686*c5c4113dSnw141292     sprintf(zBuf, "%04d-%02d-%02d %02d:%02d:%02d",x.Y, x.M, x.D, x.h, x.m,
687*c5c4113dSnw141292            (int)(x.s));
688*c5c4113dSnw141292     sqlite_set_result_string(context, zBuf, -1);
689*c5c4113dSnw141292   }
690*c5c4113dSnw141292 }
691*c5c4113dSnw141292 
692*c5c4113dSnw141292 /*
693*c5c4113dSnw141292 **    time( TIMESTRING, MOD, MOD, ...)
694*c5c4113dSnw141292 **
695*c5c4113dSnw141292 ** Return HH:MM:SS
696*c5c4113dSnw141292 */
timeFunc(sqlite_func * context,int argc,const char ** argv)697*c5c4113dSnw141292 static void timeFunc(sqlite_func *context, int argc, const char **argv){
698*c5c4113dSnw141292   DateTime x;
699*c5c4113dSnw141292   if( isDate(argc, argv, &x)==0 ){
700*c5c4113dSnw141292     char zBuf[100];
701*c5c4113dSnw141292     computeHMS(&x);
702*c5c4113dSnw141292     sprintf(zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
703*c5c4113dSnw141292     sqlite_set_result_string(context, zBuf, -1);
704*c5c4113dSnw141292   }
705*c5c4113dSnw141292 }
706*c5c4113dSnw141292 
707*c5c4113dSnw141292 /*
708*c5c4113dSnw141292 **    date( TIMESTRING, MOD, MOD, ...)
709*c5c4113dSnw141292 **
710*c5c4113dSnw141292 ** Return YYYY-MM-DD
711*c5c4113dSnw141292 */
dateFunc(sqlite_func * context,int argc,const char ** argv)712*c5c4113dSnw141292 static void dateFunc(sqlite_func *context, int argc, const char **argv){
713*c5c4113dSnw141292   DateTime x;
714*c5c4113dSnw141292   if( isDate(argc, argv, &x)==0 ){
715*c5c4113dSnw141292     char zBuf[100];
716*c5c4113dSnw141292     computeYMD(&x);
717*c5c4113dSnw141292     sprintf(zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
718*c5c4113dSnw141292     sqlite_set_result_string(context, zBuf, -1);
719*c5c4113dSnw141292   }
720*c5c4113dSnw141292 }
721*c5c4113dSnw141292 
722*c5c4113dSnw141292 /*
723*c5c4113dSnw141292 **    strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
724*c5c4113dSnw141292 **
725*c5c4113dSnw141292 ** Return a string described by FORMAT.  Conversions as follows:
726*c5c4113dSnw141292 **
727*c5c4113dSnw141292 **   %d  day of month
728*c5c4113dSnw141292 **   %f  ** fractional seconds  SS.SSS
729*c5c4113dSnw141292 **   %H  hour 00-24
730*c5c4113dSnw141292 **   %j  day of year 000-366
731*c5c4113dSnw141292 **   %J  ** Julian day number
732*c5c4113dSnw141292 **   %m  month 01-12
733*c5c4113dSnw141292 **   %M  minute 00-59
734*c5c4113dSnw141292 **   %s  seconds since 1970-01-01
735*c5c4113dSnw141292 **   %S  seconds 00-59
736*c5c4113dSnw141292 **   %w  day of week 0-6  sunday==0
737*c5c4113dSnw141292 **   %W  week of year 00-53
738*c5c4113dSnw141292 **   %Y  year 0000-9999
739*c5c4113dSnw141292 **   %%  %
740*c5c4113dSnw141292 */
strftimeFunc(sqlite_func * context,int argc,const char ** argv)741*c5c4113dSnw141292 static void strftimeFunc(sqlite_func *context, int argc, const char **argv){
742*c5c4113dSnw141292   DateTime x;
743*c5c4113dSnw141292   int n, i, j;
744*c5c4113dSnw141292   char *z;
745*c5c4113dSnw141292   const char *zFmt = argv[0];
746*c5c4113dSnw141292   char zBuf[100];
747*c5c4113dSnw141292   if( argv[0]==0 || isDate(argc-1, argv+1, &x) ) return;
748*c5c4113dSnw141292   for(i=0, n=1; zFmt[i]; i++, n++){
749*c5c4113dSnw141292     if( zFmt[i]=='%' ){
750*c5c4113dSnw141292       switch( zFmt[i+1] ){
751*c5c4113dSnw141292         case 'd':
752*c5c4113dSnw141292         case 'H':
753*c5c4113dSnw141292         case 'm':
754*c5c4113dSnw141292         case 'M':
755*c5c4113dSnw141292         case 'S':
756*c5c4113dSnw141292         case 'W':
757*c5c4113dSnw141292           n++;
758*c5c4113dSnw141292           /* fall thru */
759*c5c4113dSnw141292         case 'w':
760*c5c4113dSnw141292         case '%':
761*c5c4113dSnw141292           break;
762*c5c4113dSnw141292         case 'f':
763*c5c4113dSnw141292           n += 8;
764*c5c4113dSnw141292           break;
765*c5c4113dSnw141292         case 'j':
766*c5c4113dSnw141292           n += 3;
767*c5c4113dSnw141292           break;
768*c5c4113dSnw141292         case 'Y':
769*c5c4113dSnw141292           n += 8;
770*c5c4113dSnw141292           break;
771*c5c4113dSnw141292         case 's':
772*c5c4113dSnw141292         case 'J':
773*c5c4113dSnw141292           n += 50;
774*c5c4113dSnw141292           break;
775*c5c4113dSnw141292         default:
776*c5c4113dSnw141292           return;  /* ERROR.  return a NULL */
777*c5c4113dSnw141292       }
778*c5c4113dSnw141292       i++;
779*c5c4113dSnw141292     }
780*c5c4113dSnw141292   }
781*c5c4113dSnw141292   if( n<sizeof(zBuf) ){
782*c5c4113dSnw141292     z = zBuf;
783*c5c4113dSnw141292   }else{
784*c5c4113dSnw141292     z = sqliteMalloc( n );
785*c5c4113dSnw141292     if( z==0 ) return;
786*c5c4113dSnw141292   }
787*c5c4113dSnw141292   computeJD(&x);
788*c5c4113dSnw141292   computeYMD_HMS(&x);
789*c5c4113dSnw141292   for(i=j=0; zFmt[i]; i++){
790*c5c4113dSnw141292     if( zFmt[i]!='%' ){
791*c5c4113dSnw141292       z[j++] = zFmt[i];
792*c5c4113dSnw141292     }else{
793*c5c4113dSnw141292       i++;
794*c5c4113dSnw141292       switch( zFmt[i] ){
795*c5c4113dSnw141292         case 'd':  sprintf(&z[j],"%02d",x.D); j+=2; break;
796*c5c4113dSnw141292         case 'f': {
797*c5c4113dSnw141292           int s = x.s;
798*c5c4113dSnw141292           int ms = (x.s - s)*1000.0;
799*c5c4113dSnw141292           sprintf(&z[j],"%02d.%03d",s,ms);
800*c5c4113dSnw141292           j += strlen(&z[j]);
801*c5c4113dSnw141292           break;
802*c5c4113dSnw141292         }
803*c5c4113dSnw141292         case 'H':  sprintf(&z[j],"%02d",x.h); j+=2; break;
804*c5c4113dSnw141292         case 'W': /* Fall thru */
805*c5c4113dSnw141292         case 'j': {
806*c5c4113dSnw141292           int n;             /* Number of days since 1st day of year */
807*c5c4113dSnw141292           DateTime y = x;
808*c5c4113dSnw141292           y.validJD = 0;
809*c5c4113dSnw141292           y.M = 1;
810*c5c4113dSnw141292           y.D = 1;
811*c5c4113dSnw141292           computeJD(&y);
812*c5c4113dSnw141292           n = x.rJD - y.rJD;
813*c5c4113dSnw141292           if( zFmt[i]=='W' ){
814*c5c4113dSnw141292             int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
815*c5c4113dSnw141292             wd = ((int)(x.rJD+0.5)) % 7;
816*c5c4113dSnw141292             sprintf(&z[j],"%02d",(n+7-wd)/7);
817*c5c4113dSnw141292             j += 2;
818*c5c4113dSnw141292           }else{
819*c5c4113dSnw141292             sprintf(&z[j],"%03d",n+1);
820*c5c4113dSnw141292             j += 3;
821*c5c4113dSnw141292           }
822*c5c4113dSnw141292           break;
823*c5c4113dSnw141292         }
824*c5c4113dSnw141292         case 'J':  sprintf(&z[j],"%.16g",x.rJD); j+=strlen(&z[j]); break;
825*c5c4113dSnw141292         case 'm':  sprintf(&z[j],"%02d",x.M); j+=2; break;
826*c5c4113dSnw141292         case 'M':  sprintf(&z[j],"%02d",x.m); j+=2; break;
827*c5c4113dSnw141292         case 's': {
828*c5c4113dSnw141292           sprintf(&z[j],"%d",(int)((x.rJD-2440587.5)*86400.0 + 0.5));
829*c5c4113dSnw141292           j += strlen(&z[j]);
830*c5c4113dSnw141292           break;
831*c5c4113dSnw141292         }
832*c5c4113dSnw141292         case 'S':  sprintf(&z[j],"%02d",(int)(x.s+0.5)); j+=2; break;
833*c5c4113dSnw141292         case 'w':  z[j++] = (((int)(x.rJD+1.5)) % 7) + '0'; break;
834*c5c4113dSnw141292         case 'Y':  sprintf(&z[j],"%04d",x.Y); j+=strlen(&z[j]); break;
835*c5c4113dSnw141292         case '%':  z[j++] = '%'; break;
836*c5c4113dSnw141292       }
837*c5c4113dSnw141292     }
838*c5c4113dSnw141292   }
839*c5c4113dSnw141292   z[j] = 0;
840*c5c4113dSnw141292   sqlite_set_result_string(context, z, -1);
841*c5c4113dSnw141292   if( z!=zBuf ){
842*c5c4113dSnw141292     sqliteFree(z);
843*c5c4113dSnw141292   }
844*c5c4113dSnw141292 }
845*c5c4113dSnw141292 
846*c5c4113dSnw141292 
847*c5c4113dSnw141292 #endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */
848*c5c4113dSnw141292 
849*c5c4113dSnw141292 /*
850*c5c4113dSnw141292 ** This function registered all of the above C functions as SQL
851*c5c4113dSnw141292 ** functions.  This should be the only routine in this file with
852*c5c4113dSnw141292 ** external linkage.
853*c5c4113dSnw141292 */
sqliteRegisterDateTimeFunctions(sqlite * db)854*c5c4113dSnw141292 void sqliteRegisterDateTimeFunctions(sqlite *db){
855*c5c4113dSnw141292 #ifndef SQLITE_OMIT_DATETIME_FUNCS
856*c5c4113dSnw141292   static struct {
857*c5c4113dSnw141292      char *zName;
858*c5c4113dSnw141292      int nArg;
859*c5c4113dSnw141292      int dataType;
860*c5c4113dSnw141292      void (*xFunc)(sqlite_func*,int,const char**);
861*c5c4113dSnw141292   } aFuncs[] = {
862*c5c4113dSnw141292     { "julianday", -1, SQLITE_NUMERIC, juliandayFunc   },
863*c5c4113dSnw141292     { "date",      -1, SQLITE_TEXT,    dateFunc        },
864*c5c4113dSnw141292     { "time",      -1, SQLITE_TEXT,    timeFunc        },
865*c5c4113dSnw141292     { "datetime",  -1, SQLITE_TEXT,    datetimeFunc    },
866*c5c4113dSnw141292     { "strftime",  -1, SQLITE_TEXT,    strftimeFunc    },
867*c5c4113dSnw141292   };
868*c5c4113dSnw141292   int i;
869*c5c4113dSnw141292 
870*c5c4113dSnw141292   for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
871*c5c4113dSnw141292     sqlite_create_function(db, aFuncs[i].zName,
872*c5c4113dSnw141292            aFuncs[i].nArg, aFuncs[i].xFunc, 0);
873*c5c4113dSnw141292     if( aFuncs[i].xFunc ){
874*c5c4113dSnw141292       sqlite_function_type(db, aFuncs[i].zName, aFuncs[i].dataType);
875*c5c4113dSnw141292     }
876*c5c4113dSnw141292   }
877*c5c4113dSnw141292 #endif
878*c5c4113dSnw141292 }
879