~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2004 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
#ifdef USE_PRAGMA_IMPLEMENTATION
17
#pragma implementation				// gcc: Class implementation
18
#endif
19
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
20
#include <drizzled/server_includes.h>
1 by brian
clean slate
21
#include "tzfile.h"
22
23
/* Structure describing local time type (e.g. Moscow summer time (MSD)) */
24
typedef struct ttinfo
25
{
26
  long tt_gmtoff; // Offset from UTC in seconds
27
  uint tt_isdst;   // Is daylight saving time or not. Used to set tm_isdst
28
  uint tt_abbrind; // Index of start of abbreviation for this time type.
29
  /*
30
    We don't use tt_ttisstd and tt_ttisgmt members of original elsie-code
31
    struct since we don't support POSIX-style TZ descriptions in variables.
32
  */
33
} TRAN_TYPE_INFO;
34
35
/* Structure describing leap-second corrections. */
36
typedef struct lsinfo
37
{
38
  my_time_t ls_trans; // Transition time
39
  long      ls_corr;  // Correction to apply
40
} LS_INFO;
41
42
/*
43
  Structure with information describing ranges of my_time_t shifted to local
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
44
  time (my_time_t + offset). Used for local DRIZZLE_TIME -> my_time_t conversion.
1 by brian
clean slate
45
  See comments for TIME_to_gmt_sec() for more info.
46
*/
47
typedef struct revtinfo
48
{
49
  long rt_offset; // Offset of local time from UTC in seconds
50
  uint rt_type;    // Type of period 0 - Normal period. 1 - Spring time-gap
51
} REVT_INFO;
52
53
#ifdef TZNAME_MAX
54
#define MY_TZNAME_MAX	TZNAME_MAX
55
#endif
56
#ifndef TZNAME_MAX
57
#define MY_TZNAME_MAX	255
58
#endif
59
60
/*
61
  Structure which fully describes time zone which is
62
  described in our db or in zoneinfo files.
63
*/
64
typedef struct st_time_zone_info
65
{
66
  uint leapcnt;  // Number of leap-second corrections
67
  uint timecnt;  // Number of transitions between time types
68
  uint typecnt;  // Number of local time types
69
  uint charcnt;  // Number of characters used for abbreviations
70
  uint revcnt;   // Number of transition descr. for TIME->my_time_t conversion
71
  /* The following are dynamical arrays are allocated in MEM_ROOT */
72
  my_time_t *ats;       // Times of transitions between time types
73
  uchar	*types; // Local time types for transitions
74
  TRAN_TYPE_INFO *ttis; // Local time types descriptions
75
  /* Storage for local time types abbreviations. They are stored as ASCIIZ */
76
  char *chars;
77
  /*
78
    Leap seconds corrections descriptions, this array is shared by
79
    all time zones who use leap seconds.
80
  */
81
  LS_INFO *lsis;
82
  /*
83
    Starting points and descriptions of shifted my_time_t (my_time_t + offset)
84
    ranges on which shifted my_time_t -> my_time_t mapping is linear or undefined.
85
    Used for tm -> my_time_t conversion.
86
  */
87
  my_time_t *revts;
88
  REVT_INFO *revtis;
89
  /*
90
    Time type which is used for times smaller than first transition or if
91
    there are no transitions at all.
92
  */
93
  TRAN_TYPE_INFO *fallback_tti;
94
95
} TIME_ZONE_INFO;
96
97
98
#if !defined(TZINFO2SQL)
99
100
static const uint mon_lengths[2][MONS_PER_YEAR]=
101
{
102
  { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
103
  { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
104
};
105
106
static const uint mon_starts[2][MONS_PER_YEAR]=
107
{
108
  { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
109
  { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
110
};
111
112
static const uint year_lengths[2]=
113
{
114
  DAYS_PER_NYEAR, DAYS_PER_LYEAR
115
};
116
117
#define LEAPS_THRU_END_OF(y)  ((y) / 4 - (y) / 100 + (y) / 400)
118
119
120
/*
121
  Converts time from my_time_t representation (seconds in UTC since Epoch)
122
  to broken down representation using given local time zone offset.
123
124
  SYNOPSIS
125
    sec_to_TIME()
126
      tmp    - pointer to structure for broken down representation
127
      t      - my_time_t value to be converted
128
      offset - local time zone offset
129
130
  DESCRIPTION
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
131
    Convert my_time_t with offset to DRIZZLE_TIME struct. Differs from timesub
1 by brian
clean slate
132
    (from elsie code) because doesn't contain any leap correction and
133
    TM_GMTOFF and is_dst setting and contains some MySQL specific
134
    initialization. Funny but with removing of these we almost have
135
    glibc's offtime function.
136
*/
137
static void
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
138
sec_to_TIME(DRIZZLE_TIME * tmp, my_time_t t, long offset)
1 by brian
clean slate
139
{
140
  long days;
141
  long rem;
142
  int y;
143
  int yleap;
144
  const uint *ip;
145
146
  days= (long) (t / SECS_PER_DAY);
147
  rem=  (long) (t % SECS_PER_DAY);
148
149
  /*
150
    We do this as separate step after dividing t, because this
151
    allows us handle times near my_time_t bounds without overflows.
152
  */
153
  rem+= offset;
154
  while (rem < 0)
155
  {
156
    rem+= SECS_PER_DAY;
157
    days--;
158
  }
159
  while (rem >= SECS_PER_DAY)
160
  {
161
    rem -= SECS_PER_DAY;
162
    days++;
163
  }
164
  tmp->hour= (uint)(rem / SECS_PER_HOUR);
165
  rem= rem % SECS_PER_HOUR;
166
  tmp->minute= (uint)(rem / SECS_PER_MIN);
167
  /*
168
    A positive leap second requires a special
169
    representation.  This uses "... ??:59:60" et seq.
170
  */
171
  tmp->second= (uint)(rem % SECS_PER_MIN);
172
173
  y= EPOCH_YEAR;
174
  while (days < 0 || days >= (long)year_lengths[yleap= isleap(y)])
175
  {
176
    int	newy;
177
178
    newy= y + days / DAYS_PER_NYEAR;
179
    if (days < 0)
180
      newy--;
181
    days-= (newy - y) * DAYS_PER_NYEAR +
182
           LEAPS_THRU_END_OF(newy - 1) -
183
           LEAPS_THRU_END_OF(y - 1);
184
    y= newy;
185
  }
186
  tmp->year= y;
187
188
  ip= mon_lengths[yleap];
189
  for (tmp->month= 0; days >= (long) ip[tmp->month]; tmp->month++)
190
    days= days - (long) ip[tmp->month];
191
  tmp->month++;
192
  tmp->day= (uint)(days + 1);
193
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
194
  /* filling MySQL specific DRIZZLE_TIME members */
1 by brian
clean slate
195
  tmp->neg= 0; tmp->second_part= 0;
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
196
  tmp->time_type= DRIZZLE_TIMESTAMP_DATETIME;
1 by brian
clean slate
197
}
198
199
200
/*
201
  Find time range wich contains given my_time_t value
202
203
  SYNOPSIS
204
    find_time_range()
205
      t                - my_time_t value for which we looking for range
206
      range_boundaries - sorted array of range starts.
207
      higher_bound     - number of ranges
208
209
  DESCRIPTION
210
    Performs binary search for range which contains given my_time_t value.
211
    It has sense if number of ranges is greater than zero and my_time_t value
212
    is greater or equal than beginning of first range. It also assumes that
213
    t belongs to some range specified or end of last is MY_TIME_T_MAX.
214
215
    With this localtime_r on real data may takes less time than with linear
216
    search (I've seen 30% speed up).
217
218
  RETURN VALUE
219
    Index of range to which t belongs
220
*/
221
static uint
222
find_time_range(my_time_t t, const my_time_t *range_boundaries,
223
                uint higher_bound)
224
{
225
  uint i, lower_bound= 0;
226
227
  /*
228
    Function will work without this assertion but result would be meaningless.
229
  */
51.1.72 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
230
  assert(higher_bound > 0 && t >= range_boundaries[0]);
1 by brian
clean slate
231
232
  /*
233
    Do binary search for minimal interval which contain t. We preserve:
234
    range_boundaries[lower_bound] <= t < range_boundaries[higher_bound]
235
    invariant and decrease this higher_bound - lower_bound gap twice
236
    times on each step.
237
  */
238
239
  while (higher_bound - lower_bound > 1)
240
  {
241
    i= (lower_bound + higher_bound) >> 1;
242
    if (range_boundaries[i] <= t)
243
      lower_bound= i;
244
    else
245
      higher_bound= i;
246
  }
247
  return lower_bound;
248
}
249
250
/*
251
  Find local time transition for given my_time_t.
252
253
  SYNOPSIS
254
    find_transition_type()
255
      t   - my_time_t value to be converted
256
      sp  - pointer to struct with time zone description
257
258
  RETURN VALUE
259
    Pointer to structure in time zone description describing
260
    local time type for given my_time_t.
261
*/
262
static
263
const TRAN_TYPE_INFO *
264
find_transition_type(my_time_t t, const TIME_ZONE_INFO *sp)
265
{
266
  if (unlikely(sp->timecnt == 0 || t < sp->ats[0]))
267
  {
268
    /*
269
      If we have not any transitions or t is before first transition let
270
      us use fallback time type.
271
    */
272
    return sp->fallback_tti;
273
  }
274
275
  /*
276
    Do binary search for minimal interval between transitions which
277
    contain t. With this localtime_r on real data may takes less
278
    time than with linear search (I've seen 30% speed up).
279
  */
280
  return &(sp->ttis[sp->types[find_time_range(t, sp->ats, sp->timecnt)]]);
281
}
282
283
284
/*
285
  Converts time in my_time_t representation (seconds in UTC since Epoch) to
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
286
  broken down DRIZZLE_TIME representation in local time zone.
1 by brian
clean slate
287
288
  SYNOPSIS
289
    gmt_sec_to_TIME()
290
      tmp          - pointer to structure for broken down represenatation
291
      sec_in_utc   - my_time_t value to be converted
292
      sp           - pointer to struct with time zone description
293
294
  TODO
295
    We can improve this function by creating joined array of transitions and
296
    leap corrections. This will require adding extra field to TRAN_TYPE_INFO
297
    for storing number of "extra" seconds to minute occured due to correction
298
    (60th and 61st second, look how we calculate them as "hit" in this
299
    function).
300
    Under realistic assumptions about frequency of transitions the same array
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
301
    can be used fot DRIZZLE_TIME -> my_time_t conversion. For this we need to
1 by brian
clean slate
302
    implement tweaked binary search which will take into account that some
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
303
    DRIZZLE_TIME has two matching my_time_t ranges and some of them have none.
1 by brian
clean slate
304
*/
305
static void
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
306
gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t sec_in_utc, const TIME_ZONE_INFO *sp)
1 by brian
clean slate
307
{
308
  const TRAN_TYPE_INFO *ttisp;
309
  const LS_INFO *lp;
310
  long  corr= 0;
311
  int   hit= 0;
312
  int   i;
313
314
  /*
315
    Find proper transition (and its local time type) for our sec_in_utc value.
316
    Funny but again by separating this step in function we receive code
317
    which very close to glibc's code. No wonder since they obviously use
318
    the same base and all steps are sensible.
319
  */
320
  ttisp= find_transition_type(sec_in_utc, sp);
321
322
  /*
323
    Let us find leap correction for our sec_in_utc value and number of extra
324
    secs to add to this minute.
325
    This loop is rarely used because most users will use time zones without
326
    leap seconds, and even in case when we have such time zone there won't
327
    be many iterations (we have about 22 corrections at this moment (2004)).
328
  */
329
  for ( i= sp->leapcnt; i-- > 0; )
330
  {
331
    lp= &sp->lsis[i];
332
    if (sec_in_utc >= lp->ls_trans)
333
    {
334
      if (sec_in_utc == lp->ls_trans)
335
      {
336
        hit= ((i == 0 && lp->ls_corr > 0) ||
337
              lp->ls_corr > sp->lsis[i - 1].ls_corr);
338
        if (hit)
339
        {
340
          while (i > 0 &&
341
                 sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 &&
342
                 sp->lsis[i].ls_corr == sp->lsis[i - 1].ls_corr + 1)
343
          {
344
            hit++;
345
            i--;
346
          }
347
        }
348
      }
349
      corr= lp->ls_corr;
350
      break;
351
    }
352
  }
353
354
  sec_to_TIME(tmp, sec_in_utc, ttisp->tt_gmtoff - corr);
355
356
  tmp->second+= hit;
357
}
358
359
360
/*
361
  Converts local time in broken down representation to local
362
  time zone analog of my_time_t represenation.
363
364
  SYNOPSIS
365
    sec_since_epoch()
366
      year, mon, mday, hour, min, sec - broken down representation.
367
368
  DESCRIPTION
369
    Converts time in broken down representation to my_time_t representation
370
    ignoring time zone. Note that we cannot convert back some valid _local_
371
    times near ends of my_time_t range because of my_time_t  overflow. But we
372
    ignore this fact now since MySQL will never pass such argument.
373
374
  RETURN VALUE
375
    Seconds since epoch time representation.
376
*/
377
static my_time_t
378
sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
379
{
380
  /* Guard against my_time_t overflow(on system with 32 bit my_time_t) */
51.1.72 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
381
  assert(!(year == TIMESTAMP_MAX_YEAR && mon == 1 && mday > 17));
1 by brian
clean slate
382
#ifndef WE_WANT_TO_HANDLE_UNORMALIZED_DATES
383
  /*
384
    It turns out that only whenever month is normalized or unnormalized
385
    plays role.
386
  */
51.1.72 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
387
  assert(mon > 0 && mon < 13);
1 by brian
clean slate
388
  long days= year * DAYS_PER_NYEAR - EPOCH_YEAR * DAYS_PER_NYEAR +
389
             LEAPS_THRU_END_OF(year - 1) -
390
             LEAPS_THRU_END_OF(EPOCH_YEAR - 1);
391
  days+= mon_starts[isleap(year)][mon - 1];
392
#else
393
  long norm_month= (mon - 1) % MONS_PER_YEAR;
394
  long a_year= year + (mon - 1)/MONS_PER_YEAR - (int)(norm_month < 0);
395
  long days= a_year * DAYS_PER_NYEAR - EPOCH_YEAR * DAYS_PER_NYEAR +
396
             LEAPS_THRU_END_OF(a_year - 1) -
397
             LEAPS_THRU_END_OF(EPOCH_YEAR - 1);
398
  days+= mon_starts[isleap(a_year)]
399
                    [norm_month + (norm_month < 0 ? MONS_PER_YEAR : 0)];
400
#endif
401
  days+= mday - 1;
402
403
  return ((days * HOURS_PER_DAY + hour) * MINS_PER_HOUR + min) *
404
         SECS_PER_MIN + sec;
405
}
406
407
/*
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
408
  Converts local time in broken down DRIZZLE_TIME representation to my_time_t
1 by brian
clean slate
409
  representation.
410
411
  SYNOPSIS
412
    TIME_to_gmt_sec()
413
      t               - pointer to structure for broken down represenatation
414
      sp              - pointer to struct with time zone description
415
      in_dst_time_gap - pointer to bool which is set to true if datetime
416
                        value passed doesn't really exist (i.e. falls into
417
                        spring time-gap) and is not touched otherwise.
418
419
  DESCRIPTION
420
    This is mktime analog for MySQL. It is essentially different
421
    from mktime (or hypotetical my_mktime) because:
422
    - It has no idea about tm_isdst member so if it
423
      has two answers it will give the smaller one
424
    - If we are in spring time gap then it will return
425
      beginning of the gap
426
    - It can give wrong results near the ends of my_time_t due to
427
      overflows, but we are safe since in MySQL we will never
428
      call this function for such dates (its restriction for year
429
      between 1970 and 2038 gives us several days of reserve).
430
    - By default it doesn't support un-normalized input. But if
431
      sec_since_epoch() function supports un-normalized dates
432
      then this function should handle un-normalized input right,
433
      altough it won't normalize structure TIME.
434
435
    Traditional approach to problem of conversion from broken down
436
    representation to time_t is iterative. Both elsie's and glibc
437
    implementation try to guess what time_t value should correspond to
438
    this broken-down value. They perform localtime_r function on their
439
    guessed value and then calculate the difference and try to improve
440
    their guess. Elsie's code guesses time_t value in bit by bit manner,
441
    Glibc's code tries to add difference between broken-down value
442
    corresponding to guess and target broken-down value to current guess.
443
    It also uses caching of last found correction... So Glibc's approach
444
    is essentially faster but introduces some undetermenism (in case if
445
    is_dst member of broken-down representation (tm struct) is not known
446
    and we have two possible answers).
447
448
    We use completely different approach. It is better since it is both
449
    faster than iterative implementations and fully determenistic. If you
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
450
    look at my_time_t to DRIZZLE_TIME conversion then you'll find that it consist
1 by brian
clean slate
451
    of two steps:
452
    The first is calculating shifted my_time_t value and the second - TIME
453
    calculation from shifted my_time_t value (well it is a bit simplified
454
    picture). The part in which we are interested in is my_time_t -> shifted
455
    my_time_t conversion. It is piecewise linear function which is defined
456
    by combination of transition times as break points and times offset
457
    as changing function parameter. The possible inverse function for this
458
    converison would be ambiguos but with MySQL's restrictions we can use
459
    some function which is the same as inverse function on unambigiuos
460
    ranges and coincides with one of branches of inverse function in
461
    other ranges. Thus we just need to build table which will determine
462
    this shifted my_time_t -> my_time_t conversion similar to existing
463
    (my_time_t -> shifted my_time_t table). We do this in
464
    prepare_tz_info function.
465
466
  TODO
467
    If we can even more improve this function. For doing this we will need to
468
    build joined map of transitions and leap corrections for gmt_sec_to_TIME()
469
    function (similar to revts/revtis). Under realistic assumptions about
470
    frequency of transitions we can use the same array for TIME_to_gmt_sec().
471
    We need to implement special version of binary search for this. Such step
472
    will be beneficial to CPU cache since we will decrease data-set used for
473
    conversion twice.
474
475
  RETURN VALUE
476
    Seconds in UTC since Epoch.
477
    0 in case of error.
478
*/
479
static my_time_t
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
480
TIME_to_gmt_sec(const DRIZZLE_TIME *t, const TIME_ZONE_INFO *sp,
93 by Brian Aker
Convert tztime.cc to bool from my_bool.
481
                bool *in_dst_time_gap)
1 by brian
clean slate
482
{
483
  my_time_t local_t;
484
  uint saved_seconds;
485
  uint i;
486
  int shift= 0;
487
488
  if (!validate_timestamp_range(t))
51.1.72 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
489
    return(0);
1 by brian
clean slate
490
491
492
  /* We need this for correct leap seconds handling */
493
  if (t->second < SECS_PER_MIN)
494
    saved_seconds= 0;
495
  else
496
    saved_seconds= t->second;
497
498
  /*
499
    NOTE: to convert full my_time_t range we do a shift of the
500
    boundary dates here to avoid overflow of my_time_t.
501
    We use alike approach in my_system_gmt_sec().
502
503
    However in that function we also have to take into account
504
    overflow near 0 on some platforms. That's because my_system_gmt_sec
505
    uses localtime_r(), which doesn't work with negative values correctly
506
    on platforms with unsigned time_t (QNX). Here we don't use localtime()
507
    => we negative values of local_t are ok.
508
  */
509
510
  if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && t->day > 4)
511
  {
512
    /*
513
      We will pass (t->day - shift) to sec_since_epoch(), and
514
      want this value to be a positive number, so we shift
515
      only dates > 4.01.2038 (to avoid owerflow).
516
    */
517
    shift= 2;
518
  }
519
520
521
  local_t= sec_since_epoch(t->year, t->month, (t->day - shift),
522
                           t->hour, t->minute,
523
                           saved_seconds ? 0 : t->second);
524
525
  /* We have at least one range */
51.1.72 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
526
  assert(sp->revcnt >= 1);
1 by brian
clean slate
527
528
  if (local_t < sp->revts[0] || local_t > sp->revts[sp->revcnt])
529
  {
530
    /*
531
      This means that source time can't be represented as my_time_t due to
532
      limited my_time_t range.
533
    */
51.1.72 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
534
    return(0);
1 by brian
clean slate
535
  }
536
537
  /* binary search for our range */
538
  i= find_time_range(local_t, sp->revts, sp->revcnt);
539
540
  /*
541
    As there are no offset switches at the end of TIMESTAMP range,
542
    we could simply check for overflow here (and don't need to bother
543
    about DST gaps etc)
544
  */
545
  if (shift)
546
  {
547
    if (local_t > (my_time_t) (TIMESTAMP_MAX_VALUE - shift * SECS_PER_DAY +
548
                               sp->revtis[i].rt_offset - saved_seconds))
549
    {
51.1.72 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
550
      return(0);                           /* my_time_t overflow */
1 by brian
clean slate
551
    }
552
    local_t+= shift * SECS_PER_DAY;
553
  }
554
555
  if (sp->revtis[i].rt_type)
556
  {
557
    /*
558
      Oops! We are in spring time gap.
559
      May be we should return error here?
560
      Now we are returning my_time_t value corresponding to the
561
      beginning of the gap.
562
    */
563
    *in_dst_time_gap= 1;
564
    local_t= sp->revts[i] - sp->revtis[i].rt_offset + saved_seconds;
565
  }
566
  else
567
    local_t= local_t - sp->revtis[i].rt_offset + saved_seconds;
568
569
  /* check for TIMESTAMP_MAX_VALUE was already done above */
570
  if (local_t < TIMESTAMP_MIN_VALUE)
571
    local_t= 0;
572
51.1.72 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
573
  return(local_t);
1 by brian
clean slate
574
}
575
576
577
/*
578
  End of elsie derived code.
579
*/
580
#endif /* !defined(TZINFO2SQL) */
581
582
583
/*
584
  String with names of SYSTEM time zone.
585
*/
586
static const String tz_SYSTEM_name("SYSTEM", 6, &my_charset_latin1);
587
588
589
/*
590
  Instance of this class represents local time zone used on this system
591
  (specified by TZ environment variable or via any other system mechanism).
592
  It uses system functions (localtime_r, my_system_gmt_sec) for conversion
593
  and is always available. Because of this it is used by default - if there
594
  were no explicit time zone specified. On the other hand because of this
595
  conversion methods provided by this class is significantly slower and
596
  possibly less multi-threaded-friendly than corresponding Time_zone_db
597
  methods so the latter should be preffered there it is possible.
598
*/
599
class Time_zone_system : public Time_zone
600
{
601
public:
602
  Time_zone_system() {}                       /* Remove gcc warning */
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
603
  virtual my_time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
93 by Brian Aker
Convert tztime.cc to bool from my_bool.
604
                                    bool *in_dst_time_gap) const;
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
605
  virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const;
1 by brian
clean slate
606
  virtual const String * get_name() const;
607
};
608
609
610
/*
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
611
  Converts local time in system time zone in DRIZZLE_TIME representation
1 by brian
clean slate
612
  to its my_time_t representation.
613
614
  SYNOPSIS
615
    TIME_to_gmt_sec()
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
616
      t               - pointer to DRIZZLE_TIME structure with local time in
1 by brian
clean slate
617
                        broken-down representation.
618
      in_dst_time_gap - pointer to bool which is set to true if datetime
619
                        value passed doesn't really exist (i.e. falls into
620
                        spring time-gap) and is not touched otherwise.
621
622
  DESCRIPTION
623
    This method uses system function (localtime_r()) for conversion
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
624
    local time in system time zone in DRIZZLE_TIME structure to its my_time_t
1 by brian
clean slate
625
    representation. Unlike the same function for Time_zone_db class
626
    it it won't handle unnormalized input properly. Still it will
627
    return lowest possible my_time_t in case of ambiguity or if we
628
    provide time corresponding to the time-gap.
629
630
    You should call init_time() function before using this function.
631
632
  RETURN VALUE
633
    Corresponding my_time_t value or 0 in case of error
634
*/
635
my_time_t
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
636
Time_zone_system::TIME_to_gmt_sec(const DRIZZLE_TIME *t, bool *in_dst_time_gap) const
1 by brian
clean slate
637
{
638
  long not_used;
639
  return my_system_gmt_sec(t, &not_used, in_dst_time_gap);
640
}
641
642
643
/*
644
  Converts time from UTC seconds since Epoch (my_time_t) representation
645
  to system local time zone broken-down representation.
646
647
  SYNOPSIS
648
    gmt_sec_to_TIME()
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
649
      tmp - pointer to DRIZZLE_TIME structure to fill-in
1 by brian
clean slate
650
      t   - my_time_t value to be converted
651
652
  NOTE
653
    We assume that value passed to this function will fit into time_t range
654
    supported by localtime_r. This conversion is putting restriction on
655
    TIMESTAMP range in MySQL. If we can get rid of SYSTEM time zone at least
656
    for interaction with client then we can extend TIMESTAMP range down to
657
    the 1902 easily.
658
*/
659
void
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
660
Time_zone_system::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const
1 by brian
clean slate
661
{
662
  struct tm tmp_tm;
663
  time_t tmp_t= (time_t)t;
664
665
  localtime_r(&tmp_t, &tmp_tm);
666
  localtime_to_TIME(tmp, &tmp_tm);
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
667
  tmp->time_type= DRIZZLE_TIMESTAMP_DATETIME;
1 by brian
clean slate
668
}
669
670
671
/*
672
  Get name of time zone
673
674
  SYNOPSIS
675
    get_name()
676
677
  RETURN VALUE
678
    Name of time zone as String
679
*/
680
const String *
681
Time_zone_system::get_name() const
682
{
683
  return &tz_SYSTEM_name;
684
}
685
686
687
/*
688
  Instance of this class represents UTC time zone. It uses system gmtime_r
689
  function for conversions and is always available. It is used only for
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
690
  my_time_t -> DRIZZLE_TIME conversions in various UTC_...  functions, it is not
691
  intended for DRIZZLE_TIME -> my_time_t conversions and shouldn't be exposed to user.
1 by brian
clean slate
692
*/
693
class Time_zone_utc : public Time_zone
694
{
695
public:
696
  Time_zone_utc() {}                          /* Remove gcc warning */
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
697
  virtual my_time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
93 by Brian Aker
Convert tztime.cc to bool from my_bool.
698
                                    bool *in_dst_time_gap) const;
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
699
  virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const;
1 by brian
clean slate
700
  virtual const String * get_name() const;
701
};
702
703
704
/*
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
705
  Convert UTC time from DRIZZLE_TIME representation to its my_time_t representation.
1 by brian
clean slate
706
707
  SYNOPSIS
708
    TIME_to_gmt_sec()
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
709
      t               - pointer to DRIZZLE_TIME structure with local time
1 by brian
clean slate
710
                        in broken-down representation.
711
      in_dst_time_gap - pointer to bool which is set to true if datetime
712
                        value passed doesn't really exist (i.e. falls into
713
                        spring time-gap) and is not touched otherwise.
714
715
  DESCRIPTION
716
    Since Time_zone_utc is used only internally for my_time_t -> TIME
717
    conversions, this function of Time_zone interface is not implemented for
718
    this class and should not be called.
719
720
  RETURN VALUE
721
    0
722
*/
723
my_time_t
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
724
Time_zone_utc::TIME_to_gmt_sec(const DRIZZLE_TIME *t __attribute__((unused)),
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
725
                               bool *in_dst_time_gap __attribute__((unused))) const
