1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
#include "drizzled/tzfile.h"
24
#include "drizzled/tztime.h"
25
#include "drizzled/gettext.h"
26
#include "drizzled/session.h"
27
#include "drizzled/time_functions.h"
33
* String with names of SYSTEM time zone.
1
/* Copyright (C) 2004 MySQL AB
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.
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.
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 */
17
#include <drizzled/server_includes.h>
20
/* Structure describing local time type (e.g. Moscow summer time (MSD)) */
23
long tt_gmtoff; // Offset from UTC in seconds
24
uint32_t tt_isdst; // Is daylight saving time or not. Used to set tm_isdst
25
uint32_t tt_abbrind; // Index of start of abbreviation for this time type.
27
We don't use tt_ttisstd and tt_ttisgmt members of original elsie-code
28
struct since we don't support POSIX-style TZ descriptions in variables.
32
/* Structure describing leap-second corrections. */
35
my_time_t ls_trans; // Transition time
36
long ls_corr; // Correction to apply
40
Structure with information describing ranges of my_time_t shifted to local
41
time (my_time_t + offset). Used for local DRIZZLE_TIME -> my_time_t conversion.
42
See comments for TIME_to_gmt_sec() for more info.
44
typedef struct revtinfo
46
long rt_offset; // Offset of local time from UTC in seconds
47
uint32_t rt_type; // Type of period 0 - Normal period. 1 - Spring time-gap
52
Structure which fully describes time zone which is
53
described in our db or in zoneinfo files.
55
typedef struct st_time_zone_info
57
uint32_t leapcnt; // Number of leap-second corrections
58
uint32_t timecnt; // Number of transitions between time types
59
uint32_t typecnt; // Number of local time types
60
uint32_t charcnt; // Number of characters used for abbreviations
61
uint32_t revcnt; // Number of transition descr. for TIME->my_time_t conversion
62
/* The following are dynamical arrays are allocated in MEM_ROOT */
63
my_time_t *ats; // Times of transitions between time types
64
unsigned char *types; // Local time types for transitions
65
TRAN_TYPE_INFO *ttis; // Local time types descriptions
66
/* Storage for local time types abbreviations. They are stored as ASCIIZ */
69
Leap seconds corrections descriptions, this array is shared by
70
all time zones who use leap seconds.
74
Starting points and descriptions of shifted my_time_t (my_time_t + offset)
75
ranges on which shifted my_time_t -> my_time_t mapping is linear or undefined.
76
Used for tm -> my_time_t conversion.
81
Time type which is used for times smaller than first transition or if
82
there are no transitions at all.
84
TRAN_TYPE_INFO *fallback_tti;
89
#if !defined(TZINFO2SQL)
91
static const uint32_t mon_lengths[2][MONS_PER_YEAR]=
93
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
94
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
97
static const uint32_t mon_starts[2][MONS_PER_YEAR]=
99
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
100
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
103
static const uint32_t year_lengths[2]=
105
DAYS_PER_NYEAR, DAYS_PER_LYEAR
108
#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
112
Converts time from my_time_t representation (seconds in UTC since Epoch)
113
to broken down representation using given local time zone offset.
117
tmp - pointer to structure for broken down representation
118
t - my_time_t value to be converted
119
offset - local time zone offset
122
Convert my_time_t with offset to DRIZZLE_TIME struct. Differs from timesub
123
(from elsie code) because doesn't contain any leap correction and
124
TM_GMTOFF and is_dst setting and contains some MySQL specific
125
initialization. Funny but with removing of these we almost have
126
glibc's offtime function.
129
sec_to_TIME(DRIZZLE_TIME * tmp, my_time_t t, long offset)
137
days= (long) (t / SECS_PER_DAY);
138
rem= (long) (t % SECS_PER_DAY);
141
We do this as separate step after dividing t, because this
142
allows us handle times near my_time_t bounds without overflows.
150
while (rem >= SECS_PER_DAY)
155
tmp->hour= (uint)(rem / SECS_PER_HOUR);
156
rem= rem % SECS_PER_HOUR;
157
tmp->minute= (uint)(rem / SECS_PER_MIN);
159
A positive leap second requires a special
160
representation. This uses "... ??:59:60" et seq.
162
tmp->second= (uint)(rem % SECS_PER_MIN);
165
while (days < 0 || days >= (long)year_lengths[yleap= isleap(y)])
169
newy= y + days / DAYS_PER_NYEAR;
172
days-= (newy - y) * DAYS_PER_NYEAR +
173
LEAPS_THRU_END_OF(newy - 1) -
174
LEAPS_THRU_END_OF(y - 1);
179
ip= mon_lengths[yleap];
180
for (tmp->month= 0; days >= (long) ip[tmp->month]; tmp->month++)
181
days= days - (long) ip[tmp->month];
183
tmp->day= (uint)(days + 1);
185
/* filling MySQL specific DRIZZLE_TIME members */
186
tmp->neg= 0; tmp->second_part= 0;
187
tmp->time_type= DRIZZLE_TIMESTAMP_DATETIME;
192
Find time range wich contains given my_time_t value
196
t - my_time_t value for which we looking for range
197
range_boundaries - sorted array of range starts.
198
higher_bound - number of ranges
201
Performs binary search for range which contains given my_time_t value.
202
It has sense if number of ranges is greater than zero and my_time_t value
203
is greater or equal than beginning of first range. It also assumes that
204
t belongs to some range specified or end of last is MY_TIME_T_MAX.
206
With this localtime_r on real data may takes less time than with linear
207
search (I've seen 30% speed up).
210
Index of range to which t belongs
213
find_time_range(my_time_t t, const my_time_t *range_boundaries,
214
uint32_t higher_bound)
216
uint32_t i, lower_bound= 0;
219
Function will work without this assertion but result would be meaningless.
221
assert(higher_bound > 0 && t >= range_boundaries[0]);
224
Do binary search for minimal interval which contain t. We preserve:
225
range_boundaries[lower_bound] <= t < range_boundaries[higher_bound]
226
invariant and decrease this higher_bound - lower_bound gap twice
230
while (higher_bound - lower_bound > 1)
232
i= (lower_bound + higher_bound) >> 1;
233
if (range_boundaries[i] <= t)
242
Find local time transition for given my_time_t.
245
find_transition_type()
246
t - my_time_t value to be converted
247
sp - pointer to struct with time zone description
250
Pointer to structure in time zone description describing
251
local time type for given my_time_t.
254
const TRAN_TYPE_INFO *
255
find_transition_type(my_time_t t, const TIME_ZONE_INFO *sp)
257
if (unlikely(sp->timecnt == 0 || t < sp->ats[0]))
260
If we have not any transitions or t is before first transition let
261
us use fallback time type.
263
return sp->fallback_tti;
267
Do binary search for minimal interval between transitions which
268
contain t. With this localtime_r on real data may takes less
269
time than with linear search (I've seen 30% speed up).
271
return &(sp->ttis[sp->types[find_time_range(t, sp->ats, sp->timecnt)]]);
276
Converts time in my_time_t representation (seconds in UTC since Epoch) to
277
broken down DRIZZLE_TIME representation in local time zone.
281
tmp - pointer to structure for broken down represenatation
282
sec_in_utc - my_time_t value to be converted
283
sp - pointer to struct with time zone description
286
We can improve this function by creating joined array of transitions and
287
leap corrections. This will require adding extra field to TRAN_TYPE_INFO
288
for storing number of "extra" seconds to minute occured due to correction
289
(60th and 61st second, look how we calculate them as "hit" in this
291
Under realistic assumptions about frequency of transitions the same array
292
can be used fot DRIZZLE_TIME -> my_time_t conversion. For this we need to
293
implement tweaked binary search which will take into account that some
294
DRIZZLE_TIME has two matching my_time_t ranges and some of them have none.
297
gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t sec_in_utc, const TIME_ZONE_INFO *sp)
299
const TRAN_TYPE_INFO *ttisp;
306
Find proper transition (and its local time type) for our sec_in_utc value.
307
Funny but again by separating this step in function we receive code
308
which very close to glibc's code. No wonder since they obviously use
309
the same base and all steps are sensible.
311
ttisp= find_transition_type(sec_in_utc, sp);
314
Let us find leap correction for our sec_in_utc value and number of extra
315
secs to add to this minute.
316
This loop is rarely used because most users will use time zones without
317
leap seconds, and even in case when we have such time zone there won't
318
be many iterations (we have about 22 corrections at this moment (2004)).
320
for ( i= sp->leapcnt; i-- > 0; )
323
if (sec_in_utc >= lp->ls_trans)
325
if (sec_in_utc == lp->ls_trans)
327
hit= ((i == 0 && lp->ls_corr > 0) ||
328
lp->ls_corr > sp->lsis[i - 1].ls_corr);
332
sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 &&
333
sp->lsis[i].ls_corr == sp->lsis[i - 1].ls_corr + 1)
345
sec_to_TIME(tmp, sec_in_utc, ttisp->tt_gmtoff - corr);
352
Converts local time in broken down representation to local
353
time zone analog of my_time_t represenation.
357
year, mon, mday, hour, min, sec - broken down representation.
360
Converts time in broken down representation to my_time_t representation
361
ignoring time zone. Note that we cannot convert back some valid _local_
362
times near ends of my_time_t range because of my_time_t overflow. But we
363
ignore this fact now since MySQL will never pass such argument.
366
Seconds since epoch time representation.
369
sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
371
/* Guard against my_time_t overflow(on system with 32 bit my_time_t) */
372
assert(!(year == TIMESTAMP_MAX_YEAR && mon == 1 && mday > 17));
373
#ifndef WE_WANT_TO_HANDLE_UNORMALIZED_DATES
375
It turns out that only whenever month is normalized or unnormalized
378
assert(mon > 0 && mon < 13);
379
long days= year * DAYS_PER_NYEAR - EPOCH_YEAR * DAYS_PER_NYEAR +
380
LEAPS_THRU_END_OF(year - 1) -
381
LEAPS_THRU_END_OF(EPOCH_YEAR - 1);
382
days+= mon_starts[isleap(year)][mon - 1];
384
long norm_month= (mon - 1) % MONS_PER_YEAR;
385
long a_year= year + (mon - 1)/MONS_PER_YEAR - (int)(norm_month < 0);
386
long days= a_year * DAYS_PER_NYEAR - EPOCH_YEAR * DAYS_PER_NYEAR +
387
LEAPS_THRU_END_OF(a_year - 1) -
388
LEAPS_THRU_END_OF(EPOCH_YEAR - 1);
389
days+= mon_starts[isleap(a_year)]
390
[norm_month + (norm_month < 0 ? MONS_PER_YEAR : 0)];
394
return ((days * HOURS_PER_DAY + hour) * MINS_PER_HOUR + min) *
399
Converts local time in broken down DRIZZLE_TIME representation to my_time_t
404
t - pointer to structure for broken down represenatation
405
sp - pointer to struct with time zone description
406
in_dst_time_gap - pointer to bool which is set to true if datetime
407
value passed doesn't really exist (i.e. falls into
408
spring time-gap) and is not touched otherwise.
411
This is mktime analog for MySQL. It is essentially different
412
from mktime (or hypotetical my_mktime) because:
413
- It has no idea about tm_isdst member so if it
414
has two answers it will give the smaller one
415
- If we are in spring time gap then it will return
417
- It can give wrong results near the ends of my_time_t due to
418
overflows, but we are safe since in MySQL we will never
419
call this function for such dates (its restriction for year
420
between 1970 and 2038 gives us several days of reserve).
421
- By default it doesn't support un-normalized input. But if
422
sec_since_epoch() function supports un-normalized dates
423
then this function should handle un-normalized input right,
424
altough it won't normalize structure TIME.
426
Traditional approach to problem of conversion from broken down
427
representation to time_t is iterative. Both elsie's and glibc
428
implementation try to guess what time_t value should correspond to
429
this broken-down value. They perform localtime_r function on their
430
guessed value and then calculate the difference and try to improve
431
their guess. Elsie's code guesses time_t value in bit by bit manner,
432
Glibc's code tries to add difference between broken-down value
433
corresponding to guess and target broken-down value to current guess.
434
It also uses caching of last found correction... So Glibc's approach
435
is essentially faster but introduces some undetermenism (in case if
436
is_dst member of broken-down representation (tm struct) is not known
437
and we have two possible answers).
439
We use completely different approach. It is better since it is both
440
faster than iterative implementations and fully determenistic. If you
441
look at my_time_t to DRIZZLE_TIME conversion then you'll find that it consist
443
The first is calculating shifted my_time_t value and the second - TIME
444
calculation from shifted my_time_t value (well it is a bit simplified
445
picture). The part in which we are interested in is my_time_t -> shifted
446
my_time_t conversion. It is piecewise linear function which is defined
447
by combination of transition times as break points and times offset
448
as changing function parameter. The possible inverse function for this
449
converison would be ambiguos but with MySQL's restrictions we can use
450
some function which is the same as inverse function on unambigiuos
451
ranges and coincides with one of branches of inverse function in
452
other ranges. Thus we just need to build table which will determine
453
this shifted my_time_t -> my_time_t conversion similar to existing
454
(my_time_t -> shifted my_time_t table). We do this in
455
prepare_tz_info function.
458
If we can even more improve this function. For doing this we will need to
459
build joined map of transitions and leap corrections for gmt_sec_to_TIME()
460
function (similar to revts/revtis). Under realistic assumptions about
461
frequency of transitions we can use the same array for TIME_to_gmt_sec().
462
We need to implement special version of binary search for this. Such step
463
will be beneficial to CPU cache since we will decrease data-set used for
467
Seconds in UTC since Epoch.
471
TIME_to_gmt_sec(const DRIZZLE_TIME *t, const TIME_ZONE_INFO *sp,
472
bool *in_dst_time_gap)
475
uint32_t saved_seconds;
479
if (!validate_timestamp_range(t))
483
/* We need this for correct leap seconds handling */
484
if (t->second < SECS_PER_MIN)
487
saved_seconds= t->second;
490
NOTE: to convert full my_time_t range we do a shift of the
491
boundary dates here to avoid overflow of my_time_t.
492
We use alike approach in my_system_gmt_sec().
494
However in that function we also have to take into account
495
overflow near 0 on some platforms. That's because my_system_gmt_sec
496
uses localtime_r(), which doesn't work with negative values correctly
497
on platforms with unsigned time_t (QNX). Here we don't use localtime()
498
=> we negative values of local_t are ok.
501
if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && t->day > 4)
504
We will pass (t->day - shift) to sec_since_epoch(), and
505
want this value to be a positive number, so we shift
506
only dates > 4.01.2038 (to avoid owerflow).
512
local_t= sec_since_epoch(t->year, t->month, (t->day - shift),
514
saved_seconds ? 0 : t->second);
516
/* We have at least one range */
517
assert(sp->revcnt >= 1);
519
if (local_t < sp->revts[0] || local_t > sp->revts[sp->revcnt])
522
This means that source time can't be represented as my_time_t due to
523
limited my_time_t range.
528
/* binary search for our range */
529
i= find_time_range(local_t, sp->revts, sp->revcnt);
532
As there are no offset switches at the end of TIMESTAMP range,
533
we could simply check for overflow here (and don't need to bother
538
if (local_t > (my_time_t) (TIMESTAMP_MAX_VALUE - shift * SECS_PER_DAY +
539
sp->revtis[i].rt_offset - saved_seconds))
541
return(0); /* my_time_t overflow */
543
local_t+= shift * SECS_PER_DAY;
546
if (sp->revtis[i].rt_type)
549
Oops! We are in spring time gap.
550
May be we should return error here?
551
Now we are returning my_time_t value corresponding to the
552
beginning of the gap.
555
local_t= sp->revts[i] - sp->revtis[i].rt_offset + saved_seconds;
558
local_t= local_t - sp->revtis[i].rt_offset + saved_seconds;
560
/* check for TIMESTAMP_MAX_VALUE was already done above */
561
if (local_t < TIMESTAMP_MIN_VALUE)
569
End of elsie derived code.
571
#endif /* !defined(TZINFO2SQL) */
575
String with names of SYSTEM time zone.
35
577
static const String tz_SYSTEM_name("SYSTEM", 6, &my_charset_utf8_general_ci);
39
* Instance of this class represents local time zone used on this system
40
* (specified by TZ environment variable or via any other system mechanism).
41
* It uses system functions (localtime_r, my_system_gmt_sec) for conversion
42
* and is always available. Because of this it is used by default - if there
43
* were no explicit time zone specified. On the other hand because of this
44
* conversion methods provided by this class is significantly slower and
45
* possibly less multi-threaded-friendly than corresponding Time_zone_db
46
* methods so the latter should be preffered there it is possible.
581
Instance of this class represents local time zone used on this system
582
(specified by TZ environment variable or via any other system mechanism).
583
It uses system functions (localtime_r, my_system_gmt_sec) for conversion
584
and is always available. Because of this it is used by default - if there
585
were no explicit time zone specified. On the other hand because of this
586
conversion methods provided by this class is significantly slower and
587
possibly less multi-threaded-friendly than corresponding Time_zone_db
588
methods so the latter should be preffered there it is possible.
48
590
class Time_zone_system : public Time_zone
51
593
Time_zone_system() {} /* Remove gcc warning */
52
virtual time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
594
virtual my_time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
53
595
bool *in_dst_time_gap) const;
54
virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, time_t t) const;
596
virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const;
55
597
virtual const String * get_name() const;
61
* Converts local time in system time zone in DRIZZLE_TIME representation
62
* to its time_t representation.
65
* This method uses system function (localtime_r()) for conversion
66
* local time in system time zone in DRIZZLE_TIME structure to its time_t
67
* representation. Unlike the same function for Time_zone_db class
68
* it it won't handle unnormalized input properly. Still it will
69
* return lowest possible time_t in case of ambiguity or if we
70
* provide time corresponding to the time-gap.
72
* You should call init_time() function before using this function.
74
* @param t pointer to DRIZZLE_TIME structure with local time in
75
* broken-down representation.
76
* @param in_dst_time_gap pointer to bool which is set to true if datetime
77
* value passed doesn't really exist (i.e. falls into
78
* spring time-gap) and is not touched otherwise.
81
* Corresponding time_t value or 0 in case of error
602
Converts local time in system time zone in DRIZZLE_TIME representation
603
to its my_time_t representation.
607
t - pointer to DRIZZLE_TIME structure with local time in
608
broken-down representation.
609
in_dst_time_gap - pointer to bool which is set to true if datetime
610
value passed doesn't really exist (i.e. falls into
611
spring time-gap) and is not touched otherwise.
614
This method uses system function (localtime_r()) for conversion
615
local time in system time zone in DRIZZLE_TIME structure to its my_time_t
616
representation. Unlike the same function for Time_zone_db class
617
it it won't handle unnormalized input properly. Still it will
618
return lowest possible my_time_t in case of ambiguity or if we
619
provide time corresponding to the time-gap.
621
You should call init_time() function before using this function.
624
Corresponding my_time_t value or 0 in case of error
84
627
Time_zone_system::TIME_to_gmt_sec(const DRIZZLE_TIME *t, bool *in_dst_time_gap) const
119
* Get name of time zone
122
* Name of time zone as String
663
Get name of time zone
669
Name of time zone as String
125
672
Time_zone_system::get_name() const
127
674
return &tz_SYSTEM_name;
679
Instance of this class represents UTC time zone. It uses system gmtime_r
680
function for conversions and is always available. It is used only for
681
my_time_t -> DRIZZLE_TIME conversions in various UTC_... functions, it is not
682
intended for DRIZZLE_TIME -> my_time_t conversions and shouldn't be exposed to user.
684
class Time_zone_utc : public Time_zone
687
Time_zone_utc() {} /* Remove gcc warning */
688
virtual my_time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
689
bool *in_dst_time_gap) const;
690
virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const;
691
virtual const String * get_name() const;
696
Convert UTC time from DRIZZLE_TIME representation to its my_time_t representation.
700
t - pointer to DRIZZLE_TIME structure with local time
701
in broken-down representation.
702
in_dst_time_gap - pointer to bool which is set to true if datetime
703
value passed doesn't really exist (i.e. falls into
704
spring time-gap) and is not touched otherwise.
707
Since Time_zone_utc is used only internally for my_time_t -> TIME
708
conversions, this function of Time_zone interface is not implemented for
709
this class and should not be called.
715
Time_zone_utc::TIME_to_gmt_sec(const DRIZZLE_TIME *t __attribute__((unused)),
716
bool *in_dst_time_gap __attribute__((unused))) const
718
/* Should be never called */
725
Converts time from UTC seconds since Epoch (my_time_t) representation
726
to broken-down representation (also in UTC).
730
tmp - pointer to DRIZZLE_TIME structure to fill-in
731
t - my_time_t value to be converted
734
See note for apropriate Time_zone_system method.
737
Time_zone_utc::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const
740
time_t tmp_t= (time_t)t;
741
gmtime_r(&tmp_t, &tmp_tm);
742
localtime_to_TIME(tmp, &tmp_tm);
743
tmp->time_type= DRIZZLE_TIMESTAMP_DATETIME;
748
Get name of time zone
754
Since Time_zone_utc is used only internally by SQL's UTC_* functions it
755
is not accessible directly, and hence this function of Time_zone
756
interface is not implemented for this class and should not be called.
762
Time_zone_utc::get_name() const
764
/* Should be never called */
771
Instance of this class represents some time zone which is
772
described in mysql.time_zone family of tables.
774
class Time_zone_db : public Time_zone
777
Time_zone_db(TIME_ZONE_INFO *tz_info_arg, const String * tz_name_arg);
778
virtual my_time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
779
bool *in_dst_time_gap) const;
780
virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const;
781
virtual const String * get_name() const;
783
TIME_ZONE_INFO *tz_info;
784
const String *tz_name;
789
Initializes object representing time zone described by mysql.time_zone
794
tz_info_arg - pointer to TIME_ZONE_INFO structure which is filled
795
according to db or other time zone description
796
(for example by my_tz_init()).
797
Several Time_zone_db instances can share one
798
TIME_ZONE_INFO structure.
799
tz_name_arg - name of time zone.
801
Time_zone_db::Time_zone_db(TIME_ZONE_INFO *tz_info_arg,
802
const String *tz_name_arg):
803
tz_info(tz_info_arg), tz_name(tz_name_arg)
809
Converts local time in time zone described from TIME
810
representation to its my_time_t representation.
814
t - pointer to DRIZZLE_TIME structure with local time
815
in broken-down representation.
816
in_dst_time_gap - pointer to bool which is set to true if datetime
817
value passed doesn't really exist (i.e. falls into
818
spring time-gap) and is not touched otherwise.
821
Please see ::TIME_to_gmt_sec for function description and
822
parameter restrictions.
825
Corresponding my_time_t value or 0 in case of error
828
Time_zone_db::TIME_to_gmt_sec(const DRIZZLE_TIME *t, bool *in_dst_time_gap) const
830
return ::TIME_to_gmt_sec(t, tz_info, in_dst_time_gap);
835
Converts time from UTC seconds since Epoch (my_time_t) representation
836
to local time zone described in broken-down representation.
840
tmp - pointer to DRIZZLE_TIME structure to fill-in
841
t - my_time_t value to be converted
844
Time_zone_db::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const
846
::gmt_sec_to_TIME(tmp, t, tz_info);
851
Get name of time zone
857
Name of time zone as ASCIIZ-string
860
Time_zone_db::get_name() const
867
Instance of this class represents time zone which
868
was specified as offset from UTC.
870
class Time_zone_offset : public Time_zone
873
Time_zone_offset(long tz_offset_arg);
874
virtual my_time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
875
bool *in_dst_time_gap) const;
876
virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const;
877
virtual const String * get_name() const;
879
This have to be public because we want to be able to access it from
880
my_offset_tzs_get_key() function
884
/* Extra reserve because of snprintf */
885
char name_buff[7+16];
891
Initializes object representing time zone described by its offset from UTC.
895
tz_offset_arg - offset from UTC in seconds.
896
Positive for direction to east.
898
Time_zone_offset::Time_zone_offset(long tz_offset_arg):
899
offset(tz_offset_arg)
901
uint32_t hours= abs((int)(offset / SECS_PER_HOUR));
902
uint32_t minutes= abs((int)(offset % SECS_PER_HOUR / SECS_PER_MIN));
903
ulong length= snprintf(name_buff, sizeof(name_buff), "%s%02d:%02d",
904
(offset>=0) ? "+" : "-", hours, minutes);
905
name.set(name_buff, length, &my_charset_utf8_general_ci);
910
Converts local time in time zone described as offset from UTC
911
from DRIZZLE_TIME representation to its my_time_t representation.
915
t - pointer to DRIZZLE_TIME structure with local time
916
in broken-down representation.
917
in_dst_time_gap - pointer to bool which should be set to true if
918
datetime value passed doesn't really exist
919
(i.e. falls into spring time-gap) and is not
921
It is not really used in this class.
924
Corresponding my_time_t value or 0 in case of error
927
Time_zone_offset::TIME_to_gmt_sec(const DRIZZLE_TIME *t,
928
bool *in_dst_time_gap __attribute__((unused))) const
934
Check timestamp range.we have to do this as calling function relies on
935
us to make all validation checks here.
937
if (!validate_timestamp_range(t))
941
Do a temporary shift of the boundary dates to avoid
942
overflow of my_time_t if the time value is near it's
945
if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && t->day > 4)
948
local_t= sec_since_epoch(t->year, t->month, (t->day - shift),
949
t->hour, t->minute, t->second) -
954
/* Add back the shifted time */
955
local_t+= shift * SECS_PER_DAY;
958
if (local_t >= TIMESTAMP_MIN_VALUE && local_t <= TIMESTAMP_MAX_VALUE)
967
Converts time from UTC seconds since Epoch (my_time_t) representation
968
to local time zone described as offset from UTC and in broken-down
973
tmp - pointer to DRIZZLE_TIME structure to fill-in
974
t - my_time_t value to be converted
977
Time_zone_offset::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, my_time_t t) const
979
sec_to_TIME(tmp, t, offset);
984
Get name of time zone
990
Name of time zone as pointer to String object
993
Time_zone_offset::get_name() const
999
static Time_zone_utc tz_UTC;
130
1000
static Time_zone_system tz_SYSTEM;
1001
static Time_zone_offset tz_OFFSET0(0);
1003
Time_zone *my_tz_OFFSET0= &tz_OFFSET0;
1004
Time_zone *my_tz_UTC= &tz_UTC;
132
1005
Time_zone *my_tz_SYSTEM= &tz_SYSTEM;
137
* Initialize time zone support infrastructure.
140
* This function will init memory structures needed for time zone support,
141
* it will register mandatory SYSTEM time zone in them. It will try to open
142
* mysql.time_zone* tables and load information about default time zone and
143
* information which further will be shared among all time zones loaded.
144
* If system tables with time zone descriptions don't exist it won't fail
145
* (unless default_tzname is time zone from tables). If bootstrap parameter
146
* is true then this routine assumes that we are in bootstrap mode and won't
147
* load time zone descriptions unless someone specifies default time zone
148
* which is supposedly stored in those tables.
149
* It'll also set default time zone if it is specified.
151
* @param session current thread object
152
* @param default_tzname default time zone or 0 if none.
153
* @param bootstrap indicates whenever we are in bootstrap mode
1007
class Tz_names_entry: public Sql_alloc
1016
Initialize time zone support infrastructure.
1020
thd - current thread object
1021
default_tzname - default time zone or 0 if none.
1022
bootstrap - indicates whenever we are in bootstrap mode
1025
This function will init memory structures needed for time zone support,
1026
it will register mandatory SYSTEM time zone in them. It will try to open
1027
mysql.time_zone* tables and load information about default time zone and
1028
information which further will be shared among all time zones loaded.
1029
If system tables with time zone descriptions don't exist it won't fail
1030
(unless default_tzname is time zone from tables). If bootstrap parameter
1031
is true then this routine assumes that we are in bootstrap mode and won't
1032
load time zone descriptions unless someone specifies default time zone
1033
which is supposedly stored in those tables.
1034
It'll also set default time zone if it is specified.
160
my_tz_init(Session *session, const char *default_tzname)
1041
my_tz_init(THD *thd, const char *default_tzname)
162
1043
if (default_tzname)