21
21
/* Functions to handle date and time */
24
#include "drizzled/error.h"
25
#include "drizzled/util/test.h"
26
#include "drizzled/tztime.h"
27
#include "drizzled/session.h"
28
#include "drizzled/time_functions.h"
23
#include <drizzled/server_includes.h>
24
#include <drizzled/error.h>
25
#include <drizzled/util/test.h>
26
#include <drizzled/tztime.h>
27
#include <drizzled/session.h>
33
29
/* Some functions to calculate dates */
34
Name description of interval names used in statements.
36
'interval_type_to_name' is ordered and sorted on interval size and
38
Order of elements in 'interval_type_to_name' should correspond to
39
the order of elements in 'interval_type' enum
41
See also interval_type, interval_names
44
LEX_STRING interval_type_to_name[INTERVAL_LAST] = {
45
{ C_STRING_WITH_LEN("YEAR")},
46
{ C_STRING_WITH_LEN("QUARTER")},
47
{ C_STRING_WITH_LEN("MONTH")},
48
{ C_STRING_WITH_LEN("WEEK")},
49
{ C_STRING_WITH_LEN("DAY")},
50
{ C_STRING_WITH_LEN("HOUR")},
51
{ C_STRING_WITH_LEN("MINUTE")},
52
{ C_STRING_WITH_LEN("SECOND")},
53
{ C_STRING_WITH_LEN("MICROSECOND")},
54
{ C_STRING_WITH_LEN("YEAR_MONTH")},
55
{ C_STRING_WITH_LEN("DAY_HOUR")},
56
{ C_STRING_WITH_LEN("DAY_MINUTE")},
57
{ C_STRING_WITH_LEN("DAY_SECOND")},
58
{ C_STRING_WITH_LEN("HOUR_MINUTE")},
59
{ C_STRING_WITH_LEN("HOUR_SECOND")},
60
{ C_STRING_WITH_LEN("MINUTE_SECOND")},
61
{ C_STRING_WITH_LEN("DAY_MICROSECOND")},
62
{ C_STRING_WITH_LEN("HOUR_MICROSECOND")},
63
{ C_STRING_WITH_LEN("MINUTE_MICROSECOND")},
64
{ C_STRING_WITH_LEN("SECOND_MICROSECOND")}
67
/* Calc weekday from daynr */
68
/* Returns 0 for monday, 1 for tuesday .... */
36
70
int calc_weekday(long daynr,bool sunday_first_day_of_week)
38
72
return ((int) ((daynr + 5L + (sunday_first_day_of_week ? 1L : 0L)) % 7));
76
The bits in week_format has the following meaning:
77
WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week
78
If set Monday is first day of week
79
WEEK_YEAR (1) If not set Week is in range 0-53
81
Week 0 is returned for the the last week of the previous year (for
82
a date at start of january) In this case one can get 53 for the
83
first week of next year. This flag ensures that the week is
84
relevant for the given year. Note that this flag is only
85
releveant if WEEK_JANUARY is not set.
87
If set Week is in range 1-53.
89
In this case one may get week 53 for a date in January (when
90
the week is that last week of previous year) and week 1 for a
93
WEEK_FIRST_WEEKDAY (2) If not set Weeks are numbered according
95
If set The week that contains the first
96
'first-day-of-week' is week 1.
98
ISO 8601:1988 means that if the week containing January 1 has
99
four or more days in the new year, then it is week 1;
100
Otherwise it is the last week of the previous year, and the
42
104
uint32_t calc_week(DRIZZLE_TIME *l_time, uint32_t week_behaviour, uint32_t *year)
189
Convert a timestamp string to a DRIZZLE_TIME value and produce a warning
190
if string was truncated during conversion.
193
See description of str_to_datetime() for more information.
127
196
enum enum_drizzle_timestamp_type
128
str_to_datetime_with_warn(const char *str,
130
DRIZZLE_TIME *l_time,
197
str_to_datetime_with_warn(const char *str, uint32_t length, DRIZZLE_TIME *l_time,
201
Session *session= current_session;
134
202
enum enum_drizzle_timestamp_type ts_type;
135
Session *session= current_session;
137
204
ts_type= str_to_datetime(str, length, l_time,
138
205
(flags | (session->variables.sql_mode &
170
247
to->second= (int) from->tm_sec;
250
void calc_time_from_sec(DRIZZLE_TIME *to, long seconds, long microseconds)
253
// to->neg is not cleared, it may already be set to a useful value
254
to->time_type= DRIZZLE_TIMESTAMP_TIME;
258
to->hour= seconds/3600L;
259
t_seconds= seconds%3600L;
260
to->minute= t_seconds/60L;
261
to->second= t_seconds%60L;
262
to->second_part= microseconds;
265
void make_time(const DRIZZLE_TIME *l_time, String *str)
267
str->alloc(MAX_DATE_STRING_REP_LENGTH);
268
uint32_t length= (uint32_t) my_time_to_str(l_time, str->c_ptr());
270
str->set_charset(&my_charset_bin);
173
274
void make_date(const DRIZZLE_TIME *l_time, String *str)
175
276
str->alloc(MAX_DATE_STRING_REP_LENGTH);
236
334
ER_TRUNCATED_WRONG_VALUE, warn_buff);
337
bool date_add_interval(DRIZZLE_TIME *ltime, interval_type int_type, INTERVAL interval)
343
sign= (interval.neg ? -1 : 1);
346
case INTERVAL_SECOND:
347
case INTERVAL_SECOND_MICROSECOND:
348
case INTERVAL_MICROSECOND:
349
case INTERVAL_MINUTE:
351
case INTERVAL_MINUTE_MICROSECOND:
352
case INTERVAL_MINUTE_SECOND:
353
case INTERVAL_HOUR_MICROSECOND:
354
case INTERVAL_HOUR_SECOND:
355
case INTERVAL_HOUR_MINUTE:
356
case INTERVAL_DAY_MICROSECOND:
357
case INTERVAL_DAY_SECOND:
358
case INTERVAL_DAY_MINUTE:
359
case INTERVAL_DAY_HOUR:
361
int64_t sec, days, daynr, microseconds, extra_sec;
362
ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME; // Return full date
363
microseconds= ltime->second_part + sign*interval.second_part;
364
extra_sec= microseconds/1000000L;
365
microseconds= microseconds%1000000L;
367
sec=((ltime->day-1)*3600*24L+ltime->hour*3600+ltime->minute*60+
369
sign* (int64_t) (interval.day*3600*24L +
370
interval.hour*3600L+interval.minute*60L+
371
interval.second))+ extra_sec;
372
if (microseconds < 0)
374
microseconds+= 1000000L;
377
days= sec/(3600*24L);
384
ltime->second_part= (uint32_t) microseconds;
385
ltime->second= (uint32_t) (sec % 60);
386
ltime->minute= (uint32_t) (sec/60 % 60);
387
ltime->hour= (uint32_t) (sec/3600);
388
daynr= calc_daynr(ltime->year,ltime->month,1) + days;
389
/* Day number from year 0 to 9999-12-31 */
390
if ((uint64_t) daynr > MAX_DAY_NUMBER)
392
get_date_from_daynr((long) daynr, <ime->year, <ime->month,
398
period= (calc_daynr(ltime->year,ltime->month,ltime->day) +
399
sign * (long) interval.day);
400
/* Daynumber from year 0 to 9999-12-31 */
401
if (period > MAX_DAY_NUMBER)
403
get_date_from_daynr((long) period,<ime->year,<ime->month,<ime->day);
406
ltime->year+= sign * (long) interval.year;
407
if (ltime->year >= 10000L)
409
if (ltime->month == 2 && ltime->day == 29 &&
410
calc_days_in_year(ltime->year) != 366)
411
ltime->day=28; // Was leap-year
413
case INTERVAL_YEAR_MONTH:
414
case INTERVAL_QUARTER:
416
period= (ltime->year*12 + sign * (long) interval.year*12 +
417
ltime->month-1 + sign * (long) interval.month);
418
if (period >= 120000L)
420
ltime->year= (uint32_t) (period / 12);
421
ltime->month= (uint32_t) (period % 12L)+1;
422
/* Adjust day if the new month doesn't have enough days */
423
if (ltime->day > days_in_month[ltime->month-1])
425
ltime->day = days_in_month[ltime->month-1];
426
if (ltime->month == 2 && calc_days_in_year(ltime->year) == 366)
427
ltime->day++; // Leap-year
437
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
438
ER_DATETIME_FUNCTION_OVERFLOW,
439
ER(ER_DATETIME_FUNCTION_OVERFLOW),
447
Calculate difference between two datetime values as seconds + microseconds.
451
l_time1 - TIME/DATE/DATETIME value
452
l_time2 - TIME/DATE/DATETIME value
453
l_sign - 1 absolute values are substracted,
454
-1 absolute values are added.
455
seconds_out - Out parameter where difference between
456
l_time1 and l_time2 in seconds is stored.
457
microseconds_out- Out parameter where microsecond part of difference
458
between l_time1 and l_time2 is stored.
461
This function calculates difference between l_time1 and l_time2 absolute
462
values. So one should set l_sign and correct result if he want to take
463
signs into account (i.e. for DRIZZLE_TIME values).
466
Returns sign of difference.
467
1 means negative result
468
0 means positive result
241
473
calc_time_diff(DRIZZLE_TIME *l_time1, DRIZZLE_TIME *l_time2, int l_sign, int64_t *seconds_out,