SQLite

Check-in [b910a3d537]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Enhance the 'utc' modifier on date/time functions so that if the LHS is already known to be in UTC, the modifier becomes a no-op. This is not an incompatibility because the behavior is documented as "undefined" in that scenario.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b910a3d53769689d9212a06f974ccce54844bbe4
User & Date: drh 2015-12-23 10:54:48.693
Context
2015-12-23
16:42
Fix some harmless gcc compiler warnings. Mostly in fts5, but also two in the core code. (check-in: 5d44d4a6cf user: dan tags: trunk)
10:54
Enhance the 'utc' modifier on date/time functions so that if the LHS is already known to be in UTC, the modifier becomes a no-op. This is not an incompatibility because the behavior is documented as "undefined" in that scenario. (check-in: b910a3d537 user: drh tags: trunk)
2015-12-21
15:22
Ensure that the Expr objects that describe indexed expressions are not modified by code generation. Fix for an assert() problem found by Jon Metzman using AFL. (check-in: 34073ce87d user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/date.c.
61
62
63
64
65
66
67

68
69
70
71
72
73
74
  int h, m;          /* Hour and minutes */
  int tz;            /* Timezone offset in minutes */
  double s;          /* Seconds */
  char validYMD;     /* True (1) if Y,M,D are valid */
  char validHMS;     /* True (1) if h,m,s are valid */
  char validJD;      /* True (1) if iJD is valid */
  char validTZ;      /* True (1) if tz is valid */

};


/*
** Convert zDate into one or more integers.  Additional arguments
** come in groups of 5 as follows:
**







>







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
  int h, m;          /* Hour and minutes */
  int tz;            /* Timezone offset in minutes */
  double s;          /* Seconds */
  char validYMD;     /* True (1) if Y,M,D are valid */
  char validHMS;     /* True (1) if h,m,s are valid */
  char validJD;      /* True (1) if iJD is valid */
  char validTZ;      /* True (1) if tz is valid */
  char tzSet;        /* Timezone was set explicitly */
};


/*
** Convert zDate into one or more integers.  Additional arguments
** come in groups of 5 as follows:
**
154
155
156
157
158
159
160

161
162
163
164
165
166
167
  if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
    return 1;
  }
  zDate += 5;
  p->tz = sgn*(nMn + nHr*60);
zulu_time:
  while( sqlite3Isspace(*zDate) ){ zDate++; }

  return *zDate!=0;
}

/*
** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
** The HH, MM, and SS must each be exactly 2 digits.  The
** fractional seconds FFFF can be one or more digits.







>







155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
  if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
    return 1;
  }
  zDate += 5;
  p->tz = sgn*(nMn + nHr*60);
zulu_time:
  while( sqlite3Isspace(*zDate) ){ zDate++; }
  p->tzSet = 1;
  return *zDate!=0;
}

/*
** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
** The HH, MM, and SS must each be exactly 2 digits.  The
** fractional seconds FFFF can be one or more digits.
586
587
588
589
590
591
592

593
594
595
596
597
598
599




600
601
602
603
604
605
606
      if( strcmp(z, "unixepoch")==0 && p->validJD ){
        p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000;
        clearYMD_HMS_TZ(p);
        rc = 0;
      }
#ifndef SQLITE_OMIT_LOCALTIME
      else if( strcmp(z, "utc")==0 ){

        sqlite3_int64 c1;
        computeJD(p);
        c1 = localtimeOffset(p, pCtx, &rc);
        if( rc==SQLITE_OK ){
          p->iJD -= c1;
          clearYMD_HMS_TZ(p);
          p->iJD += c1 - localtimeOffset(p, pCtx, &rc);




        }
      }
#endif
      break;
    }
    case 'w': {
      /*







>
|
|
|
|
|
|
|
>
>
>
>







588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
      if( strcmp(z, "unixepoch")==0 && p->validJD ){
        p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000;
        clearYMD_HMS_TZ(p);
        rc = 0;
      }
#ifndef SQLITE_OMIT_LOCALTIME
      else if( strcmp(z, "utc")==0 ){
        if( p->tzSet==0 ){
          sqlite3_int64 c1;
          computeJD(p);
          c1 = localtimeOffset(p, pCtx, &rc);
          if( rc==SQLITE_OK ){
            p->iJD -= c1;
            clearYMD_HMS_TZ(p);
            p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
          }
          p->tzSet = 1;
        }else{
          rc = SQLITE_OK;
        }
      }
#endif
      break;
    }
    case 'w': {
      /*
Changes to test/date.test.
331
332
333
334
335
336
337









338
339
340
341
342
343
344
    datetest 6.7.1 {datetime('2006-04-02 01:59:00','utc')} {2006-04-02 06:59:00}
  }
  datetest 6.7.2 {datetime('2007-03-11 01:59:00','utc')} {2007-03-11 06:59:00}

  datetest 6.8 {datetime('2000-04-02 02:00:00','utc')} {2000-04-02 06:00:00}
  datetest 6.8.1 {datetime('2006-04-02 02:00:00','utc')} {2006-04-02 06:00:00}
  datetest 6.8.2 {datetime('2007-03-11 02:00:00','utc')} {2007-03-11 06:00:00}










  datetest 6.10 {datetime('2000-01-01 12:00:00','localtime')} \
      {2000-01-01 07:00:00}
  datetest 6.11 {datetime('1969-01-01 12:00:00','localtime')} \
      {1969-01-01 07:00:00}
  datetest 6.12 {datetime('2039-01-01 12:00:00','localtime')} \
      {2039-01-01 07:00:00}







>
>
>
>
>
>
>
>
>







331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
    datetest 6.7.1 {datetime('2006-04-02 01:59:00','utc')} {2006-04-02 06:59:00}
  }
  datetest 6.7.2 {datetime('2007-03-11 01:59:00','utc')} {2007-03-11 06:59:00}

  datetest 6.8 {datetime('2000-04-02 02:00:00','utc')} {2000-04-02 06:00:00}
  datetest 6.8.1 {datetime('2006-04-02 02:00:00','utc')} {2006-04-02 06:00:00}
  datetest 6.8.2 {datetime('2007-03-11 02:00:00','utc')} {2007-03-11 06:00:00}

  # The 'utc' modifier is a no-op if the LHS is known to already be in UTC
  datetest 6.9.1 {datetime('2015-12-23 12:00:00','utc')} {2015-12-23 17:00:00}
  datetest 6.9.2 {datetime('2015-12-23 12:00:00z','utc')} {2015-12-23 12:00:00}
  datetest 6.9.3 {datetime('2015-12-23 12:00:00-03:00','utc')} \
         {2015-12-23 15:00:00}
  datetest 6.9.4 {datetime('2015-12-23 12:00:00','utc','utc','utc')} \
         {2015-12-23 17:00:00}


  datetest 6.10 {datetime('2000-01-01 12:00:00','localtime')} \
      {2000-01-01 07:00:00}
  datetest 6.11 {datetime('1969-01-01 12:00:00','localtime')} \
      {1969-01-01 07:00:00}
  datetest 6.12 {datetime('2039-01-01 12:00:00','localtime')} \
      {2039-01-01 07:00:00}