~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/functions/time/date_format.cc

MergedĀ fromĀ Lee.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include <drizzled/functions/time/date_format.h>
23
23
#include <drizzled/session.h>
24
24
 
 
25
/**
 
26
  Create a formated date/time value in a string.
 
27
*/
 
28
 
 
29
static bool make_date_time(DATE_TIME_FORMAT *format, DRIZZLE_TIME *l_time,
 
30
                    enum enum_drizzle_timestamp_type type, String *str)
 
31
{
 
32
  char intbuff[15];
 
33
  uint32_t hours_i;
 
34
  uint32_t weekday;
 
35
  ulong length;
 
36
  const char *ptr, *end;
 
37
  Session *session= current_session;
 
38
  MY_LOCALE *locale= session->variables.lc_time_names;
 
39
 
 
40
  str->length(0);
 
41
 
 
42
  if (l_time->neg)
 
43
    str->append('-');
 
44
  
 
45
  end= (ptr= format->format.str) + format->format.length;
 
46
  for (; ptr != end ; ptr++)
 
47
  {
 
48
    if (*ptr != '%' || ptr+1 == end)
 
49
      str->append(*ptr);
 
50
    else
 
51
    {
 
52
      switch (*++ptr) {
 
53
      case 'M':
 
54
        if (!l_time->month)
 
55
          return 1;
 
56
        str->append(locale->month_names->type_names[l_time->month-1],
 
57
                    strlen(locale->month_names->type_names[l_time->month-1]),
 
58
                    system_charset_info);
 
59
        break;
 
60
      case 'b':
 
61
        if (!l_time->month)
 
62
          return 1;
 
63
        str->append(locale->ab_month_names->type_names[l_time->month-1],
 
64
                    strlen(locale->ab_month_names->type_names[l_time->month-1]),
 
65
                    system_charset_info);
 
66
        break;
 
67
      case 'W':
 
68
        if (type == DRIZZLE_TIMESTAMP_TIME)
 
69
          return 1;
 
70
        weekday= calc_weekday(calc_daynr(l_time->year,l_time->month,
 
71
                              l_time->day),0);
 
72
        str->append(locale->day_names->type_names[weekday],
 
73
                    strlen(locale->day_names->type_names[weekday]),
 
74
                    system_charset_info);
 
75
        break;
 
76
      case 'a':
 
77
        if (type == DRIZZLE_TIMESTAMP_TIME)
 
78
          return 1;
 
79
        weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
 
80
                             l_time->day),0);
 
81
        str->append(locale->ab_day_names->type_names[weekday],
 
82
                    strlen(locale->ab_day_names->type_names[weekday]),
 
83
                    system_charset_info);
 
84
        break;
 
85
      case 'D':
 
86
        if (type == DRIZZLE_TIMESTAMP_TIME)
 
87
          return 1;
 
88
        length= int10_to_str(l_time->day, intbuff, 10) - intbuff;
 
89
        str->append_with_prefill(intbuff, length, 1, '0');
 
90
        if (l_time->day >= 10 &&  l_time->day <= 19)
 
91
          str->append(STRING_WITH_LEN("th"));
 
92
        else
 
93
        {
 
94
          switch (l_time->day %10) {
 
95
          case 1:
 
96
            str->append(STRING_WITH_LEN("st"));
 
97
            break;
 
98
          case 2:
 
99
            str->append(STRING_WITH_LEN("nd"));
 
100
            break;
 
101
          case 3:
 
102
            str->append(STRING_WITH_LEN("rd"));
 
103
            break;
 
104
          default:
 
105
            str->append(STRING_WITH_LEN("th"));
 
106
            break;
 
107
          }
 
108
        }
 
109
        break;
 
110
      case 'Y':
 
111
        length= int10_to_str(l_time->year, intbuff, 10) - intbuff;
 
112
        str->append_with_prefill(intbuff, length, 4, '0');
 
113
        break;
 
114
      case 'y':
 
115
        length= int10_to_str(l_time->year%100, intbuff, 10) - intbuff;
 
116
        str->append_with_prefill(intbuff, length, 2, '0');
 
117
        break;
 
118
      case 'm':
 
119
        length= int10_to_str(l_time->month, intbuff, 10) - intbuff;
 
120
        str->append_with_prefill(intbuff, length, 2, '0');
 
121
        break;
 
122
      case 'c':
 
123
        length= int10_to_str(l_time->month, intbuff, 10) - intbuff;
 
124
        str->append_with_prefill(intbuff, length, 1, '0');
 
125
        break;
 
126
      case 'd':
 
127
        length= int10_to_str(l_time->day, intbuff, 10) - intbuff;
 
128
        str->append_with_prefill(intbuff, length, 2, '0');
 
129
        break;
 
130
      case 'e':
 
131
        length= int10_to_str(l_time->day, intbuff, 10) - intbuff;
 
132
        str->append_with_prefill(intbuff, length, 1, '0');
 
133
        break;
 
134
      case 'f':
 
135
        length= int10_to_str(l_time->second_part, intbuff, 10) - intbuff;
 
136
        str->append_with_prefill(intbuff, length, 6, '0');
 
137
        break;
 
138
      case 'H':
 
139
        length= int10_to_str(l_time->hour, intbuff, 10) - intbuff;
 
140
        str->append_with_prefill(intbuff, length, 2, '0');
 
141
        break;
 
142
      case 'h':
 
143
      case 'I':
 
144
        hours_i= (l_time->hour%24 + 11)%12+1;
 
145
        length= int10_to_str(hours_i, intbuff, 10) - intbuff;
 
146
        str->append_with_prefill(intbuff, length, 2, '0');
 
147
        break;
 
148
      case 'i':                                 /* minutes */
 
149
        length= int10_to_str(l_time->minute, intbuff, 10) - intbuff;
 
150
        str->append_with_prefill(intbuff, length, 2, '0');
 
151
        break;
 
152
      case 'j':
 
153
        if (type == DRIZZLE_TIMESTAMP_TIME)
 
154
          return 1;
 
155
        length= int10_to_str(calc_daynr(l_time->year,l_time->month,
 
156
                                        l_time->day) - 
 
157
                     calc_daynr(l_time->year,1,1) + 1, intbuff, 10) - intbuff;
 
158
        str->append_with_prefill(intbuff, length, 3, '0');
 
159
        break;
 
160
      case 'k':
 
161
        length= int10_to_str(l_time->hour, intbuff, 10) - intbuff;
 
162
        str->append_with_prefill(intbuff, length, 1, '0');
 
163
        break;
 
164
      case 'l':
 
165
        hours_i= (l_time->hour%24 + 11)%12+1;
 
166
        length= int10_to_str(hours_i, intbuff, 10) - intbuff;
 
167
        str->append_with_prefill(intbuff, length, 1, '0');
 
168
        break;
 
169
      case 'p':
 
170
        hours_i= l_time->hour%24;
 
171
        str->append(hours_i < 12 ? "AM" : "PM",2);
 
172
        break;
 
173
      case 'r':
 
174
        length= sprintf(intbuff, 
 
175
                    ((l_time->hour % 24) < 12) ?
 
176
                    "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM",
 
177
                    (l_time->hour+11)%12+1,
 
178
                    l_time->minute,
 
179
                    l_time->second);
 
180
        str->append(intbuff, length);
 
181
        break;
 
182
      case 'S':
 
183
      case 's':
 
184
        length= int10_to_str(l_time->second, intbuff, 10) - intbuff;
 
185
        str->append_with_prefill(intbuff, length, 2, '0');
 
186
        break;
 
187
      case 'T':
 
188
        length= sprintf(intbuff, 
 
189
                    "%02d:%02d:%02d", 
 
190
                    l_time->hour, 
 
191
                    l_time->minute,
 
192
                    l_time->second);
 
193
        str->append(intbuff, length);
 
194
        break;
 
195
      case 'U':
 
196
      case 'u':
 
197
      {
 
198
        uint32_t year;
 
199
        if (type == DRIZZLE_TIMESTAMP_TIME)
 
200
          return 1;
 
201
        length= int10_to_str(calc_week(l_time,
 
202
                                       (*ptr) == 'U' ?
 
203
                                       WEEK_FIRST_WEEKDAY : WEEK_MONDAY_FIRST,
 
204
                                       &year),
 
205
                             intbuff, 10) - intbuff;
 
206
        str->append_with_prefill(intbuff, length, 2, '0');
 
207
      }
 
208
      break;
 
209
      case 'v':
 
210
      case 'V':
 
211
      {
 
212
        uint32_t year;
 
213
        if (type == DRIZZLE_TIMESTAMP_TIME)
 
214
          return 1;
 
215
        length= int10_to_str(calc_week(l_time,
 
216
                                       ((*ptr) == 'V' ?
 
217
                                        (WEEK_YEAR | WEEK_FIRST_WEEKDAY) :
 
218
                                        (WEEK_YEAR | WEEK_MONDAY_FIRST)),
 
219
                                       &year),
 
220
                             intbuff, 10) - intbuff;
 
221
        str->append_with_prefill(intbuff, length, 2, '0');
 
222
      }
 
223
      break;
 
224
      case 'x':
 
225
      case 'X':
 
226
      {
 
227
        uint32_t year;
 
228
        if (type == DRIZZLE_TIMESTAMP_TIME)
 
229
          return 1;
 
230
        (void) calc_week(l_time,
 
231
                         ((*ptr) == 'X' ?
 
232
                          WEEK_YEAR | WEEK_FIRST_WEEKDAY :
 
233
                          WEEK_YEAR | WEEK_MONDAY_FIRST),
 
234
                         &year);
 
235
        length= int10_to_str(year, intbuff, 10) - intbuff;
 
236
        str->append_with_prefill(intbuff, length, 4, '0');
 
237
      }
 
238
      break;
 
239
      case 'w':
 
240
        if (type == DRIZZLE_TIMESTAMP_TIME)
 
241
          return 1;
 
242
        weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
 
243
                                        l_time->day),1);
 
244
        length= int10_to_str(weekday, intbuff, 10) - intbuff;
 
245
        str->append_with_prefill(intbuff, length, 1, '0');
 
246
        break;
 
247
 
 
248
      default:
 
249
        str->append(*ptr);
 
250
        break;
 
251
      }
 
252
    }
 
253
  }
 
254
  return 0;
 
255
}
 
256
 
25
257
void Item_func_date_format::fix_length_and_dec()
26
258
{
27
259
  Session* session= current_session;