1 by brian
clean slate
726
{
727
  /* Should be never called */
51.1.72 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
728
  assert(0);
1 by brian
clean slate
729
  return 0;
730
}
731
732
733
/*
734
  Converts time from UTC seconds since Epoch (my_time_t) representation
735
  to broken-down representation (also in UTC).
736
737
  SYNOPSIS
738
    gmt_sec_to_TIME()
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
739
      tmp - pointer to DRIZZLE_TIME structure to fill-in
1 by brian
clean slate
740
      t   - my_time_t value to be converted
741
742
  NOTE
743
    See note for apropriate Time_zone_system method.
744
*/
745
void
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
746
Time_zone_utc::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const
1 by brian
clean slate
747
{
748
  struct tm tmp_tm;
749
  time_t tmp_t= (time_t)t;
750
  gmtime_r(&tmp_t, &tmp_tm);
751
  localtime_to_TIME(tmp, &tmp_tm);
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
752
  tmp->time_type= DRIZZLE_TIMESTAMP_DATETIME;
1 by brian
clean slate
753
}
754
755
756
/*
757
  Get name of time zone
758
759
  SYNOPSIS
760
    get_name()
761
762
  DESCRIPTION
763
    Since Time_zone_utc is used only internally by SQL's UTC_* functions it
764
    is not accessible directly, and hence this function of Time_zone
765
    interface is not implemented for this class and should not be called.
766
767
  RETURN VALUE
768
    0
769
*/
770
const String *
771
Time_zone_utc::get_name() const
772
{
773
  /* Should be never called */
51.1.72 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
774
  assert(0);
1 by brian
clean slate
775
  return 0;
776
}
777
778
779
/*
780
  Instance of this class represents some time zone which is
781
  described in mysql.time_zone family of tables.
782
*/
783
class Time_zone_db : public Time_zone
784
{
785
public:
786
  Time_zone_db(TIME_ZONE_INFO *tz_info_arg, const String * tz_name_arg);
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
787
  virtual my_time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
93 by Brian Aker
Convert tztime.cc to bool from my_bool.
788
                                    bool *in_dst_time_gap) const;
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
789
  virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const;
