/ Check-in [a5a5fbd6]
Login
Overview
Comment:Update date/time functions so that they correctly handle NULL arguments. (CVS 1147)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:a5a5fbd60153dd068ec2559455146e84da075b90
User & Date: drh 2003-12-23 16:34:13
Context
2003-12-24
01:41
minor edits for new date.c with mingw/msys on Windows (CVS 1148) check-in: 9392c514 user: dougcurrie tags: trunk
2003-12-23
16:34
Update date/time functions so that they correctly handle NULL arguments. (CVS 1147) check-in: a5a5fbd6 user: drh tags: trunk
16:22
Add localtime<-->UTC conversions to the date functions. (CVS 1146) check-in: 8482b8c4 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/date.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
...
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
...
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
** This file contains the C functions that implement date and time
** functions for SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: date.c,v 1.3 2003/12/23 16:22:18 drh Exp $
**
** NOTES:
**
** SQLite processes all times and dates as Julian Day numbers.  The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
** calendar system.
................................................................................
** argv[1] and following are modifiers.  Parse them all and write
** the resulting time into the DateTime structure p.  Return 0
** on success and 1 if there are any errors.
*/
static int isDate(int argc, const char **argv, DateTime *p){
  int i;
  if( argc==0 ) return 1;
  if( parseDateOrTime(argv[0], p) ) return 1;
  for(i=1; i<argc; i++){
    if( parseModifier(argv[i], p) ) return 1;
  }
  return 0;
}


/*
** The following routines implement the various date and time functions
................................................................................
*/
static void strftimeFunc(sqlite_func *context, int argc, const char **argv){
  DateTime x;
  int n, i, j;
  char *z;
  const char *zFmt = argv[0];
  char zBuf[100];
  if( isDate(argc-1, argv+1, &x) ) return;
  for(i=0, n=1; zFmt[i]; i++, n++){
    if( zFmt[i]=='%' ){
      switch( zFmt[i+1] ){
        case 'd':
        case 'H':
        case 'm':
        case 'M':
................................................................................
     int nArg;
     int dataType;
     void (*xFunc)(sqlite_func*,int,const char**);
  } aFuncs[] = {
#ifndef SQLITE_OMIT_DATETIME_FUNCS
    { "julianday", -1, SQLITE_NUMERIC, juliandayFunc   },
    { "date",      -1, SQLITE_TEXT,    dateFunc        },
    { "time",       1, SQLITE_TEXT,    timeFunc        },
    { "datetime",  -1, SQLITE_TEXT,    datetimeFunc    },
    { "strftime",  -1, SQLITE_TEXT,    strftimeFunc    },
#endif
  };
  int i;

  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){







|







 







|

|







 







|







 







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
...
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
...
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
** This file contains the C functions that implement date and time
** functions for SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: date.c,v 1.4 2003/12/23 16:34:13 drh Exp $
**
** NOTES:
**
** SQLite processes all times and dates as Julian Day numbers.  The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
** calendar system.
................................................................................
** argv[1] and following are modifiers.  Parse them all and write
** the resulting time into the DateTime structure p.  Return 0
** on success and 1 if there are any errors.
*/
static int isDate(int argc, const char **argv, DateTime *p){
  int i;
  if( argc==0 ) return 1;
  if( argv[0]==0 || parseDateOrTime(argv[0], p) ) return 1;
  for(i=1; i<argc; i++){
    if( argv[i]==0 || parseModifier(argv[i], p) ) return 1;
  }
  return 0;
}


/*
** The following routines implement the various date and time functions
................................................................................
*/
static void strftimeFunc(sqlite_func *context, int argc, const char **argv){
  DateTime x;
  int n, i, j;
  char *z;
  const char *zFmt = argv[0];
  char zBuf[100];
  if( argv[0]==0 || isDate(argc-1, argv+1, &x) ) return;
  for(i=0, n=1; zFmt[i]; i++, n++){
    if( zFmt[i]=='%' ){
      switch( zFmt[i+1] ){
        case 'd':
        case 'H':
        case 'm':
        case 'M':
................................................................................
     int nArg;
     int dataType;
     void (*xFunc)(sqlite_func*,int,const char**);
  } aFuncs[] = {
#ifndef SQLITE_OMIT_DATETIME_FUNCS
    { "julianday", -1, SQLITE_NUMERIC, juliandayFunc   },
    { "date",      -1, SQLITE_TEXT,    dateFunc        },
    { "time",      -1, SQLITE_TEXT,    timeFunc        },
    { "datetime",  -1, SQLITE_TEXT,    datetimeFunc    },
    { "strftime",  -1, SQLITE_TEXT,    strftimeFunc    },
#endif
  };
  int i;

  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){

Changes to test/date.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
147
148
149
150
151
152
153
154




















155
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing date and time functions.
#
# $Id: date.test,v 1.2 2003/12/23 16:22:18 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

proc datetest {tnum expr result} {
  do_test date-$tnum [subst {
    execsql "SELECT coalesce($expr,'NULL')"
................................................................................
  datetest 6.13 {datetime('2000-07-01 12:00:00','localtime')} \
      {2000-07-01 08:00:00}
  datetest 6.14 {datetime('1969-07-01 12:00:00','localtime')} \
      {1969-07-01 07:00:00}
  datetest 6.15 {datetime('2039-07-01 12:00:00','localtime')} \
      {2039-07-01 07:00:00}
}





















finish_test







|







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing date and time functions.
#
# $Id: date.test,v 1.3 2003/12/23 16:34:13 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

proc datetest {tnum expr result} {
  do_test date-$tnum [subst {
    execsql "SELECT coalesce($expr,'NULL')"
................................................................................
  datetest 6.13 {datetime('2000-07-01 12:00:00','localtime')} \
      {2000-07-01 08:00:00}
  datetest 6.14 {datetime('1969-07-01 12:00:00','localtime')} \
      {1969-07-01 07:00:00}
  datetest 6.15 {datetime('2039-07-01 12:00:00','localtime')} \
      {2039-07-01 07:00:00}
}

# Date-time functions that contain NULL arguments return a NULL
# result.
#
datetest 7.1 {datetime(null)} NULL
datetest 7.2 {datetime('now',null)} NULL
datetest 7.3 {datetime('now','localtime',null)} NULL
datetest 7.4 {time(null)} NULL
datetest 7.5 {time('now',null)} NULL
datetest 7.6 {time('now','localtime',null)} NULL
datetest 7.7 {date(null)} NULL
datetest 7.8 {date('now',null)} NULL
datetest 7.9 {date('now','localtime',null)} NULL
datetest 7.10 {julianday(null)} NULL
datetest 7.11 {julianday('now',null)} NULL
datetest 7.12 {julianday('now','localtime',null)} NULL
datetest 7.13 {strftime(null,'now')} NULL
datetest 7.14 {strftime('%s',null)} NULL
datetest 7.15 {strftime('%s','now',null)} NULL
datetest 7.16 {strftime('%s','now','localtime',null)} NULL

finish_test