my_time.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. Copyright (c) 2004, 2011, Oracle and/or its affiliates.
  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. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
  13. /*
  14. This is a private header of sql-common library, containing
  15. declarations for my_time.c
  16. */
  17. #ifndef _my_time_h_
  18. #define _my_time_h_
  19. #include "my_global.h"
  20. #include "mysql_time.h"
  21. C_MODE_START
  22. extern ulonglong log_10_int[20];
  23. extern uchar days_in_month[];
  24. #define MY_TIME_T_MAX LONG_MAX
  25. #define MY_TIME_T_MIN LONG_MIN
  26. /* Time handling defaults */
  27. #define TIMESTAMP_MAX_YEAR 2038
  28. #define TIMESTAMP_MIN_YEAR (1900 + YY_PART_YEAR - 1)
  29. #define TIMESTAMP_MAX_VALUE INT_MAX32
  30. #define TIMESTAMP_MIN_VALUE 0
  31. /* two-digit years < this are 20..; >= this are 19.. */
  32. #define YY_PART_YEAR 70
  33. /*
  34. check for valid times only if the range of time_t is greater than
  35. the range of my_time_t
  36. */
  37. #if SIZEOF_TIME_T > 4 || defined(TIME_T_UNSIGNED)
  38. # define IS_TIME_T_VALID_FOR_TIMESTAMP(x) \
  39. ((x) <= TIMESTAMP_MAX_VALUE && \
  40. (x) >= TIMESTAMP_MIN_VALUE)
  41. #else
  42. # define IS_TIME_T_VALID_FOR_TIMESTAMP(x) \
  43. ((x) >= TIMESTAMP_MIN_VALUE)
  44. #endif
  45. /* Flags to str_to_datetime */
  46. /*
  47. TIME_FUZZY_DATES is used for the result will only be used for comparison
  48. purposes. Conversion is as relaxed as possible.
  49. */
  50. #define TIME_FUZZY_DATES 1
  51. #define TIME_DATETIME_ONLY 2
  52. #define TIME_TIME_ONLY 4
  53. #define TIME_NO_ZERO_IN_DATE (1UL << 23) /* == MODE_NO_ZERO_IN_DATE */
  54. #define TIME_NO_ZERO_DATE (1UL << 24) /* == MODE_NO_ZERO_DATE */
  55. #define TIME_INVALID_DATES (1UL << 25) /* == MODE_INVALID_DATES */
  56. #define MYSQL_TIME_WARN_TRUNCATED 1
  57. #define MYSQL_TIME_WARN_OUT_OF_RANGE 2
  58. #define MYSQL_TIME_NOTE_TRUNCATED 16
  59. #define MYSQL_TIME_WARN_WARNINGS (MYSQL_TIME_WARN_TRUNCATED|MYSQL_TIME_WARN_OUT_OF_RANGE)
  60. #define MYSQL_TIME_WARN_NOTES (MYSQL_TIME_NOTE_TRUNCATED)
  61. #define MYSQL_TIME_WARN_HAVE_WARNINGS(x) MY_TEST((x) & MYSQL_TIME_WARN_WARNINGS)
  62. #define MYSQL_TIME_WARN_HAVE_NOTES(x) MY_TEST((x) & MYSQL_TIME_WARN_NOTES)
  63. /* Usefull constants */
  64. #define SECONDS_IN_24H 86400L
  65. /* Limits for the TIME data type */
  66. #define TIME_MAX_HOUR 838
  67. #define TIME_MAX_MINUTE 59
  68. #define TIME_MAX_SECOND 59
  69. #define TIME_MAX_SECOND_PART 999999
  70. #define TIME_SECOND_PART_FACTOR (TIME_MAX_SECOND_PART+1)
  71. #define TIME_SECOND_PART_DIGITS 6
  72. #define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + TIME_MAX_SECOND)
  73. #define TIME_MAX_VALUE_SECONDS (TIME_MAX_HOUR * 3600L + \
  74. TIME_MAX_MINUTE * 60L + TIME_MAX_SECOND)
  75. /*
  76. Structure to return status from
  77. str_to_datetime(), str_to_time().
  78. */
  79. typedef struct st_mysql_time_status
  80. {
  81. int warnings;
  82. uint precision;
  83. } MYSQL_TIME_STATUS;
  84. static inline void my_time_status_init(MYSQL_TIME_STATUS *status)
  85. {
  86. status->warnings= status->precision= 0;
  87. }
  88. my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
  89. ulonglong flags, int *was_cut);
  90. my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
  91. ulonglong flag, MYSQL_TIME_STATUS *status);
  92. my_bool str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
  93. ulonglong flags, MYSQL_TIME_STATUS *status);
  94. longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res,
  95. ulonglong flags, int *was_cut);
  96. static inline
  97. longlong double_to_datetime(double nr, MYSQL_TIME *ltime, uint flags, int *cut)
  98. {
  99. if (nr < 0 || nr > LONGLONG_MAX)
  100. nr= (double)LONGLONG_MAX;
  101. return number_to_datetime((longlong) floor(nr),
  102. (ulong)((nr-floor(nr))*TIME_SECOND_PART_FACTOR),
  103. ltime, flags, cut);
  104. }
  105. int number_to_time(my_bool neg, ulonglong nr, ulong sec_part,
  106. MYSQL_TIME *ltime, int *was_cut);
  107. ulonglong TIME_to_ulonglong_datetime(const MYSQL_TIME *);
  108. ulonglong TIME_to_ulonglong_date(const MYSQL_TIME *);
  109. ulonglong TIME_to_ulonglong_time(const MYSQL_TIME *);
  110. ulonglong TIME_to_ulonglong(const MYSQL_TIME *);
  111. double TIME_to_double(const MYSQL_TIME *my_time);
  112. longlong pack_time(const MYSQL_TIME *my_time);
  113. MYSQL_TIME *unpack_time(longlong packed, MYSQL_TIME *my_time);
  114. int check_time_range(struct st_mysql_time *my_time, uint dec, int *warning);
  115. my_bool check_datetime_range(const MYSQL_TIME *ltime);
  116. long calc_daynr(uint year,uint month,uint day);
  117. uint calc_days_in_year(uint year);
  118. uint year_2000_handling(uint year);
  119. void my_init_time(void);
  120. /*
  121. Function to check sanity of a TIMESTAMP value
  122. DESCRIPTION
  123. Check if a given MYSQL_TIME value fits in TIMESTAMP range.
  124. This function doesn't make precise check, but rather a rough
  125. estimate.
  126. RETURN VALUES
  127. TRUE The value seems sane
  128. FALSE The MYSQL_TIME value is definitely out of range
  129. */
  130. static inline my_bool validate_timestamp_range(const MYSQL_TIME *t)
  131. {
  132. if ((t->year > TIMESTAMP_MAX_YEAR || t->year < TIMESTAMP_MIN_YEAR) ||
  133. (t->year == TIMESTAMP_MAX_YEAR && (t->month > 1 || t->day > 19)) ||
  134. (t->year == TIMESTAMP_MIN_YEAR && (t->month < 12 || t->day < 31)))
  135. return FALSE;
  136. return TRUE;
  137. }
  138. my_time_t
  139. my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, uint *error_code);
  140. void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type);
  141. /*
  142. Required buffer length for my_time_to_str, my_date_to_str,
  143. my_datetime_to_str and TIME_to_string functions. Note, that the
  144. caller is still responsible to check that given TIME structure
  145. has values in valid ranges, otherwise size of the buffer could
  146. be not enough. We also rely on the fact that even wrong values
  147. sent using binary protocol fit in this buffer.
  148. */
  149. #define MAX_DATE_STRING_REP_LENGTH 30
  150. #define AUTO_SEC_PART_DIGITS 31 /* same as NOT_FIXED_DEC */
  151. int my_time_to_str(const MYSQL_TIME *l_time, char *to, uint digits);
  152. int my_date_to_str(const MYSQL_TIME *l_time, char *to);
  153. int my_datetime_to_str(const MYSQL_TIME *l_time, char *to, uint digits);
  154. int my_TIME_to_str(const MYSQL_TIME *l_time, char *to, uint digits);
  155. int my_timeval_to_str(const struct timeval *tm, char *to, uint dec);
  156. static inline longlong sec_part_shift(longlong second_part, uint digits)
  157. {
  158. return second_part / (longlong)log_10_int[TIME_SECOND_PART_DIGITS - digits];
  159. }
  160. static inline longlong sec_part_unshift(longlong second_part, uint digits)
  161. {
  162. return second_part * (longlong)log_10_int[TIME_SECOND_PART_DIGITS - digits];
  163. }
  164. /* Date/time rounding and truncation functions */
  165. static inline long my_time_fraction_remainder(long nr, uint decimals)
  166. {
  167. DBUG_ASSERT(decimals <= TIME_SECOND_PART_DIGITS);
  168. return nr % (long) log_10_int[TIME_SECOND_PART_DIGITS - decimals];
  169. }
  170. static inline void my_time_trunc(MYSQL_TIME *ltime, uint decimals)
  171. {
  172. ltime->second_part-= my_time_fraction_remainder(ltime->second_part, decimals);
  173. }
  174. static inline void my_timeval_trunc(struct timeval *tv, uint decimals)
  175. {
  176. tv->tv_usec-= my_time_fraction_remainder(tv->tv_usec, decimals);
  177. }
  178. #define hrtime_to_my_time(X) ((my_time_t)hrtime_to_time(X))
  179. /*
  180. Available interval types used in any statement.
  181. 'interval_type' must be sorted so that simple intervals comes first,
  182. ie year, quarter, month, week, day, hour, etc. The order based on
  183. interval size is also important and the intervals should be kept in a
  184. large to smaller order. (get_interval_value() depends on this)
  185. Note: If you change the order of elements in this enum you should fix
  186. order of elements in 'interval_type_to_name' and 'interval_names'
  187. arrays
  188. See also interval_type_to_name, get_interval_value, interval_names
  189. */
  190. enum interval_type
  191. {
  192. INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_WEEK, INTERVAL_DAY,
  193. INTERVAL_HOUR, INTERVAL_MINUTE, INTERVAL_SECOND, INTERVAL_MICROSECOND,
  194. INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, INTERVAL_DAY_MINUTE,
  195. INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND,
  196. INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND, INTERVAL_HOUR_MICROSECOND,
  197. INTERVAL_MINUTE_MICROSECOND, INTERVAL_SECOND_MICROSECOND, INTERVAL_LAST
  198. };
  199. C_MODE_END
  200. #endif /* _my_time_h_ */