1 by brian
clean slate
790
  virtual const String * get_name() const;
791
private:
792
  TIME_ZONE_INFO *tz_info;
793
  const String *tz_name;
794
};
795
796
797
/*
798
  Initializes object representing time zone described by mysql.time_zone
799
  tables.
800
801
  SYNOPSIS
802
    Time_zone_db()
803
      tz_info_arg - pointer to TIME_ZONE_INFO structure which is filled
804
                    according to db or other time zone description
805
                    (for example by my_tz_init()).
806
                    Several Time_zone_db instances can share one
807
                    TIME_ZONE_INFO structure.
808
      tz_name_arg - name of time zone.
809
*/
810
Time_zone_db::Time_zone_db(TIME_ZONE_INFO *tz_info_arg,
811
                           const String *tz_name_arg):
812
  tz_info(tz_info_arg), tz_name(tz_name_arg)
813
{
814
}
815
816
817
/*
818
  Converts local time in time zone described from TIME
819
  representation to its my_time_t representation.
820
821
  SYNOPSIS
822
    TIME_to_gmt_sec()
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
823
      t               - pointer to DRIZZLE_TIME structure with local time
1 by brian
clean slate
824
                        in broken-down representation.
825
      in_dst_time_gap - pointer to bool which is set to true if datetime
826
                        value passed doesn't really exist (i.e. falls into
827
                        spring time-gap) and is not touched otherwise.
828
829
  DESCRIPTION
830
    Please see ::TIME_to_gmt_sec for function description and
831
    parameter restrictions.
832
833
  RETURN VALUE
834
    Corresponding my_time_t value or 0 in case of error
835
*/
836
my_time_t
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
837
Time_zone_db::TIME_to_gmt_sec(const DRIZZLE_TIME *t, bool *in_dst_time_gap) const
1 by brian
clean slate
838
{
839
  return ::TIME_to_gmt_sec(t, tz_info, in_dst_time_gap);
840
}
841
842
843
/*
844
  Converts time from UTC seconds since Epoch (my_time_t) representation
845
  to local time zone described in broken-down representation.
846
847
  SYNOPSIS
848
    gmt_sec_to_TIME()
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
849
      tmp - pointer to DRIZZLE_TIME structure to fill-in
1 by brian
clean slate
850
      t   - my_time_t value to be converted
851
*/
852
void
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
853
Time_zone_db::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const
1 by brian
clean slate
854
{
855
  ::gmt_sec_to_TIME(tmp, t, tz_info);
856
}
857
858
859
/*
860
  Get name of time zone
861
862
  SYNOPSIS
863
    get_name()
864
865
  RETURN VALUE
866
    Name of time zone as ASCIIZ-string
867
*/
868
const String *
869
Time_zone_db::get_name() const
870
{
871
  return tz_name;
872
}
873
874
875
/*
876
  Instance of this class represents time zone which
877
  was specified as offset from UTC.
878
*/
879
class Time_zone_offset : public Time_zone
880
{
881
public:
882
  Time_zone_offset(long tz_offset_arg);
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
883
  virtual my_time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
93 by Brian Aker
Convert tztime.cc to bool from my_bool.
884
                                    bool *in_dst_time_gap) const;
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
885
  virtual void   gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const;
