My Project
sql_time.h
00001 /* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
00015 
00016 #ifndef SQL_TIME_INCLUDED
00017 #define SQL_TIME_INCLUDED
00018 
00019 #include "my_global.h"                          /* ulong */
00020 #include "my_time.h"
00021 #include "mysql_time.h"                         /* timestamp_type */
00022 #include "sql_error.h"                          /* Sql_condition */
00023 #include "structs.h"                            /* INTERVAL */
00024 
00025 typedef enum enum_mysql_timestamp_type timestamp_type;
00026 typedef struct st_date_time_format DATE_TIME_FORMAT;
00027 typedef struct st_known_date_time_format KNOWN_DATE_TIME_FORMAT;
00028 
00029 /* Flags for calc_week() function.  */
00030 #define WEEK_MONDAY_FIRST    1
00031 #define WEEK_YEAR            2
00032 #define WEEK_FIRST_WEEKDAY   4
00033 
00034 ulong convert_period_to_month(ulong period);
00035 ulong convert_month_to_period(ulong month);
00036 void mix_date_and_time(MYSQL_TIME *ldate, const MYSQL_TIME *ltime);
00037 void get_date_from_daynr(long daynr,uint *year, uint *month, uint *day);
00038 my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, my_bool *not_exist);
00039 bool datetime_with_no_zero_in_date_to_timeval(THD *thd, const MYSQL_TIME *t,
00040                                               struct timeval *tm,
00041                                               int *warnings);
00042 bool datetime_to_timeval(THD *thd, const MYSQL_TIME *t,
00043                          struct timeval *tm, int *warnings);
00044 bool str_to_datetime_with_warn(String *str,  MYSQL_TIME *l_time, uint flags);
00045 bool my_decimal_to_datetime_with_warn(const my_decimal *decimal,
00046                                       MYSQL_TIME *ltime, uint flags);
00047 bool my_double_to_datetime_with_warn(double nr, MYSQL_TIME *ltime, uint flags);
00048 bool my_longlong_to_datetime_with_warn(longlong nr,
00049                                        MYSQL_TIME *ltime, uint flags);
00050 bool my_decimal_to_time_with_warn(const my_decimal *decimal,
00051                                   MYSQL_TIME *ltime);
00052 bool my_double_to_time_with_warn(double nr, MYSQL_TIME *ltime);
00053 bool my_longlong_to_time_with_warn(longlong nr, MYSQL_TIME *ltime);
00054 bool str_to_time_with_warn(String *str, MYSQL_TIME *l_time);
00055 void time_to_datetime(THD *thd, const MYSQL_TIME *tm, MYSQL_TIME *dt);
00056 inline void datetime_to_time(MYSQL_TIME *ltime)
00057 {
00058   ltime->year= ltime->month= ltime->day= 0;
00059   ltime->time_type= MYSQL_TIMESTAMP_TIME;
00060 }
00061 inline void datetime_to_date(MYSQL_TIME *ltime)
00062 {
00063   ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
00064   ltime->time_type= MYSQL_TIMESTAMP_DATE;
00065 }
00066 inline void date_to_datetime(MYSQL_TIME *ltime)
00067 {
00068   ltime->time_type= MYSQL_TIMESTAMP_DATETIME;
00069 }
00070 void make_truncated_value_warning(THD *thd,
00071                                   Sql_condition::enum_warning_level level,
00072                                   ErrConvString val,
00073                                   timestamp_type time_type,
00074                                   const char *field_name);
00075 inline void make_truncated_value_warning(ErrConvString val,
00076                                          timestamp_type time_type)
00077 {
00078   make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
00079                                val, time_type, NullS);
00080 }
00081 extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type,
00082                                                const char *format_str,
00083                                                uint format_length);
00084 extern DATE_TIME_FORMAT *date_time_format_copy(THD *thd,
00085                                                DATE_TIME_FORMAT *format);
00086 const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format,
00087                                      timestamp_type type);
00088 void make_date(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time,
00089                String *str);
00090 void make_time(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time,
00091                String *str, uint dec);
00092 void make_datetime(const DATE_TIME_FORMAT *format, const MYSQL_TIME *l_time,
00093                    String *str, uint dec);
00094 bool my_TIME_to_str(const MYSQL_TIME *ltime, String *str, uint dec);
00095 
00096 /* MYSQL_TIME operations */
00097 bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type,
00098                        INTERVAL interval);
00099 bool calc_time_diff(const MYSQL_TIME *l_time1, const MYSQL_TIME *l_time2,
00100                     int l_sign, longlong *seconds_out, long *microseconds_out);
00101 int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b);
00102 void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
00103 void calc_time_from_sec(MYSQL_TIME *to, longlong seconds, long microseconds);
00104 uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year);
00105 
00106 int calc_weekday(long daynr,bool sunday_first_day_of_week);
00107 bool parse_date_time_format(timestamp_type format_type, 
00108                             const char *format, uint format_length,
00109                             DATE_TIME_FORMAT *date_time_format);
00110 /* Character set-aware version of str_to_time() */
00111 bool str_to_time(const CHARSET_INFO *cs, const char *str, uint length,
00112                  MYSQL_TIME *l_time, uint flags, MYSQL_TIME_STATUS *status);
00113 static inline bool
00114 str_to_time(const String *str, MYSQL_TIME *ltime, uint flags,
00115             MYSQL_TIME_STATUS *status)
00116 {
00117   return str_to_time(str->charset(), str->ptr(), str->length(),
00118                      ltime, flags, status);
00119 }
00120 
00121 bool time_add_nanoseconds_with_round(MYSQL_TIME *ltime, uint nanoseconds,  
00122                                      int *warnings);
00123 /* Character set-aware version of str_to_datetime() */
00124 bool str_to_datetime(const CHARSET_INFO *cs,
00125                      const char *str, uint length,
00126                      MYSQL_TIME *l_time, uint flags,
00127                      MYSQL_TIME_STATUS *status);
00128 static inline bool
00129 str_to_datetime(const String *str, MYSQL_TIME *ltime, uint flags,
00130                 MYSQL_TIME_STATUS *status)
00131 {
00132   return str_to_datetime(str->charset(), str->ptr(), str->length(),
00133                          ltime, flags, status);
00134 }
00135 
00136 bool datetime_add_nanoseconds_with_round(MYSQL_TIME *ltime,
00137                                          uint nanoseconds, int *warnings);
00138 
00139 /* convenience wrapper */
00140 inline bool parse_date_time_format(timestamp_type format_type, 
00141                                    DATE_TIME_FORMAT *date_time_format)
00142 {
00143   return parse_date_time_format(format_type,
00144                                 date_time_format->format.str,
00145                                 date_time_format->format.length,
00146                                 date_time_format);
00147 }
00148 
00149 
00150 extern DATE_TIME_FORMAT global_date_format;
00151 extern DATE_TIME_FORMAT global_datetime_format;
00152 extern DATE_TIME_FORMAT global_time_format;
00153 extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
00154 extern LEX_STRING interval_type_to_name[];
00155 
00156 /* Date/time rounding and truncation functions */
00157 inline long my_time_fraction_remainder(long nr, uint decimals)
00158 {
00159   DBUG_ASSERT(decimals <= DATETIME_MAX_DECIMALS);
00160   return nr % (long) log_10_int[DATETIME_MAX_DECIMALS - decimals];
00161 }
00162 inline void my_time_trunc(MYSQL_TIME *ltime, uint decimals)
00163 {
00164   ltime->second_part-= my_time_fraction_remainder(ltime->second_part, decimals);
00165 }
00166 inline void my_datetime_trunc(MYSQL_TIME *ltime, uint decimals)
00167 {
00168   return my_time_trunc(ltime, decimals);
00169 }
00170 inline void my_timeval_trunc(struct timeval *tv, uint decimals)
00171 {
00172   tv->tv_usec-= my_time_fraction_remainder(tv->tv_usec, decimals);
00173 }
00174 bool my_time_round(MYSQL_TIME *ltime, uint decimals);
00175 bool my_datetime_round(MYSQL_TIME *ltime, uint decimals, int *warnings);
00176 bool my_timeval_round(struct timeval *tv, uint decimals);
00177 
00178 
00179 inline ulonglong TIME_to_ulonglong_datetime_round(const MYSQL_TIME *ltime)
00180 {
00181   // Catch simple cases
00182   if (ltime->second_part < 500000)
00183     return TIME_to_ulonglong_datetime(ltime);
00184   if (ltime->second < 59)
00185     return TIME_to_ulonglong_datetime(ltime) + 1;
00186   // Corner case e.g. 'YYYY-MM-DD hh:mm:59.5'. Proceed with slower method.
00187   int warnings= 0;
00188   MYSQL_TIME tmp= *ltime;
00189   my_datetime_round(&tmp, 0, &warnings);
00190   return TIME_to_ulonglong_datetime(&tmp);// + TIME_microseconds_round(ltime);
00191 }
00192 
00193 
00194 inline ulonglong TIME_to_ulonglong_time_round(const MYSQL_TIME *ltime)
00195 {
00196   if (ltime->second_part < 500000)
00197     return TIME_to_ulonglong_time(ltime);
00198   if (ltime->second < 59)
00199     return TIME_to_ulonglong_time(ltime) + 1;
00200   // Corner case e.g. 'hh:mm:59.5'. Proceed with slower method.
00201   MYSQL_TIME tmp= *ltime;
00202   my_time_round(&tmp, 0);
00203   return TIME_to_ulonglong_time(&tmp);
00204 }
00205 
00206 
00207 inline ulonglong TIME_to_ulonglong_round(const MYSQL_TIME *ltime)
00208 {
00209   switch (ltime->time_type)
00210   {
00211   case MYSQL_TIMESTAMP_TIME:
00212     return TIME_to_ulonglong_time_round(ltime);
00213   case MYSQL_TIMESTAMP_DATETIME:
00214     return TIME_to_ulonglong_datetime_round(ltime);
00215   case MYSQL_TIMESTAMP_DATE:
00216     return TIME_to_ulonglong_date(ltime);
00217   default:
00218     DBUG_ASSERT(0);
00219     return 0;
00220   }
00221 }
00222 
00223 
00224 inline double TIME_microseconds(const MYSQL_TIME *ltime)
00225 {
00226   return (double) ltime->second_part / 1000000;
00227 }
00228 
00229 inline double TIME_to_double_datetime(const MYSQL_TIME *ltime)
00230 {
00231   return (double) TIME_to_ulonglong_datetime(ltime) + TIME_microseconds(ltime);
00232 }
00233 
00234 
00235 inline double TIME_to_double_time(const MYSQL_TIME *ltime)
00236 {
00237   return (double) TIME_to_ulonglong_time(ltime) + TIME_microseconds(ltime);
00238 }
00239 
00240 
00241 inline double TIME_to_double(const MYSQL_TIME *ltime)
00242 {
00243   return (double) TIME_to_ulonglong(ltime) + TIME_microseconds(ltime);
00244 }
00245 
00246 
00247 static inline bool
00248 check_fuzzy_date(const MYSQL_TIME *ltime, uint fuzzydate)
00249 {
00250   return !(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day);
00251 }
00252 
00253 static inline bool
00254 non_zero_date(const MYSQL_TIME *ltime)
00255 {
00256   return ltime->year || ltime->month || ltime->day;
00257 }
00258 
00259 static inline bool
00260 non_zero_time(const MYSQL_TIME *ltime)
00261 {
00262   return ltime->hour || ltime->minute || ltime->second || ltime->second_part;
00263 }
00264 
00265 longlong TIME_to_longlong_packed(const MYSQL_TIME *tm,
00266                                  enum enum_field_types type);
00267 void TIME_from_longlong_packed(MYSQL_TIME *ltime,
00268                                enum enum_field_types type,
00269                                longlong packed_value);
00270 my_decimal *my_decimal_from_datetime_packed(my_decimal *dec,
00271                                             enum enum_field_types type,
00272                                             longlong packed_value);
00273 
00274 longlong longlong_from_datetime_packed(enum enum_field_types type,
00275                                        longlong packed_value);
00276 
00277 double double_from_datetime_packed(enum enum_field_types type,
00278                                    longlong packed_value);
00279 
00280 static inline
00281 timestamp_type field_type_to_timestamp_type(enum enum_field_types type)
00282 {
00283   switch (type)
00284   {
00285   case MYSQL_TYPE_TIME: return MYSQL_TIMESTAMP_TIME;
00286   case MYSQL_TYPE_DATE: return MYSQL_TIMESTAMP_DATE;
00287   case MYSQL_TYPE_TIMESTAMP:
00288   case MYSQL_TYPE_DATETIME: return MYSQL_TIMESTAMP_DATETIME;
00289   default: return MYSQL_TIMESTAMP_NONE;
00290   }
00291 }
00292 #endif /* SQL_TIME_INCLUDED */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines