151 lines
5.6 KiB
C
151 lines
5.6 KiB
C
#ifndef TIME_ZONE_COMMON_H
|
|
#define TIME_ZONE_COMMON_H
|
|
/* Copyright (c) 2004, 2024, Oracle and/or its affiliates.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License, version 2.0,
|
|
as published by the Free Software Foundation.
|
|
|
|
This program is designed to work with certain software (including
|
|
but not limited to OpenSSL) that is licensed under separate terms,
|
|
as designated in a particular file or component or in included license
|
|
documentation. The authors of MySQL hereby grant you an additional
|
|
permission to link the program and your derivative works with the
|
|
separately licensed software that they have either included with
|
|
the program or referenced in the documentation.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License, version 2.0, for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
|
|
#include "my_alloc.h" // MEM_ROOT
|
|
#include "my_time_t.h" // my_time_t
|
|
/**
|
|
@file
|
|
Contains common functionality shared between mysqld and
|
|
mysql_tz_info_to_sql.
|
|
*/
|
|
|
|
/*
|
|
Now we don't use abbreviations in server but we will do this in future.
|
|
*/
|
|
#if !defined(NDEBUG)
|
|
/* Let use abbreviations for debug purposes */
|
|
#undef ABBR_ARE_USED
|
|
#define ABBR_ARE_USED
|
|
#endif /* !defined(NDEBUG) */
|
|
|
|
/* Structure describing local time type (e.g. Moscow summer time (MSD)) */
|
|
typedef struct ttinfo {
|
|
long tt_gmtoff; // Offset from UTC in seconds
|
|
unsigned tt_isdst; // Is daylight saving time or not. Used to set tm_isdst
|
|
#ifdef ABBR_ARE_USED
|
|
unsigned tt_abbrind; // Index of start of abbreviation for this time type.
|
|
#endif
|
|
/*
|
|
We don't use tt_ttisstd and tt_ttisgmt members of original elsie-code
|
|
struct since we don't support POSIX-style TZ descriptions in variables.
|
|
*/
|
|
} TRAN_TYPE_INFO;
|
|
|
|
/* Structure describing leap-second corrections. */
|
|
typedef struct lsinfo {
|
|
my_time_t ls_trans; // Transition time
|
|
long ls_corr; // Correction to apply
|
|
} LS_INFO;
|
|
|
|
/*
|
|
Structure with information describing ranges of my_time_t shifted to local
|
|
time (my_time_t + offset). Used for local MYSQL_TIME -> my_time_t conversion.
|
|
See comments for TIME_to_gmt_sec() for more info.
|
|
*/
|
|
typedef struct revtinfo {
|
|
long rt_offset; // Offset of local time from UTC in seconds
|
|
unsigned rt_type; // Type of period 0 - Normal period. 1 - Spring time-gap
|
|
} REVT_INFO;
|
|
|
|
#ifdef TZNAME_MAX
|
|
#define MY_TZNAME_MAX TZNAME_MAX
|
|
#endif
|
|
#ifndef TZNAME_MAX
|
|
#define MY_TZNAME_MAX 255
|
|
#endif
|
|
|
|
/*
|
|
Structure which fully describes time zone which is
|
|
described in our db or in zoneinfo files.
|
|
*/
|
|
struct TIME_ZONE_INFO {
|
|
unsigned leapcnt; // Number of leap-second corrections
|
|
unsigned timecnt; // Number of transitions between time types
|
|
unsigned typecnt; // Number of local time types
|
|
size_t charcnt; // Number of characters used for abbreviations
|
|
unsigned
|
|
revcnt; // Number of transition descr. for TIME->my_time_t conversion
|
|
/* The following are dynamical arrays are allocated in MEM_ROOT */
|
|
my_time_t *ats; // Times of transitions between time types
|
|
uchar *types; // Local time types for transitions
|
|
TRAN_TYPE_INFO *ttis; // Local time types descriptions
|
|
#ifdef ABBR_ARE_USED
|
|
/* Storage for local time types abbreviations. They are stored as ASCIIZ */
|
|
char *chars;
|
|
#endif
|
|
/*
|
|
Leap seconds corrections descriptions, this array is shared by
|
|
all time zones who use leap seconds.
|
|
*/
|
|
LS_INFO *lsis;
|
|
/*
|
|
Starting points and descriptions of shifted my_time_t (my_time_t + offset)
|
|
ranges on which shifted my_time_t -> my_time_t mapping is linear or
|
|
undefined. Used for tm -> my_time_t conversion.
|
|
*/
|
|
my_time_t *revts;
|
|
REVT_INFO *revtis;
|
|
/*
|
|
Time type which is used for times smaller than first transition or if
|
|
there are no transitions at all.
|
|
*/
|
|
TRAN_TYPE_INFO *fallback_tti;
|
|
};
|
|
|
|
/*
|
|
Finish preparation of time zone description for use in TIME_to_gmt_sec()
|
|
and gmt_sec_to_TIME() functions.
|
|
|
|
SYNOPSIS
|
|
prepare_tz_info()
|
|
sp - pointer to time zone description
|
|
storage - pointer to MEM_ROOT where arrays for map allocated
|
|
|
|
DESCRIPTION
|
|
First task of this function is to find fallback time type which will
|
|
be used if there are no transitions or we have moment in time before
|
|
any transitions.
|
|
Second task is to build "shifted my_time_t" -> my_time_t map used in
|
|
MYSQL_TIME -> my_time_t conversion.
|
|
Note: See description of TIME_to_gmt_sec() function first.
|
|
In order to perform MYSQL_TIME -> my_time_t conversion we need to build
|
|
table which defines "shifted by tz offset and leap seconds my_time_t" ->
|
|
my_time_t function which is almost the same (except ranges of ambiguity)
|
|
as reverse function to piecewise linear function used for my_time_t ->
|
|
"shifted my_time_t" conversion and which is also specified as table in
|
|
zoneinfo file or in our db (It is specified as start of time type ranges
|
|
and time type offsets). So basic idea is very simple - let us iterate
|
|
through my_time_t space from one point of discontinuity of my_time_t ->
|
|
"shifted my_time_t" function to another and build our approximation of
|
|
reverse function. (Actually we iterate through ranges on which
|
|
my_time_t -> "shifted my_time_t" is linear function).
|
|
|
|
RETURN VALUES
|
|
0 Ok
|
|
1 Error
|
|
*/
|
|
bool prepare_tz_info(TIME_ZONE_INFO *sp, MEM_ROOT *storage);
|
|
|
|
#endif // TIME_ZONE_COMMON_H
|