Drizzled Public API Documentation

time.h

00001 /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 MySQL
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 #pragma once
00022 
00023 #if TIME_WITH_SYS_TIME
00024 # include <sys/time.h>
00025 # include <time.h>
00026 #else
00027 # if HAVE_SYS_TIME_H
00028 #  include <sys/time.h>
00029 # else
00030 #  include <time.h>
00031 # endif
00032 #endif
00033 
00034 #include <drizzled/sql_string.h>
00035 
00036 namespace drizzled
00037 {
00038 
00039 extern uint64_t log_10_int[20];
00040 extern unsigned char days_in_month[];
00041 
00042 /* Time handling defaults */
00043 #define TIMESTAMP_MIN_YEAR (1900 + YY_PART_YEAR - 1)
00044 #define TIMESTAMP_MAX_VALUE INT32_MAX
00045 #define TIMESTAMP_MIN_VALUE 1
00046 
00047 /* two-digit years < this are 20..; >= this are 19.. */
00048 #define YY_PART_YEAR     70
00049 
00050 /* Flags to str_to_datetime */
00051 #define TIME_FUZZY_DATE   1
00052 #define TIME_DATETIME_ONLY  2
00053 
00054 /* Must be same as MODE_NO_ZERO_IN_DATE */
00055 #define TIME_NO_ZERO_IN_DATE    (65536L*2*2*2*2*2*2*2)
00056 
00057 /* Must be same as MODE_NO_ZERO_DATE */
00058 #define TIME_NO_ZERO_DATE (TIME_NO_ZERO_IN_DATE*2)
00059 #define TIME_INVALID_DATES  (TIME_NO_ZERO_DATE*2)
00060 
00061 #define DRIZZLE_TIME_WARN_TRUNCATED    1
00062 #define DRIZZLE_TIME_WARN_OUT_OF_RANGE 2
00063 
00064 /* Limits for the TIME data type */
00065 #define TIME_MAX_HOUR 838
00066 #define TIME_MAX_MINUTE 59
00067 #define TIME_MAX_SECOND 59
00068 #define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + \
00069                         TIME_MAX_SECOND)
00070 
00071 /*
00072   Structure which is used to represent datetime values inside Drizzle.
00073 
00074   We assume that values in this structure are normalized, i.e. year <= 9999,
00075   month <= 12, day <= 31, hour <= 23, hour <= 59, hour <= 59. Many functions
00076   in server such as my_system_gmt_sec() or make_time() family of functions
00077   rely on this (actually now usage of make_*() family relies on a bit weaker
00078   restriction). Also functions that produce type::Time as result ensure this.
00079   There is one exception to this rule though if this structure holds time
00080   value (time_type == DRIZZLE_TIMESTAMP_TIME) days and hour member can hold
00081   bigger values.
00082 */
00083 namespace type {
00084 
00085 enum timestamp_t
00086 {
00087   DRIZZLE_TIMESTAMP_NONE= -2, DRIZZLE_TIMESTAMP_ERROR= -1,
00088   DRIZZLE_TIMESTAMP_DATE= 0, DRIZZLE_TIMESTAMP_DATETIME= 1, DRIZZLE_TIMESTAMP_TIME= 2
00089 };
00090 
00091 enum cut_t
00092 {
00093   VALID= 0,
00094   CUT= 1,
00095   INVALID= 2
00096 };
00097 
00098 /*
00099   datatime_t while being stored in an integer is actually a formatted value.
00100 */
00101 typedef int64_t datetime_t;
00102 typedef int64_t date_t;
00103 
00104 inline bool is_valid(const datetime_t &value)
00105 {
00106   if (value == -1L)
00107     return false;
00108 
00109   return true;
00110 }
00111 
00112 class Time
00113 {
00114 public:
00115   typedef uint32_t usec_t;
00116   typedef int64_t epoch_t;
00117 
00118   Time()
00119   {
00120     reset();
00121   }
00122 
00123   Time(uint32_t year_arg,
00124        uint32_t month_arg,
00125        uint32_t day_arg,
00126        uint32_t hour_arg,
00127        uint32_t minute_arg,
00128        uint32_t second_arg,
00129        usec_t second_part_arg,
00130        timestamp_t type_arg) :
00131     year(year_arg),
00132     month(month_arg),
00133     day(day_arg),
00134     hour(hour_arg),
00135     minute(minute_arg),
00136     second(second_arg),
00137     second_part(second_part_arg),
00138     neg(false),
00139     time_type(type_arg),
00140     _is_local_time(false)
00141   {
00142   }
00143 
00144   Time(uint32_t hour_arg,
00145        uint32_t minute_arg,
00146        uint32_t second_arg,
00147        usec_t second_part_arg,
00148        bool neg_arg) :
00149     year(0),
00150     month(0),
00151     day(0),
00152     hour(hour_arg),
00153     minute(minute_arg),
00154     second(second_arg),
00155     second_part(second_part_arg),
00156     neg(neg_arg),
00157     time_type(DRIZZLE_TIMESTAMP_TIME),
00158     _is_local_time(false)
00159   {
00160   }
00161 
00162   uint32_t year, month, day, hour, minute, second;
00163   usec_t second_part;
00164   bool neg;
00165   timestamp_t time_type;
00166   bool _is_local_time;
00167 
00168   void reset()
00169   {
00170     year= month= day= hour= minute= second= second_part= 0;
00171     neg= false;
00172     time_type= DRIZZLE_TIMESTAMP_DATE;
00173     _is_local_time= false;
00174   }
00175 
00176   timestamp_t type() const
00177   {
00178     return time_type;
00179   }
00180 
00181   void convert(drizzled::String &str, timestamp_t arg= type::DRIZZLE_TIMESTAMP_DATETIME);
00182   void convert(char *str, size_t &to_length, timestamp_t arg= type::DRIZZLE_TIMESTAMP_DATETIME);
00183   void convert(datetime_t &datetime, timestamp_t arg= type::DRIZZLE_TIMESTAMP_DATETIME);
00184   void convert(datetime_t &ret, int64_t nr, uint32_t flags);
00185   void convert(datetime_t &ret, int64_t nr, uint32_t flags, type::cut_t &was_cut);
00186   void convert(type::Time::epoch_t &epoch, long *my_timezone,
00187                bool *in_dst_time_gap, bool skip_timezone= false) const;
00188 
00189   void truncate(const timestamp_t arg);
00190 
00191   bool store(const char *str,uint32_t length, int &warning, type::timestamp_t arg= DRIZZLE_TIMESTAMP_TIME);
00192   type::timestamp_t store(const char *str, uint32_t length, uint32_t flags, type::cut_t &was_cut);
00193   type::timestamp_t store(const char *str, uint32_t length, uint32_t flags);
00194   void store(const type::Time::epoch_t &from, bool use_localtime= false);
00195   void store(const type::Time::epoch_t &from, const usec_t &from_fractional_seconds, bool use_localtime= false);
00196   void store(const struct tm &from);
00197   void store(const struct timeval &from);
00198 
00199 
00200   static const uint32_t FRACTIONAL_DIGITS= 1000000;
00201   static const size_t MAX_STRING_LENGTH= 32;   // +32 to make my_snprintf_{8bit|ucs2} happy
00202 
00203   bool check(bool not_zero_date, uint32_t flags, type::cut_t &was_cut) const;
00204 
00205   inline bool isValidEpoch() const
00206   {
00207     if ((year < TIMESTAMP_MIN_YEAR) or (year == TIMESTAMP_MIN_YEAR && (month < 12 || day < 31)))
00208     {
00209       return false;
00210     }
00211 
00212     return true;
00213   }
00214 };
00215 
00216 }
00217 
00218 long calc_daynr(uint32_t year,uint32_t month,uint32_t day);
00219 uint32_t calc_days_in_year(uint32_t year);
00220 uint32_t year_2000_handling(uint32_t year);
00221 
00222 void init_time(void);
00223 
00224 /*
00225   Available interval types used in any statement.
00226 
00227   'interval_type' must be sorted so that simple intervals comes first,
00228   ie year, quarter, month, week, day, hour, etc. The order based on
00229   interval size is also important and the intervals should be kept in a
00230   large to smaller order. (get_interval_value() depends on this)
00231 
00232   Note: If you change the order of elements in this enum you should fix
00233   order of elements in 'interval_type_to_name' and 'interval_names'
00234   arrays
00235 
00236   See also interval_type_to_name, get_interval_value, interval_names
00237 */
00238 
00239 enum interval_type
00240 {
00241   INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_WEEK, INTERVAL_DAY,
00242   INTERVAL_HOUR, INTERVAL_MINUTE, INTERVAL_SECOND, INTERVAL_MICROSECOND,
00243   INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, INTERVAL_DAY_MINUTE,
00244   INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND,
00245   INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND, INTERVAL_HOUR_MICROSECOND,
00246   INTERVAL_MINUTE_MICROSECOND, INTERVAL_SECOND_MICROSECOND, INTERVAL_LAST
00247 };
00248 
00249 } /* namespace drizzled */
00250