1 // ANNA - Anna is Not 'N' Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // https://bitbucket.org/testillano/anna
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
37 #ifndef anna_dbms_Date_hpp
38 #define anna_dbms_Date_hpp
42 #include <anna/config/defines.hpp>
43 #include <anna/core/RuntimeException.hpp>
45 #include <anna/dbms/Data.hpp>
52 Tipo de datos que permite trabajar con el tipo de dato 'Date' de un gestor de base de
55 Dependiendo el gestor de base de datos usado el tipo \em date puede contener informacion que incluya
56 la hora del día, en Oracle (tm) la incluye, mientras que en mysql, por ejemplo, no la incluye.
58 Internamente trabaja con una estructura de tipo 'tm' que habitualmente tendrá los campos:
61 int tm_sec; // Seconds. [0-60] (1 leap second)
62 int tm_min; // Minutes. [0-59]
63 int tm_hour; // Hours. [0-23]
64 int tm_mday; // Day. [1-31]
65 int tm_mon; // Month. [0-11]
66 int tm_year; // Year - 1900.
67 int tm_wday; // Day of week. [0-6]
68 int tm_yday; // Days in year.[0-365]
69 int tm_isdst; // DST. [-1/0/1]
73 class Date : public Data {
76 * Espacio maximo reservado para representar lo datos de una fecha sobre una cadena.
78 static const int MaxDateSize = 48;
82 \param isNulleable Indica si el dato puede tomar valores nulos.
83 \param format Formato usado para interpretar los datos de esta fecha, en los metodos Date::getCStringValue y
84 Date::setValue (const char*) y Date::setValue (const std::string&). Sigue la especificacion:
87 %a Replaced by the localeâs abbreviated weekday name. [ tm_wday]
89 %A Replaced by the localeâs full weekday name. [ tm_wday]
91 %b Replaced by the localeâs abbreviated month name. [ tm_mon]
93 %B Replaced by the localeâs full month name. [ tm_mon]
95 %c Replaced by the localeâs appropriate date and time representation. (See the Base Definitions volume of
96 IEEE Std 1003.1-2001, <time.h>.)
98 %C Replaced by the year divided by 100 and truncated to an integer, as a decimal number [00,99]. [ tm_year]
100 %d Replaced by the day of the month as a decimal number [01,31]. [ tm_mday]
102 %D Equivalent to %m / %d / %y . [ tm_mon, tm_mday, tm_year]
104 %e Replaced by the day of the month as a decimal number [1,31]; a single digit is preceded by a space. [
107 %F Equivalent to %Y - %m - %d (the ISO 8601:2000 standard date format). [ tm_year, tm_mon, tm_mday]
109 %g Replaced by the last 2 digits of the week-based year (see below) as a decimal number [00,99]. [ tm_year,
112 %G Replaced by the week-based year (see below) as a decimal number (for example, 1977). [ tm_year, tm_wday,
115 %h Equivalent to %b . [ tm_mon]
117 %H Replaced by the hour (24-hour clock) as a decimal number [00,23]. [ tm_hour]
119 %I Replaced by the hour (12-hour clock) as a decimal number [01,12]. [ tm_hour]
121 %j Replaced by the day of the year as a decimal number [001,366]. [ tm_yday]
123 %m Replaced by the month as a decimal number [01,12]. [ tm_mon]
125 %M Replaced by the minute as a decimal number [00,59]. [ tm_min]
127 %n Replaced by a <newline>.
129 %p Replaced by the localeâs equivalent of either a.m. or p.m. [ tm_hour]
131 %r Replaced by the time in a.m. and p.m. notation; in the POSIX locale this shall be equivalent to %I : %M
132 : %S %p . [ tm_hour, tm_min, tm_sec]
134 %R Replaced by the time in 24-hour notation ( %H : %M ). [ tm_hour, tm_min]
136 %S Replaced by the second as a decimal number [00,60]. [ tm_sec]
138 %t Replaced by a <tab>.
140 %T Replaced by the time ( %H : %M : %S ). [ tm_hour, tm_min, tm_sec]
142 %u Replaced by the weekday as a decimal number [1,7], with 1 representing Monday. [ tm_wday]
144 %U Replaced by the week number of the year as a decimal number [00,53]. The first Sunday of January is the
145 first day of week 1; days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
147 %V Replaced by the week number of the year (Monday as the first day of the week) as a decimal number [01,53].
148 If the week containing 1 January has four or more days in the new year, then it is considered week 1. Oth-
149 erwise, it is the last week of the previous year, and the next week is week 1. Both January 4th and the
150 first Thursday of January are always in week 1. [ tm_year, tm_wday, tm_yday]
152 %w Replaced by the weekday as a decimal number [0,6], with 0 representing Sunday. [ tm_wday]
154 %W Replaced by the week number of the year as a decimal number [00,53]. The first Monday of January is the
155 first day of week 1; days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
157 %x Replaced by the localeâs appropriate date representation. (See the Base Definitions volume of
158 IEEE Std 1003.1-2001, <time.h>.)
160 %X Replaced by the localeâs appropriate time representation. (See the Base Definitions volume of
161 IEEE Std 1003.1-2001, <time.h>.)
163 %y Replaced by the last two digits of the year as a decimal number [00,99]. [ tm_year]
165 %Y Replaced by the year as a decimal number (for example, 1997). [ tm_year]
167 %z Replaced by the offset from UTC in the ISO 8601:2000 standard format ( +hhmm or -hhmm ), or by no charac-
168 ters if no timezone is determinable. For example, "-0430" means 4 hours 30 minutes behind UTC (west of
169 Greenwich). If tm_isdst is zero, the standard time offset is used. If tm_isdst is greater than zero, the
170 daylight savings time offset is used. If tm_isdst is negative, no characters are returned. [ tm_isdst]
172 %Z Replaced by the timezone name or abbreviation, or by no bytes if no timezone information exists. [
178 Para obtener más informacion sobre la espeficacion de formato \em man \em strftime (p.e.).
180 explicit Date(const bool isNulleable = false, const char* format = NULL) ;
184 \param other Instancia de la que copiar.
186 Date(const Date& other);
194 Devuelve el contenido de esta fecha.
195 \return El contenido de esta fecha.
196 \warning Si el metodo Data::isNull devolvio \em true el contenido de la estructura no esta definido.
198 const tm& getValue() const throw() { return a_value; }
201 Devuelve el contenido de esta fecha.
202 \return El contenido de esta fecha.
203 \warning Si el metodo Data::isNull devolvio \em true el contenido de la estructura no esta definido.
205 tm& getValue() throw() { return a_value; }
208 * Interpreta el contenido de la fecha y lo transfiere al buffer.
209 * \return El buffer que contiene esta fecha interpretada con el formato indicado en el contructor.
210 * \warning El resultado sera NULL en caso de no poder interpretar correctamente la fecha.
212 virtual const char* getCStringValue() const throw();
215 * Interpreta el contenido de esta fecha como el numero de segundos transcurridos desde el 1 de Enero de 1970.
216 * Si el contenido de la columna sociada es nulo este metodo devolvera 0. Si la conversion a segundos no puede
217 * ser realizada devolvera -1.
218 * \return Interpreta el contenido de esta fecha como el numero de segundos transcurridos desde el 1 de Enero de 1970.
219 * Si el contenido de la columna sociada es nulo este metodo devolvera 0. Si la conversion a
220 * segundos no puede ser realizada devolvera -1.
222 Second getSecondValue() const throw() { return Second((Data::isNull() == true) ? 0 : mktime(&const_cast <Date*>(this)->a_value)); }
225 * Devuelve el formato indicado en el constructor de la clase.
226 * \return El formato indicado en el constructor de la clase.
228 const char* getFormat() const throw() { return a_format; }
231 * Devuelve el año contenido por esta fecha.
232 * \return El año contenido por esta fecha.
234 int getYear() const throw() { return a_value.tm_year + 1900; }
237 * Devuelve el mes contenido por esta fecha.
238 * \return El mes contenido por esta fecha.
240 int getMonth() const throw() { return a_value.tm_mon + 1; }
243 * Devuelve el dia del mes contenido por esta fecha.
244 * \return El dia del mes contenido por esta fecha.
246 int getDay() const throw() { return a_value.tm_mday; }
249 * Devuelve la hora del dia contenida en la fecha.
250 * \return La hora del dia contenida en la fecha.
251 * \warning Verifique que el tipo 'Date' de su RDBMS es capaz de contener horas, minutos y segundos.
253 int getHour() const throw() { return a_value.tm_hour; }
256 * Devuelve el minuto de la hora contenida en la fecha.
257 * \return El minuto de la hora contenida en la fecha.
258 * \warning Verifique que el tipo 'Date' de su RDBMS es capaz de contener horas, minutos y segundos.
260 int getMinute() const throw() { return a_value.tm_min; }
263 * Devuelve el segundo de la hora contenida en la fecha.
264 * \return El segundo de la hora contenida en la fecha.
265 * \warning Verifique que el tipo 'Date' de su RDBMS es capaz de contener horas, minutos y segundos.
267 int getSecond() const throw() { return a_value.tm_sec; }
270 * Establece el año de esta fecha
271 * \param year Año de la fecha. Debe ser mayor de 1900.
273 void setYear(const int year) throw(RuntimeException) { set("Year", a_value.tm_year, year - 1900, 0, -1); }
276 * Establece mes de esta fecha.
277 * \param month Mes de la fecha. Debe estar comprendido entre 1 y 12.
279 void setMonth(const int month) throw(RuntimeException) { set("Month", a_value.tm_mon, month - 1, 0, 11); }
282 * Establece el dia del mes de esta fecha.
283 * \param day Dia del mes. Debe estar comprendido entre 1 y 31.
285 void setDay(const int day) throw(RuntimeException) { set("Day", a_value.tm_mday, day, 1, 31); }
288 * Establece la hora de esta fecha.
289 * \param hour Hora del dia. Debe estar comprendida entre 0 y 23.
290 * \warning Verifique que el tipo 'Date' de su RDBMS es capaz de contener horas, minutos y segundos.
292 void setHour(const int hour) throw(RuntimeException) { set("Hour", a_value.tm_hour, hour, 0, 23); }
295 * Establece el minuto de esta fecha.
296 * \param minute Minuto de la hora del dia. Debe estar comprendida entre 0 y 59.
297 * \warning Verifique que el tipo 'Date' de su RDBMS es capaz de contener horas, minutos y segundos.
299 void setMinute(const int minute) throw(RuntimeException) { set("Minute", a_value.tm_min, minute, 0, 59); }
302 * Establece el segundo de esta fecha.
303 * \param second Segungo de la hora del dia. Debe estar comprendida entre 0 y 60.
304 * \warning Verifique que el tipo 'Date' de su RDBMS es capaz de contener horas, minutos y segundos.
306 void setSecond(const int second) throw(RuntimeException) { set("Second", a_value.tm_sec, second, 0, 60); }
309 Interpreta la cadena recibida segun el formato indicado en el constructor y la asigna a esta instancia, pero requiere que al
310 invocar al constructor de esta fecha se indique el formato usado para traducir.
311 \param str Cadena de la que copiar.
313 void setValue(const char* str) throw(RuntimeException);
316 Interpreta la cadena recibida segun el formato indicado en el constructor y la asigna a esta instancia, pero requiere que al
317 invocar al constructor de esta fecha se indique el formato usado para traducir.
318 \param str Cadena de la que copiar.
320 void setValue(const std::string& str) throw(RuntimeException) { setValue(str.c_str()); }
323 * Establece esta fecha con los segundos transcurridos desde el 1/1/1970.
324 * \param second Numeros de segundos transcurridos desde el 1 de Enero de 1970.
325 * \see anna::functions::second
327 void setValue(const Second &second) throw(RuntimeException);
331 \param date Fecha de la que copiar.
332 \return La instancia de esta fecha.
333 \warning Solo copia el contenido de la fecha recibida, no cambia el formato de interpretacion de la fecha origen.
335 Date& operator = (const Date& date) throw(RuntimeException);
338 Devuelve una cadena con la informacion referente a esta instancia.
339 \return Una cadena con la informacion referente a esta instancia.
341 virtual std::string asString() const throw();
346 char a_buffer [MaxDateSize + 1];
349 * Constructor invocado desde el constructor de TimeStamp.
350 \param type Sera Data::Type::TimeStamp.
351 \param isNulleable Indica si el dato puede tomar valores nulos.
352 \param format Formato usado para representar los datos de esta fecha.
354 explicit Date(const Type::_v type, const bool isNulleable, const char* format);
357 void set(const char* what, int& variable, const int value, const int min, const int max) throw(RuntimeException);
358 void do_clear() throw() { anna_memset(&a_value, 0, sizeof(a_value)); }