1 /* Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
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, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 /*
24 This is a private header of sql-common library, containing
25 declarations for my_time.c
26 */
27
28 #ifndef _my_time_h_
29 #define _my_time_h_
30 #include "my_global.h"
31 #include "mysql_time.h"
32
33 C_MODE_START
34
35 extern ulonglong log_10_int[20];
36 extern uchar days_in_month[];
37 extern const char my_zero_datetime6[]; /* "0000-00-00 00:00:00.000000" */
38
39 /*
40 Portable time_t replacement.
41 Should be signed and hold seconds for 1902 -- 2038-01-19 range
42 i.e at least a 32bit variable
43
44 Using the system built in time_t is not an option as
45 we rely on the above requirements in the time functions
46 */
47 typedef long my_time_t;
48
49 typedef enum enum_mysql_timestamp_type timestamp_type;
50
51 #define MY_TIME_T_MAX LONG_MAX
52 #define MY_TIME_T_MIN LONG_MIN
53
54 /* Time handling defaults */
55 #define TIMESTAMP_MAX_YEAR 2038
56 #define TIMESTAMP_MIN_YEAR (1900 + YY_PART_YEAR - 1)
57 #define TIMESTAMP_MAX_VALUE INT_MAX32
58 #define TIMESTAMP_MIN_VALUE 1
59
60 /* two-digit years < this are 20..; >= this are 19.. */
61 #define YY_PART_YEAR 70
62
63 /*
64 check for valid times only if the range of time_t is greater than
65 the range of my_time_t
66 */
67 #if SIZEOF_TIME_T > 4
68 # define IS_TIME_T_VALID_FOR_TIMESTAMP(x) \
69 ((x) <= TIMESTAMP_MAX_VALUE && \
70 (x) >= TIMESTAMP_MIN_VALUE)
71 #else
72 # define IS_TIME_T_VALID_FOR_TIMESTAMP(x) \
73 ((x) >= TIMESTAMP_MIN_VALUE)
74 #endif
75
76 /* Flags to str_to_datetime and number_to_datetime */
77 typedef uint my_time_flags_t;
78 static const my_time_flags_t TIME_FUZZY_DATE= 1;
79 static const my_time_flags_t TIME_DATETIME_ONLY= 2;
80 static const my_time_flags_t TIME_NO_NSEC_ROUNDING= 4;
81 static const my_time_flags_t TIME_NO_DATE_FRAC_WARN= 8;
82 static const my_time_flags_t TIME_NO_ZERO_IN_DATE= 16;
83 static const my_time_flags_t TIME_NO_ZERO_DATE= 32;
84 static const my_time_flags_t TIME_INVALID_DATES= 64;
85
86 /* Conversion warnings */
87 #define MYSQL_TIME_WARN_TRUNCATED 1
88 #define MYSQL_TIME_WARN_OUT_OF_RANGE 2
89 #define MYSQL_TIME_WARN_INVALID_TIMESTAMP 4
90 #define MYSQL_TIME_WARN_ZERO_DATE 8
91 #define MYSQL_TIME_NOTE_TRUNCATED 16
92 #define MYSQL_TIME_WARN_ZERO_IN_DATE 32
93
94 /* Usefull constants */
95 #define SECONDS_IN_24H 86400L
96
97 /* Limits for the TIME data type */
98 #define TIME_MAX_HOUR 838
99 #define TIME_MAX_MINUTE 59
100 #define TIME_MAX_SECOND 59
101 #define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + \
102 TIME_MAX_SECOND)
103 #define TIME_MAX_VALUE_SECONDS (TIME_MAX_HOUR * 3600L + \
104 TIME_MAX_MINUTE * 60L + TIME_MAX_SECOND)
105
106 /*
107 Structure to return status from
108 str_to_datetime(), str_to_time(), number_to_datetime(), number_to_time()
109 */
110 typedef struct st_mysql_time_status
111 {
112 int warnings;
113 uint fractional_digits;
114 uint nanoseconds;
115 } MYSQL_TIME_STATUS;
116
my_time_status_init(MYSQL_TIME_STATUS * status)117 static inline void my_time_status_init(MYSQL_TIME_STATUS *status)
118 {
119 status->warnings= status->fractional_digits= status->nanoseconds= 0;
120 }
121
122
123 my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
124 my_time_flags_t flags, int *was_cut);
125 my_bool str_to_datetime(const char *str, size_t length, MYSQL_TIME *l_time,
126 my_time_flags_t flags, MYSQL_TIME_STATUS *status);
127 longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
128 my_time_flags_t flags, int *was_cut);
129 my_bool number_to_time(longlong nr, MYSQL_TIME *ltime, int *warnings);
130 ulonglong TIME_to_ulonglong_datetime(const MYSQL_TIME *);
131 ulonglong TIME_to_ulonglong_date(const MYSQL_TIME *);
132 ulonglong TIME_to_ulonglong_time(const MYSQL_TIME *);
133 ulonglong TIME_to_ulonglong(const MYSQL_TIME *);
134
135 #define MY_PACKED_TIME_GET_INT_PART(x) ((x) >> 24)
136 #define MY_PACKED_TIME_GET_FRAC_PART(x) ((x) % (1LL << 24))
137 #define MY_PACKED_TIME_MAKE(i, f) ((((longlong) (i)) << 24) + (f))
138 #define MY_PACKED_TIME_MAKE_INT(i) ((((longlong) (i)) << 24))
139
140 longlong year_to_longlong_datetime_packed(long year);
141 longlong TIME_to_longlong_datetime_packed(const MYSQL_TIME *);
142 longlong TIME_to_longlong_date_packed(const MYSQL_TIME *);
143 longlong TIME_to_longlong_time_packed(const MYSQL_TIME *);
144 longlong TIME_to_longlong_packed(const MYSQL_TIME *);
145
146 void TIME_from_longlong_datetime_packed(MYSQL_TIME *ltime, longlong nr);
147 void TIME_from_longlong_time_packed(MYSQL_TIME *ltime, longlong nr);
148 void TIME_from_longlong_date_packed(MYSQL_TIME *ltime, longlong nr);
149 void TIME_set_yymmdd(MYSQL_TIME *ltime, uint yymmdd);
150 void TIME_set_hhmmss(MYSQL_TIME *ltime, uint hhmmss);
151
152 void my_datetime_packed_to_binary(longlong nr, uchar *ptr, uint dec);
153 longlong my_datetime_packed_from_binary(const uchar *ptr, uint dec);
154
155 void my_time_packed_to_binary(longlong nr, uchar *ptr, uint dec);
156 longlong my_time_packed_from_binary(const uchar *ptr, uint dec);
157
158 void my_timestamp_to_binary(const struct timeval *tm, uchar *ptr, uint dec);
159 void my_timestamp_from_binary(struct timeval *tm, const uchar *ptr, uint dec);
160
161 my_bool str_to_time(const char *str, size_t length, MYSQL_TIME *l_time,
162 MYSQL_TIME_STATUS *status);
163
164 my_bool check_time_mmssff_range(const MYSQL_TIME *ltime);
165 my_bool check_time_range_quick(const MYSQL_TIME *ltime);
166 my_bool check_datetime_range(const MYSQL_TIME *ltime);
167 void adjust_time_range(struct st_mysql_time *, int *warning);
168
169 long calc_daynr(uint year,uint month,uint day);
170 uint calc_days_in_year(uint year);
171 uint year_2000_handling(uint year);
172
173 void my_init_time(void);
174
175
176 /*
177 Function to check sanity of a TIMESTAMP value
178
179 DESCRIPTION
180 Check if a given MYSQL_TIME value fits in TIMESTAMP range.
181 This function doesn't make precise check, but rather a rough
182 estimate.
183
184 RETURN VALUES
185 TRUE The value seems sane
186 FALSE The MYSQL_TIME value is definitely out of range
187 */
188
validate_timestamp_range(const MYSQL_TIME * t)189 static inline my_bool validate_timestamp_range(const MYSQL_TIME *t)
190 {
191 if ((t->year > TIMESTAMP_MAX_YEAR || t->year < TIMESTAMP_MIN_YEAR) ||
192 (t->year == TIMESTAMP_MAX_YEAR && (t->month > 1 || t->day > 19)) ||
193 (t->year == TIMESTAMP_MIN_YEAR && (t->month < 12 || t->day < 31)))
194 return FALSE;
195
196 return TRUE;
197 }
198
199 my_time_t
200 my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone,
201 my_bool *in_dst_time_gap);
202
203 void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type);
204 void set_max_time(MYSQL_TIME *tm, my_bool neg);
205 void set_max_hhmmss(MYSQL_TIME *tm);
206
207 /*
208 Required buffer length for my_time_to_str, my_date_to_str,
209 my_datetime_to_str and TIME_to_string functions. Note, that the
210 caller is still responsible to check that given TIME structure
211 has values in valid ranges, otherwise size of the buffer could
212 be not enough. We also rely on the fact that even wrong values
213 sent using binary protocol fit in this buffer.
214 */
215 #define MAX_DATE_STRING_REP_LENGTH 30
216
217 int my_time_to_str(const MYSQL_TIME *l_time, char *to, uint dec);
218 int my_date_to_str(const MYSQL_TIME *l_time, char *to);
219 int my_datetime_to_str(const MYSQL_TIME *l_time, char *to, uint dec);
220 int my_TIME_to_str(const MYSQL_TIME *l_time, char *to, uint dec);
221
222 int my_timeval_to_str(const struct timeval *tm, char *to, uint dec);
223
224 /*
225 Available interval types used in any statement.
226
227 'interval_type' must be sorted so that simple intervals comes first,
228 ie year, quarter, month, week, day, hour, etc. The order based on
229 interval size is also important and the intervals should be kept in a
230 large to smaller order. (get_interval_value() depends on this)
231
232 Note: If you change the order of elements in this enum you should fix
233 order of elements in 'interval_type_to_name' and 'interval_names'
234 arrays
235
236 See also interval_type_to_name, get_interval_value, interval_names
237 */
238
239 enum interval_type
240 {
241 INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_WEEK, INTERVAL_DAY,
242 INTERVAL_HOUR, INTERVAL_MINUTE, INTERVAL_SECOND, INTERVAL_MICROSECOND,
243 INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, INTERVAL_DAY_MINUTE,
244 INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND,
245 INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND, INTERVAL_HOUR_MICROSECOND,
246 INTERVAL_MINUTE_MICROSECOND, INTERVAL_SECOND_MICROSECOND, INTERVAL_LAST
247 };
248
249 C_MODE_END
250
251 #endif /* _my_time_h_ */
252