1 by brian
clean slate
886
  virtual const String * get_name() const;
887
  /*
888
    This have to be public because we want to be able to access it from
889
    my_offset_tzs_get_key() function
890
  */
891
  long offset;
892
private:
893
  /* Extra reserve because of snprintf */
894
  char name_buff[7+16];
895
  String name;
896
};
897
898
899
/*
900
  Initializes object representing time zone described by its offset from UTC.
901
902
  SYNOPSIS
903
    Time_zone_offset()
904
      tz_offset_arg - offset from UTC in seconds.
905
                      Positive for direction to east.
906
*/
907
Time_zone_offset::Time_zone_offset(long tz_offset_arg):
908
  offset(tz_offset_arg)
909
{
910
  uint hours= abs((int)(offset / SECS_PER_HOUR));
911
  uint minutes= abs((int)(offset % SECS_PER_HOUR / SECS_PER_MIN));
77.1.18 by Monty Taylor
Removed my_vsnprintf and my_snprintf.
912
  ulong length= snprintf(name_buff, sizeof(name_buff), "%s%02d:%02d",
913
                         (offset>=0) ? "+" : "-", hours, minutes);
1 by brian
clean slate
914
  name.set(name_buff, length, &my_charset_latin1);
915
}
916
917
918
/*
919
  Converts local time in time zone described as offset from UTC
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
920
  from DRIZZLE_TIME representation to its my_time_t representation.
1 by brian
clean slate
921
922
  SYNOPSIS
923
    TIME_to_gmt_sec()
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
924
      t               - pointer to DRIZZLE_TIME structure with local time
1 by brian
clean slate
925
                        in broken-down representation.
926
      in_dst_time_gap - pointer to bool which should be set to true if
927
                        datetime  value passed doesn't really exist
928
                        (i.e. falls into spring time-gap) and is not
929
                        touched otherwise.
930
                        It is not really used in this class.
931
932
  RETURN VALUE
933
    Corresponding my_time_t value or 0 in case of error
934
*/
935
my_time_t
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
936
Time_zone_offset::TIME_to_gmt_sec(const DRIZZLE_TIME *t,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
937
                                  bool *in_dst_time_gap __attribute__((unused))) const
