21
#include <drizzled/server_includes.h>
22
#include <drizzled/tzfile.h>
23
#include <drizzled/tztime.h>
24
#include <drizzled/gettext.h>
25
#include <drizzled/session.h>
27
/* Structure describing local time type (e.g. Moscow summer time (MSD)) */
30
long tt_gmtoff; // Offset from UTC in seconds
31
uint32_t tt_isdst; // Is daylight saving time or not. Used to set tm_isdst
32
uint32_t tt_abbrind; // Index of start of abbreviation for this time type.
34
We don't use tt_ttisstd and tt_ttisgmt members of original elsie-code
35
struct since we don't support POSIX-style TZ descriptions in variables.
39
/* Structure describing leap-second corrections. */
42
time_t ls_trans; // Transition time
43
long ls_corr; // Correction to apply
47
Structure with information describing ranges of time_t shifted to local
48
time (time_t + offset). Used for local DRIZZLE_TIME -> time_t conversion.
49
See comments for TIME_to_gmt_sec() for more info.
51
typedef struct revtinfo
53
long rt_offset; // Offset of local time from UTC in seconds
54
uint32_t rt_type; // Type of period 0 - Normal period. 1 - Spring time-gap
59
Structure which fully describes time zone which is
60
described in our db or in zoneinfo files.
62
typedef struct st_time_zone_info
64
uint32_t leapcnt; // Number of leap-second corrections
65
uint32_t timecnt; // Number of transitions between time types
66
uint32_t typecnt; // Number of local time types
67
uint32_t charcnt; // Number of characters used for abbreviations
68
uint32_t revcnt; // Number of transition descr. for TIME->time_t conversion
69
/* The following are dynamical arrays are allocated in MEM_ROOT */
70
time_t *ats; // Times of transitions between time types
71
unsigned char *types; // Local time types for transitions
72
TRAN_TYPE_INFO *ttis; // Local time types descriptions
73
/* Storage for local time types abbreviations. They are stored as ASCIIZ */
76
Leap seconds corrections descriptions, this array is shared by
77
all time zones who use leap seconds.
81
Starting points and descriptions of shifted time_t (time_t + offset)
82
ranges on which shifted time_t -> time_t mapping is linear or undefined.
83
Used for tm -> time_t conversion.
88
Time type which is used for times smaller than first transition or if
89
there are no transitions at all.
91
TRAN_TYPE_INFO *fallback_tti;
96
#if !defined(TZINFO2SQL)
98
static const uint32_t mon_lengths[2][MONS_PER_YEAR]=
100
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
101
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
104
static const uint32_t mon_starts[2][MONS_PER_YEAR]=
106
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
107
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
110
static const uint32_t year_lengths[2]=
112
DAYS_PER_NYEAR, DAYS_PER_LYEAR
115
#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
119
Converts time from time_t representation (seconds in UTC since Epoch)
120
to broken down representation using given local time zone offset.
124
tmp - pointer to structure for broken down representation
125
t - time_t value to be converted
126
offset - local time zone offset
129
Convert time_t with offset to DRIZZLE_TIME struct. Differs from timesub
130
(from elsie code) because doesn't contain any leap correction and
131
TM_GMTOFF and is_dst setting and contains some MySQL specific
132
initialization. Funny but with removing of these we almost have
133
glibc's offtime function.
136
sec_to_TIME(DRIZZLE_TIME * tmp, time_t t, long offset)
144
days= (long) (t / SECS_PER_DAY);
145
rem= (long) (t % SECS_PER_DAY);
148
We do this as separate step after dividing t, because this
149
allows us handle times near time_t bounds without overflows.
157
while (rem >= SECS_PER_DAY)
162
tmp->hour= (uint32_t)(rem / SECS_PER_HOUR);
163
rem= rem % SECS_PER_HOUR;
164
tmp->minute= (uint32_t)(rem / SECS_PER_MIN);
166
A positive leap second requires a special
167
representation. This uses "... ??:59:60" et seq.
169
tmp->second= (uint32_t)(rem % SECS_PER_MIN);
172
while (days < 0 || days >= (long)year_lengths[yleap= isleap(y)])
176
newy= y + days / DAYS_PER_NYEAR;
179
days-= (newy - y) * DAYS_PER_NYEAR +
180
LEAPS_THRU_END_OF(newy - 1) -
181
LEAPS_THRU_END_OF(y - 1);
186
ip= mon_lengths[yleap];
187
for (tmp->month= 0; days >= (long) ip[tmp->month]; tmp->month++)
188
days= days - (long) ip[tmp->month];
190
tmp->day= (uint32_t)(days + 1);
192
/* filling MySQL specific DRIZZLE_TIME members */
193
tmp->neg= 0; tmp->second_part= 0;
194
tmp->time_type= DRIZZLE_TIMESTAMP_DATETIME;
199
Find time range wich contains given time_t value
203
t - time_t value for which we looking for range
204
range_boundaries - sorted array of range starts.
205
higher_bound - number of ranges
208
Performs binary search for range which contains given time_t value.
209
It has sense if number of ranges is greater than zero and time_t value
210
is greater or equal than beginning of first range. It also assumes that
211
t belongs to some range specified.
213
With this localtime_r on real data may takes less time than with linear
214
search (I've seen 30% speed up).
217
Index of range to which t belongs
220
find_time_range(time_t t, const time_t *range_boundaries,
221
uint32_t higher_bound)
223
uint32_t i, lower_bound= 0;
226
Function will work without this assertion but result would be meaningless.
228
assert(higher_bound > 0 && t >= range_boundaries[0]);
231
Do binary search for minimal interval which contain t. We preserve:
232
range_boundaries[lower_bound] <= t < range_boundaries[higher_bound]
233
invariant and decrease this higher_bound - lower_bound gap twice
237
while (higher_bound - lower_bound > 1)
239
i= (lower_bound + higher_bound) >> 1;
240
if (range_boundaries[i] <= t)
249
Find local time transition for given time_t.
252
find_transition_type()
253
t - time_t value to be converted
254
sp - pointer to struct with time zone description
257
Pointer to structure in time zone description describing
258
local time type for given time_t.
261
const TRAN_TYPE_INFO *
262
find_transition_type(time_t t, const TIME_ZONE_INFO *sp)
264
if (unlikely(sp->timecnt == 0 || t < sp->ats[0]))
267
If we have not any transitions or t is before first transition let
268
us use fallback time type.
270
return sp->fallback_tti;
274
Do binary search for minimal interval between transitions which
275
contain t. With this localtime_r on real data may takes less
276
time than with linear search (I've seen 30% speed up).
278
return &(sp->ttis[sp->types[find_time_range(t, sp->ats, sp->timecnt)]]);
283
Converts time in time_t representation (seconds in UTC since Epoch) to
284
broken down DRIZZLE_TIME representation in local time zone.
288
tmp - pointer to structure for broken down represenatation
289
sec_in_utc - time_t value to be converted
290
sp - pointer to struct with time zone description
293
We can improve this function by creating joined array of transitions and
294
leap corrections. This will require adding extra field to TRAN_TYPE_INFO
295
for storing number of "extra" seconds to minute occured due to correction
296
(60th and 61st second, look how we calculate them as "hit" in this
298
Under realistic assumptions about frequency of transitions the same array
299
can be used for DRIZZLE_TIME -> time_t conversion. For this we need to
300
implement tweaked binary search which will take into account that some
301
DRIZZLE_TIME has two matching time_t ranges and some of them have none.
304
gmt_sec_to_TIME(DRIZZLE_TIME *tmp, time_t sec_in_utc, const TIME_ZONE_INFO *sp)
306
const TRAN_TYPE_INFO *ttisp;
313
Find proper transition (and its local time type) for our sec_in_utc value.
314
Funny but again by separating this step in function we receive code
315
which very close to glibc's code. No wonder since they obviously use
316
the same base and all steps are sensible.
318
ttisp= find_transition_type(sec_in_utc, sp);
321
Let us find leap correction for our sec_in_utc value and number of extra
322
secs to add to this minute.
323
This loop is rarely used because most users will use time zones without
324
leap seconds, and even in case when we have such time zone there won't
325
be many iterations (we have about 22 corrections at this moment (2004)).
327
for ( i= sp->leapcnt; i-- > 0; )
330
if (sec_in_utc >= lp->ls_trans)
332
if (sec_in_utc == lp->ls_trans)
334
hit= ((i == 0 && lp->ls_corr > 0) ||
335
lp->ls_corr > sp->lsis[i - 1].ls_corr);
339
sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 &&
340
sp->lsis[i].ls_corr == sp->lsis[i - 1].ls_corr + 1)
352
sec_to_TIME(tmp, sec_in_utc, ttisp->tt_gmtoff - corr);
359
Converts local time in broken down representation to local
360
time zone analog of time_t represenation.
364
year, mon, mday, hour, min, sec - broken down representation.
367
Converts time in broken down representation to time_t representation
368
ignoring time zone. Note that we cannot convert back some valid _local_
369
times near ends of time_t range because of time_t overflow. But we
370
ignore this fact now since MySQL will never pass such argument.
373
Seconds since epoch time representation.
376
sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
378
/* Guard against time_t overflow (on system with 32 bit time_t) */
379
assert(!(year == TIMESTAMP_MAX_YEAR && mon == 1 && mday > 17));
380
#ifndef WE_WANT_TO_HANDLE_UNORMALIZED_DATES
382
It turns out that only whenever month is normalized or unnormalized
385
assert(mon > 0 && mon < 13);
386
long days= year * DAYS_PER_NYEAR - EPOCH_YEAR * DAYS_PER_NYEAR +
387
LEAPS_THRU_END_OF(year - 1) -
388
LEAPS_THRU_END_OF(EPOCH_YEAR - 1);
389
days+= mon_starts[isleap(year)][mon - 1];
391
long norm_month= (mon - 1) % MONS_PER_YEAR;
392
long a_year= year + (mon - 1)/MONS_PER_YEAR - (int)(norm_month < 0);
393
long days= a_year * DAYS_PER_NYEAR - EPOCH_YEAR * DAYS_PER_NYEAR +
394
LEAPS_THRU_END_OF(a_year - 1) -
395
LEAPS_THRU_END_OF(EPOCH_YEAR - 1);
396
days+= mon_starts[isleap(a_year)]
397
[norm_month + (norm_month < 0 ? MONS_PER_YEAR : 0)];
401
return ((days * HOURS_PER_DAY + hour) * MINS_PER_HOUR + min) *
406
Converts local time in broken down DRIZZLE_TIME representation to time_t
411
t - pointer to structure for broken down represenatation
412
sp - pointer to struct with time zone description
413
in_dst_time_gap - pointer to bool which is set to true if datetime
414
value passed doesn't really exist (i.e. falls into
415
spring time-gap) and is not touched otherwise.
418
This is mktime analog for MySQL. It is essentially different
419
from mktime (or hypotetical my_mktime) because:
420
- It has no idea about tm_isdst member so if it
421
has two answers it will give the smaller one
422
- If we are in spring time gap then it will return
424
- It can give wrong results near the ends of time_t due to
425
overflows, but we are safe since in MySQL we will never
426
call this function for such dates (its restriction for year
427
between 1970 and 2038 gives us several days of reserve).
428
- By default it doesn't support un-normalized input. But if
429
sec_since_epoch() function supports un-normalized dates
430
then this function should handle un-normalized input right,
431
altough it won't normalize structure TIME.
433
Traditional approach to problem of conversion from broken down
434
representation to time_t is iterative. Both elsie's and glibc
435
implementation try to guess what time_t value should correspond to
436
this broken-down value. They perform localtime_r function on their
437
guessed value and then calculate the difference and try to improve
438
their guess. Elsie's code guesses time_t value in bit by bit manner,
439
Glibc's code tries to add difference between broken-down value
440
corresponding to guess and target broken-down value to current guess.
441
It also uses caching of last found correction... So Glibc's approach
442
is essentially faster but introduces some undetermenism (in case if
443
is_dst member of broken-down representation (tm struct) is not known
444
and we have two possible answers).
446
We use completely different approach. It is better since it is both
447
faster than iterative implementations and fully determenistic. If you
448
look at time_t to DRIZZLE_TIME conversion then you'll find that it consist
450
The first is calculating shifted time_t value and the second - TIME
451
calculation from shifted time_t value (well it is a bit simplified
452
picture). The part in which we are interested in is time_t -> shifted
453
time_t conversion. It is piecewise linear function which is defined
454
by combination of transition times as break points and times offset
455
as changing function parameter. The possible inverse function for this
456
converison would be ambiguos but with MySQL's restrictions we can use
457
some function which is the same as inverse function on unambigiuos
458
ranges and coincides with one of branches of inverse function in
459
other ranges. Thus we just need to build table which will determine
460
this shifted time_t -> time_t conversion similar to existing
461
(time_t -> shifted time_t table). We do this in
462
prepare_tz_info function.
465
If we can even more improve this function. For doing this we will need to
466
build joined map of transitions and leap corrections for gmt_sec_to_TIME()
467
function (similar to revts/revtis). Under realistic assumptions about
468
frequency of transitions we can use the same array for TIME_to_gmt_sec().
469
We need to implement special version of binary search for this. Such step
470
will be beneficial to CPU cache since we will decrease data-set used for
474
Seconds in UTC since Epoch.
478
TIME_to_gmt_sec(const DRIZZLE_TIME *t, const TIME_ZONE_INFO *sp,
479
bool *in_dst_time_gap)
482
uint32_t saved_seconds;
486
if (!validate_timestamp_range(t))
490
/* We need this for correct leap seconds handling */
491
if (t->second < SECS_PER_MIN)
494
saved_seconds= t->second;
497
NOTE: to convert full time_t range we do a shift of the
498
boundary dates here to avoid overflow of time_t.
499
We use alike approach in my_system_gmt_sec().
501
However in that function we also have to take into account
502
overflow near 0 on some platforms. That's because my_system_gmt_sec
503
uses localtime_r(), which doesn't work with negative values correctly
504
on platforms with unsigned time_t (QNX). Here we don't use localtime()
505
=> we negative values of local_t are ok.
508
if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && t->day > 4)
511
We will pass (t->day - shift) to sec_since_epoch(), and
512
want this value to be a positive number, so we shift
513
only dates > 4.01.2038 (to avoid owerflow).
519
local_t= sec_since_epoch(t->year, t->month, (t->day - shift),
521
saved_seconds ? 0 : t->second);
523
/* We have at least one range */
524
assert(sp->revcnt >= 1);
526
if (local_t < sp->revts[0] || local_t > sp->revts[sp->revcnt])
529
This means that source time can't be represented as time_t due to
530
limited time_t range.
535
/* binary search for our range */
536
i= find_time_range(local_t, sp->revts, sp->revcnt);
539
As there are no offset switches at the end of TIMESTAMP range,
540
we could simply check for overflow here (and don't need to bother
545
if (local_t > (time_t) (TIMESTAMP_MAX_VALUE - shift * SECS_PER_DAY +
546
sp->revtis[i].rt_offset - saved_seconds))
548
return(0); /* time_t overflow */
550
local_t+= shift * SECS_PER_DAY;
553
if (sp->revtis[i].rt_type)
556
Oops! We are in spring time gap.
557
May be we should return error here?
558
Now we are returning time_t value corresponding to the
559
beginning of the gap.
562
local_t= sp->revts[i] - sp->revtis[i].rt_offset + saved_seconds;
565
local_t= local_t - sp->revtis[i].rt_offset + saved_seconds;
567
/* check for TIMESTAMP_MAX_VALUE was already done above */
568
if (local_t < TIMESTAMP_MIN_VALUE)
576
End of elsie derived code.
578
#endif /* !defined(TZINFO2SQL) */
582
String with names of SYSTEM time zone.
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.
584
35
static const String tz_SYSTEM_name("SYSTEM", 6, &my_charset_utf8_general_ci);
588
Instance of this class represents local time zone used on this system
589
(specified by TZ environment variable or via any other system mechanism).
590
It uses system functions (localtime_r, my_system_gmt_sec) for conversion
591
and is always available. Because of this it is used by default - if there
592
were no explicit time zone specified. On the other hand because of this
593
conversion methods provided by this class is significantly slower and
594
possibly less multi-threaded-friendly than corresponding Time_zone_db
595
methods so the latter should be preffered there it is possible.
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.
597
48
class Time_zone_system : public Time_zone
600
51
Time_zone_system() {} /* Remove gcc warning */
601
virtual time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
602
bool *in_dst_time_gap) const;
603
virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, time_t t) const;
52
virtual type::Time::epoch_t TIME_to_gmt_sec(const type::Time &t,
53
bool *in_dst_time_gap) const;
54
virtual void gmt_sec_to_TIME(type::Time &tmp, type::Time::epoch_t t) const;
604
55
virtual const String * get_name() const;
609
Converts local time in system time zone in DRIZZLE_TIME representation
610
to its time_t representation.
614
t - pointer to DRIZZLE_TIME structure with local time in
615
broken-down representation.
616
in_dst_time_gap - pointer to bool which is set to true if datetime
617
value passed doesn't really exist (i.e. falls into
618
spring time-gap) and is not touched otherwise.
621
This method uses system function (localtime_r()) for conversion
622
local time in system time zone in DRIZZLE_TIME structure to its time_t
623
representation. Unlike the same function for Time_zone_db class
624
it it won't handle unnormalized input properly. Still it will
625
return lowest possible time_t in case of ambiguity or if we
626
provide time corresponding to the time-gap.
628
You should call init_time() function before using this function.
631
Corresponding time_t value or 0 in case of error
634
Time_zone_system::TIME_to_gmt_sec(const DRIZZLE_TIME *t, bool *in_dst_time_gap) const
61
* Converts local time in system time zone in type::Time representation
62
* to its type::Time::epoch_t representation.
65
* This method uses system function (localtime_r()) for conversion
66
* local time in system time zone in type::Time structure to its type::Time::epoch_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 type::Time::epoch_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 type::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 type::Time::epoch_t value or 0 in case of error
84
Time_zone_system::TIME_to_gmt_sec(const type::Time &t, bool *in_dst_time_gap) const
637
return my_system_gmt_sec(t, ¬_used, in_dst_time_gap);
87
type::Time::epoch_t tmp;
88
t.convert(tmp, ¬_used, in_dst_time_gap);
642
Converts time from UTC seconds since Epoch (time_t) representation
643
to system local time zone broken-down representation.
647
tmp - pointer to DRIZZLE_TIME structure to fill-in
648
t - time_t value to be converted
651
We assume that value passed to this function will fit into time_t range
652
supported by localtime_r. This conversion is putting restriction on
653
TIMESTAMP range in MySQL. If we can get rid of SYSTEM time zone at least
654
for interaction with client then we can extend TIMESTAMP range down to
95
* Converts time from UTC seconds since Epoch (type::Time::epoch_t) representation
96
* to system local time zone broken-down representation.
98
* @param tmp pointer to type::Time structure to fill-in
99
* @param t type::Time::epoch_t value to be converted
101
* Note: We assume that value passed to this function will fit into type::Time::epoch_t range
102
* supported by localtime_r. This conversion is putting restriction on
103
* TIMESTAMP range in MySQL. If we can get rid of SYSTEM time zone at least
104
* for interaction with client then we can extend TIMESTAMP range down to
658
Time_zone_system::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, time_t t) const
108
Time_zone_system::gmt_sec_to_TIME(type::Time &tmp, type::Time::epoch_t t) const
661
time_t tmp_t= (time_t)t;
663
localtime_r(&tmp_t, &tmp_tm);
664
localtime_to_TIME(tmp, &tmp_tm);
665
tmp->time_type= DRIZZLE_TIMESTAMP_DATETIME;
670
Get name of time zone
676
Name of time zone as String
116
* Get name of time zone
119
* Name of time zone as String
679
122
Time_zone_system::get_name() const
681
124
return &tz_SYSTEM_name;
686
Instance of this class represents UTC time zone. It uses system gmtime_r
687
function for conversions and is always available. It is used only for
688
time_t -> DRIZZLE_TIME conversions in various UTC_... functions, it is not
689
intended for DRIZZLE_TIME -> time_t conversions and shouldn't be exposed to user.
691
class Time_zone_utc : public Time_zone
694
Time_zone_utc() {} /* Remove gcc warning */
695
virtual time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
696
bool *in_dst_time_gap) const;
697
virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, time_t t) const;
698
virtual const String * get_name() const;
703
Convert UTC time from DRIZZLE_TIME representation to its time_t representation.
707
t - pointer to DRIZZLE_TIME structure with local time
708
in broken-down representation.
709
in_dst_time_gap - pointer to bool which is set to true if datetime
710
value passed doesn't really exist (i.e. falls into
711
spring time-gap) and is not touched otherwise.
714
Since Time_zone_utc is used only internally for time_t -> TIME
715
conversions, this function of Time_zone interface is not implemented for
716
this class and should not be called.
722
Time_zone_utc::TIME_to_gmt_sec(const DRIZZLE_TIME *,
725
/* Should be never called */
732
Converts time from UTC seconds since Epoch (time_t) representation
733
to broken-down representation (also in UTC).
737
tmp - pointer to DRIZZLE_TIME structure to fill-in
738
t - time_t value to be converted
741
See note for apropriate Time_zone_system method.
744
Time_zone_utc::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, time_t t) const
747
time_t tmp_t= (time_t)t;
748
gmtime_r(&tmp_t, &tmp_tm);
749
localtime_to_TIME(tmp, &tmp_tm);
750
tmp->time_type= DRIZZLE_TIMESTAMP_DATETIME;
755
Get name of time zone
761
Since Time_zone_utc is used only internally by SQL's UTC_* functions it
762
is not accessible directly, and hence this function of Time_zone
763
interface is not implemented for this class and should not be called.
769
Time_zone_utc::get_name() const
771
/* Should be never called */
778
Instance of this class represents some time zone which is
779
described in mysql.time_zone family of tables.
781
class Time_zone_db : public Time_zone
784
Time_zone_db(TIME_ZONE_INFO *tz_info_arg, const String * tz_name_arg);
785
virtual time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
786
bool *in_dst_time_gap) const;
787
virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, time_t t) const;
788
virtual const String * get_name() const;
790
TIME_ZONE_INFO *tz_info;
791
const String *tz_name;
796
Initializes object representing time zone described by mysql.time_zone
801
tz_info_arg - pointer to TIME_ZONE_INFO structure which is filled
802
according to db or other time zone description
803
(for example by my_tz_init()).
804
Several Time_zone_db instances can share one
805
TIME_ZONE_INFO structure.
806
tz_name_arg - name of time zone.
808
Time_zone_db::Time_zone_db(TIME_ZONE_INFO *tz_info_arg,
809
const String *tz_name_arg):
810
tz_info(tz_info_arg), tz_name(tz_name_arg)
816
Converts local time in time zone described from TIME
817
representation to its time_t representation.
821
t - pointer to DRIZZLE_TIME structure with local time
822
in broken-down representation.
823
in_dst_time_gap - pointer to bool which is set to true if datetime
824
value passed doesn't really exist (i.e. falls into
825
spring time-gap) and is not touched otherwise.
828
Please see ::TIME_to_gmt_sec for function description and
829
parameter restrictions.
832
Corresponding time_t value or 0 in case of error
835
Time_zone_db::TIME_to_gmt_sec(const DRIZZLE_TIME *t, bool *in_dst_time_gap) const
837
return ::TIME_to_gmt_sec(t, tz_info, in_dst_time_gap);
842
Converts time from UTC seconds since Epoch (time_t) representation
843
to local time zone described in broken-down representation.
847
tmp - pointer to DRIZZLE_TIME structure to fill-in
848
t - time_t value to be converted
851
Time_zone_db::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, time_t t) const
853
::gmt_sec_to_TIME(tmp, t, tz_info);
858
Get name of time zone
864
Name of time zone as ASCIIZ-string
867
Time_zone_db::get_name() const
874
Instance of this class represents time zone which
875
was specified as offset from UTC.
877
class Time_zone_offset : public Time_zone
880
Time_zone_offset(long tz_offset_arg);
881
virtual time_t TIME_to_gmt_sec(const DRIZZLE_TIME *t,
882
bool *in_dst_time_gap) const;
883
virtual void gmt_sec_to_TIME(DRIZZLE_TIME *tmp, time_t t) const;
884
virtual const String * get_name() const;
886
This have to be public because we want to be able to access it from
887
my_offset_tzs_get_key() function
891
/* Extra reserve because of snprintf */
892
char name_buff[7+16];
898
Initializes object representing time zone described by its offset from UTC.
902
tz_offset_arg - offset from UTC in seconds.
903
Positive for direction to east.
905
Time_zone_offset::Time_zone_offset(long tz_offset_arg):
906
offset(tz_offset_arg)
908
uint32_t hours= abs((int)(offset / SECS_PER_HOUR));
909
uint32_t minutes= abs((int)(offset % SECS_PER_HOUR / SECS_PER_MIN));
910
ulong length= snprintf(name_buff, sizeof(name_buff), "%s%02d:%02d",
911
(offset>=0) ? "+" : "-", hours, minutes);
912
name.set(name_buff, length, &my_charset_utf8_general_ci);
917
Converts local time in time zone described as offset from UTC
918
from DRIZZLE_TIME representation to its time_t representation.
922
t - pointer to DRIZZLE_TIME structure with local time
923
in broken-down representation.
924
in_dst_time_gap - pointer to bool which should be set to true if
925
datetime value passed doesn't really exist
926
(i.e. falls into spring time-gap) and is not
928
It is not really used in this class.
931
Corresponding time_t value or 0 in case of error
934
Time_zone_offset::TIME_to_gmt_sec(const DRIZZLE_TIME *t,
941
Check timestamp range.we have to do this as calling function relies on
942
us to make all validation checks here.
944
if (!validate_timestamp_range(t))
948
Do a temporary shift of the boundary dates to avoid
949
overflow of time_t if the time value is near it's
952
if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && t->day > 4)
955
local_t= sec_since_epoch(t->year, t->month, (t->day - shift),
956
t->hour, t->minute, t->second) -
961
/* Add back the shifted time */
962
local_t+= shift * SECS_PER_DAY;
965
if (local_t >= TIMESTAMP_MIN_VALUE && local_t <= TIMESTAMP_MAX_VALUE)
974
Converts time from UTC seconds since Epoch (time_t) representation
975
to local time zone described as offset from UTC and in broken-down
980
tmp - pointer to DRIZZLE_TIME structure to fill-in
981
t - time_t value to be converted
984
Time_zone_offset::gmt_sec_to_TIME(DRIZZLE_TIME *tmp, time_t t) const
986
sec_to_TIME(tmp, t, offset);
991
Get name of time zone
997
Name of time zone as pointer to String object
1000
Time_zone_offset::get_name() const
1006
static Time_zone_utc tz_UTC;
1007
127
static Time_zone_system tz_SYSTEM;
1008
static Time_zone_offset tz_OFFSET0(0);
1010
Time_zone *my_tz_OFFSET0= &tz_OFFSET0;
1011
Time_zone *my_tz_UTC= &tz_UTC;
1012
129
Time_zone *my_tz_SYSTEM= &tz_SYSTEM;
1014
class Tz_names_entry: public Sql_alloc
1023
Initialize time zone support infrastructure.
1027
session - current thread object
1028
default_tzname - default time zone or 0 if none.
1029
bootstrap - indicates whenever we are in bootstrap mode
1032
This function will init memory structures needed for time zone support,
1033
it will register mandatory SYSTEM time zone in them. It will try to open
1034
mysql.time_zone* tables and load information about default time zone and
1035
information which further will be shared among all time zones loaded.
1036
If system tables with time zone descriptions don't exist it won't fail
1037
(unless default_tzname is time zone from tables). If bootstrap parameter
1038
is true then this routine assumes that we are in bootstrap mode and won't
1039
load time zone descriptions unless someone specifies default time zone
1040
which is supposedly stored in those tables.
1041
It'll also set default time zone if it is specified.
134
* Initialize time zone support infrastructure.
137
* This function will init memory structures needed for time zone support,
138
* it will register mandatory SYSTEM time zone in them. It will try to open
139
* mysql.time_zone* tables and load information about default time zone and
140
* information which further will be shared among all time zones loaded.
141
* If system tables with time zone descriptions don't exist it won't fail
142
* (unless default_tzname is time zone from tables). If bootstrap parameter
143
* is true then this routine assumes that we are in bootstrap mode and won't
144
* load time zone descriptions unless someone specifies default time zone
145
* which is supposedly stored in those tables.
146
* It'll also set default time zone if it is specified.
148
* @param session current thread object
149
* @param default_tzname default time zone or 0 if none.
150
* @param bootstrap indicates whenever we are in bootstrap mode
1048
157
my_tz_init(Session *session, const char *default_tzname)