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