1 by brian
clean slate
938
{
939
  my_time_t local_t;
940
  int shift= 0;
941
942
  /*
943
    Check timestamp range.we have to do this as calling function relies on
944
    us to make all validation checks here.
945
  */
946
  if (!validate_timestamp_range(t))
947
    return 0;
948
949
  /*
950
    Do a temporary shift of the boundary dates to avoid
951
    overflow of my_time_t if the time value is near it's
952
    maximum range
953
  */
954
  if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && t->day > 4)
955
    shift= 2;
956
957
  local_t= sec_since_epoch(t->year, t->month, (t->day - shift),
958
                           t->hour, t->minute, t->second) -
959
           offset;
960
961
  if (shift)
962
  {
963
    /* Add back the shifted time */
964
    local_t+= shift * SECS_PER_DAY;
965
  }
966
967
  if (local_t >= TIMESTAMP_MIN_VALUE && local_t <= TIMESTAMP_MAX_VALUE)
968
    return local_t;
969
970
  /* range error*/
971
  return 0;
972
}
973
974
975
/*
976
  Converts time from UTC seconds since Epoch (my_time_t) representation
977
  to local time zone described as offset from UTC and in broken-down
978
  representation.
979
980
  SYNOPSIS
981
    gmt_sec_to_TIME()
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
982
      tmp - pointer to DRIZZLE_TIME structure to fill-in
1 by brian
clean slate
983
      t   - my_time_t value to be converted
984
*/
985
void
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
986
Time_zone_offset::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const
1 by brian
clean slate
987
{
988
  sec_to_TIME(tmp, t, offset);
989
}
990
991
992
/*
993
  Get name of time zone
994
995
  SYNOPSIS
996
    get_name()
997
998
  RETURN VALUE
999
    Name of time zone as pointer to String object
1000
*/
1001
const String *
1002
Time_zone_offset::get_name() const
1003
{
1004
  return &name;
1005
}
1006
1007
1008
static Time_zone_utc tz_UTC;
1009
static Time_zone_system tz_SYSTEM;
1010
static Time_zone_offset tz_OFFSET0(0);
1011
1012
Time_zone *my_tz_OFFSET0= &tz_OFFSET0;
1013
Time_zone *my_tz_UTC= &tz_UTC;
1014
Time_zone *my_tz_SYSTEM= &tz_SYSTEM;
1015
1016
class Tz_names_entry: public Sql_alloc
1017
{
1018
public:
1019
  String name;
1020
  Time_zone *tz;
1021
};
1022
1023
1024
/*
1025
  Initialize time zone support infrastructure.
1026
1027
  SYNOPSIS
1028
    my_tz_init()
1029
      thd            - current thread object
1030
      default_tzname - default time zone or 0 if none.
1031
      bootstrap      - indicates whenever we are in bootstrap mode
1032
1033
  DESCRIPTION
1034
    This function will init memory structures needed for time zone support,
1035
    it will register mandatory SYSTEM time zone in them. It will try to open
1036
    mysql.time_zone* tables and load information about default time zone and
1037
    information which further will be shared among all time zones loaded.
1038
    If system tables with time zone descriptions don't exist it won't fail
1039
    (unless default_tzname is time zone from tables). If bootstrap parameter
1040
    is true then this routine assumes that we are in bootstrap mode and won't
1041
    load time zone descriptions unless someone specifies default time zone
1042
    which is supposedly stored in those tables.
1043
    It'll also set default time zone if it is specified.
1044
1045
  RETURN VALUES
1046
    0 - ok
1047
    1 - Error
1048
*/
53.1.1 by Brian Aker
First pass through removing timezone. Left infrastructure for possible call
1049
bool
77.1.46 by Monty Taylor
Finished the warnings work!
1050
my_tz_init(THD *thd, const char *default_tzname,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
1051
           bool bootstrap __attribute__((unused)))
1 by brian
clean slate
1052
{
1053
  if (default_tzname)
1054
  {
1055
    String tmp_tzname2(default_tzname, &my_charset_latin1);
1056
    /*
1057
      Time zone tables may be open here, and my_tz_find() may open
1058
      most of them once more, but this is OK for system tables open
1059
      for READ.
1060
    */
1061
    if (!(global_system_variables.time_zone= my_tz_find(thd, &tmp_tzname2)))
1062
    {
261.3.1 by Monty Taylor
Added strings from three more files...
1063
      sql_print_error(_("Fatal error: Illegal or unknown default time zone '%s'"),
1 by brian
clean slate
1064
                      default_tzname);
53.1.1 by Brian Aker
First pass through removing timezone. Left infrastructure for possible call
1065
      return true;
1 by brian
clean slate
1066
    }
1067
  }
1068
53.1.1 by Brian Aker
First pass through removing timezone. Left infrastructure for possible call
1069
  return false;
1 by brian
clean slate
1070
}
1071
1072
1073
/*
1074
  Free resources used by time zone support infrastructure.
1075
*/
1076
1077
void my_tz_free()
1078
{
1079
}
1080
1081
1082
/*
1083
  Parse string that specifies time zone as offset from UTC.
1084
1085
  SYNOPSIS
1086
    str_to_offset()
1087
      str    - pointer to string which contains offset
1088
      length - length of string
1089
      offset - out parameter for storing found offset in seconds.
1090
1091
  DESCRIPTION
1092
    This function parses string which contains time zone offset
1093
    in form similar to '+10:00' and converts found value to
1094
    seconds from UTC form (east is positive).
1095
1096
  RETURN VALUE
1097
    0 - Ok
1098
    1 - String doesn't contain valid time zone offset
1099
*/
93 by Brian Aker
Convert tztime.cc to bool from my_bool.
1100
bool
1 by brian
clean slate
1101
str_to_offset(const char *str, uint length, long *offset)
1102
{
1103
  const char *end= str + length;
93 by Brian Aker
Convert tztime.cc to bool from my_bool.
1104
  bool negative;
1 by brian
clean slate
1105
  ulong number_tmp;
1106
  long offset_tmp;
1107
1108
  if (length < 4)
1109
    return 1;
1110
1111
  if (*str == '+')
1112
    negative= 0;
1113
  else if (*str == '-')
1114
    negative= 1;
1115
  else
1116
    return 1;
1117
  str++;
1118
1119
  number_tmp= 0;
1120
1121
  while (str < end && my_isdigit(&my_charset_latin1, *str))
1122
  {
1123
    number_tmp= number_tmp*10 + *str - '0';
1124
    str++;
1125
  }
1126
1127
  if (str + 1 >= end || *str != ':')
1128
    return 1;
1129
  str++;
1130
1131
  offset_tmp = number_tmp * MINS_PER_HOUR; number_tmp= 0;
1132
1133
  while (str < end && my_isdigit(&my_charset_latin1, *str))
1134
  {
1135
    number_tmp= number_tmp * 10 + *str - '0';
1136
    str++;
1137
  }
1138
1139
  if (str != end)
1140
    return 1;
1141
1142
  offset_tmp= (offset_tmp + number_tmp) * SECS_PER_MIN;
1143
1144
  if (negative)
1145
    offset_tmp= -offset_tmp;
1146
1147
  /*
1148
    Check if offset is in range prescribed by standard
1149
    (from -12:59 to 13:00).
1150
  */
1151
1152
  if (number_tmp > 59 || offset_tmp < -13 * SECS_PER_HOUR + 1 ||
1153
      offset_tmp > 13 * SECS_PER_HOUR)
1154
    return 1;
1155
1156
  *offset= offset_tmp;
1157
1158
  return 0;
1159
}
1160
1161
1162
/*
1163
  Get Time_zone object for specified time zone.
1164
53.1.1 by Brian Aker
First pass through removing timezone. Left infrastructure for possible call
1165
  Not implemented yet. This needs to hook into some sort of OS system call.
1 by brian
clean slate
1166
1167
*/
1168
Time_zone *
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
1169
my_tz_find(THD *thd __attribute__((unused)),
1170
           const String *name __attribute__((unused)))
1 by brian
clean slate
1171
{
53.1.1 by Brian Aker
First pass through removing timezone. Left infrastructure for possible call
1172
  return NULL;
1173
}