PostgreSQL Source Code: src/interfaces/ecpg/pgtypeslib/datetime.c Source File (original) (raw)
1
2
4
6#include <ctype.h>
7#include <limits.h>
8
13
16{
18
20
21 return result;
22}
23
24void
26{
28}
29
32{
34
35 dDate = 0;
36
38 {
39
41 }
42
43 return dDate;
44}
45
48{
51 struct tm tt,
52 *tm = &tt;
53 int dtype;
54 int nf;
58 char *realptr;
59 char **ptr = (endptr != NULL) ? endptr : &realptr;
60
61 bool EuroDates = false;
62
63 errno = 0;
65 {
67 return INT_MIN;
68 }
69
70 if (ParseDateTime(str, lowstr, field, ftype, &nf, ptr) != 0 ||
71 DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, EuroDates) != 0)
72 {
74 return INT_MIN;
75 }
76
77 switch (dtype)
78 {
80 break;
81
84 {
86 return INT_MIN;
87 }
88 break;
89
90 default:
92 return INT_MIN;
93 }
94
96
97 return dDate;
98}
99
100char *
102{
103 struct tm tt,
104 *tm = &tt;
107 bool EuroDates = false;
108
112}
113
114void
116{
117 int y,
118 m,
119 d;
120
121 j2date((int) (jd + date2j(2000, 1, 1)), &y, &m, &d);
122 mdy[0] = m;
123 mdy[1] = d;
124 mdy[2] = y;
125}
126
127void
129{
130
131
132
133
134 *jdate = (date) (date2j(mdy[2], mdy[0], mdy[1]) - date2j(2000, 1, 1));
135}
136
137int
139{
140
141
142
143
144 return (int) (dDate + date2j(2000, 1, 1) + 1) % 7;
145}
146
147void
149{
150 struct tm ts;
151
153 if (errno == 0)
154 *d = date2j(ts.tm_year, ts.tm_mon, ts.tm_mday) - date2j(2000, 1, 1);
155}
156
157#define PGTYPES_DATE_NUM_MAX_DIGITS 20
158
160#define PGTYPES_FMTDATE_DAY_DIGITS_LZ 1
161#define PGTYPES_FMTDATE_DOW_LITERAL_SHORT 2
162#define PGTYPES_FMTDATE_MONTH_DIGITS_LZ 3
163#define PGTYPES_FMTDATE_MONTH_LITERAL_SHORT 4
164#define PGTYPES_FMTDATE_YEAR_DIGITS_SHORT 5
165#define PGTYPES_FMTDATE_YEAR_DIGITS_LONG 6
166
169{
170 static struct
171 {
173 int component;
174 } mapping[] =
175 {
176
177
178
179
180 {
182 },
183 {
185 },
186 {
188 },
189 {
191 },
192 {
194 },
195 {
197 },
198 {
199 NULL, 0
200 }
201 };
202
204 int replace_type;
205
206 int i;
207 int dow;
208 char *start_pattern;
210
211
212 strcpy(outbuf, fmtstring);
213
214
217
218 for (i = 0; mapping[i].format != NULL; i++)
219 {
220 while ((start_pattern = strstr(outbuf, mapping[i].format)) != NULL)
221 {
222 switch (mapping[i].component)
223 {
227 break;
231 break;
235 break;
239 break;
243 break;
247 break;
248 default:
249
250
251
252
253 replace_val.str_val = " ";
255 }
256 switch (replace_type)
257 {
260 memcpy(start_pattern, replace_val.str_val,
261 strlen(replace_val.str_val));
264 break;
266 {
268
269 if (!t)
270 return -1;
273 memcpy(start_pattern, t, strlen(t));
275 }
276 break;
278 {
280
281 if (!t)
282 return -1;
284 "%02u", replace_val.uint_val);
285 memcpy(start_pattern, t, strlen(t));
287 }
288 break;
290 {
292
293 if (!t)
294 return -1;
296 "%04u", replace_val.uint_val);
297 memcpy(start_pattern, t, strlen(t));
299 }
300 break;
301 default:
302
303
304
305
306
307 break;
308 }
309 }
310 }
311 return 0;
312}
313
314
315
316
317
318
319
320
321
322
323
324
325
326
328#define PGTYPES_DATE_MONTH_MAXLENGTH 20
331{
332
333
334
335
337 int token_values[3] = {-1, -1, -1};
338 char *fmt_token_order;
339 char *fmt_ystart,
340 *fmt_mstart,
341 *fmt_dstart;
342 unsigned int i;
343 int reading_digit;
344 int token_count;
345 char *str_copy;
347
349
350 if (!d || || !fmt)
351 {
353 return -1;
354 }
355
356
357 fmt_ystart = strstr(fmt, "yy");
358 fmt_mstart = strstr(fmt, "mm");
359 fmt_dstart = strstr(fmt, "dd");
360
361 if (!fmt_ystart || !fmt_mstart || !fmt_dstart)
362 {
364 return -1;
365 }
366
367 if (fmt_ystart < fmt_mstart)
368 {
369
370 if (fmt_dstart < fmt_ystart)
371 {
372
373 fmt_token_order = "dym";
374 }
375 else if (fmt_dstart > fmt_mstart)
376 {
377
378 fmt_token_order = "ymd";
379 }
380 else
381 {
382
383 fmt_token_order = "ydm";
384 }
385 }
386 else
387 {
388
389
390 if (fmt_dstart < fmt_mstart)
391 {
392
393 fmt_token_order = "dmy";
394 }
395 else if (fmt_dstart > fmt_ystart)
396 {
397
398 fmt_token_order = "myd";
399 }
400 else
401 {
402
403 fmt_token_order = "mdy";
404 }
405 }
406
407
408
409
410
411
412
413
414
415
416
417
418 reading_digit = 1;
420 {
421 if (!isdigit((unsigned char) str[i]))
422 {
423 reading_digit = 0;
424 break;
425 }
426 }
427 if (reading_digit)
428 {
429 int frag_length[3];
430 int target_pos;
431
434 {
436 return -1;
437 }
438
439
440
441
442
443
445 if (!str_copy)
446 return -1;
447
448
449 if (i == 6)
450 {
451 frag_length[0] = 2;
452 frag_length[1] = 2;
453 frag_length[2] = 2;
454 }
455 else
456 {
457 if (fmt_token_order[0] == 'y')
458 {
459 frag_length[0] = 4;
460 frag_length[1] = 2;
461 frag_length[2] = 2;
462 }
463 else if (fmt_token_order[1] == 'y')
464 {
465 frag_length[0] = 2;
466 frag_length[1] = 4;
467 frag_length[2] = 2;
468 }
469 else
470 {
471 frag_length[0] = 2;
472 frag_length[1] = 2;
473 frag_length[2] = 4;
474 }
475 }
476 target_pos = 0;
477
478
479
480
481
482
484 {
485 int start_pos = 0;
486
487 if (i >= 1)
488 start_pos += frag_length[0];
489 if (i == 2)
490 start_pos += frag_length[1];
491
492 strncpy(str_copy + target_pos, str + start_pos,
493 frag_length[i]);
494 target_pos += frag_length[i];
495 if (i != 2)
496 {
497 str_copy[target_pos] = ' ';
498 target_pos++;
499 }
500 }
501 str_copy[target_pos] = '\0';
502 }
503 else
504 {
506 if (!str_copy)
507 return -1;
508
509
510 for (i = 0; str_copy[i]; i++)
511 str_copy[i] = (char) pg_tolower((unsigned char) str_copy[i]);
512 }
513
514
515 reading_digit = 0;
516 token_count = 0;
517 for (i = 0; i < strlen(str_copy); i++)
518 {
519 if (!isdigit((unsigned char) str_copy[i]) && reading_digit)
520 {
521
522 token[token_count][1] = i - 1;
523 reading_digit = 0;
524 token_count++;
525 }
526 else if (isdigit((unsigned char) str_copy[i]) && !reading_digit)
527 {
528
529 token[token_count][0] = i;
530 reading_digit = 1;
531 }
532 }
533
534
535
536
537
538 if (reading_digit)
539 {
540 token[token_count][1] = i - 1;
541 token_count++;
542 }
543
544
545 if (token_count < 2)
546 {
547
548
549
550
551 free(str_copy);
553 return -1;
554 }
555
556 if (token_count != 3)
557 {
558
559
560
561
563 char *start_pos;
564 int j;
565 int offset;
566 int found = 0;
568
569 if (!month_lower_tmp)
570 {
571
572 free(str_copy);
573 return -1;
574 }
577 {
579 {
580 month_lower_tmp[j] = (char) pg_tolower((unsigned char) list[i][j]);
581 if (!month_lower_tmp[j])
582 {
583
584 break;
585 }
586 }
587 if ((start_pos = strstr(str_copy, month_lower_tmp)))
588 {
589 offset = start_pos - str_copy;
590
591
592
593
594
595 if (offset < token[0][0])
596 {
601 token_count = 0;
602 }
603 else if (offset < token[1][0])
604 {
607 token_count = 1;
608 }
609 else
610 token_count = 2;
611 token[token_count][0] = offset;
612 token[token_count][1] = offset + strlen(month_lower_tmp) - 1;
613
614
615
616
617
618 token_values[token_count] = i + 1;
619 found = 1;
620 break;
621 }
622
623
624
625
626
627
629 {
631 {
633 i = -1;
634 }
635 }
636 }
637 if (!found)
638 {
639 free(month_lower_tmp);
640 free(str_copy);
642 return -1;
643 }
644
645
646
647
648
649
650
651
652
653
654
655
656 if (fmt_token_order[token_count] != 'm')
657 {
658
659 token_values[token_count] = -1;
660 }
661 free(month_lower_tmp);
662 }
663
664
666 {
667 *(str_copy + token[i][1] + 1) = '\0';
668
669 if (token_values[i] == -1)
670 {
671 errno = 0;
672 token_values[i] = strtol(str_copy + token[i][0], (char **) NULL, 10);
673
674 if (errno)
675 token_values[i] = -1;
676 }
677 if (fmt_token_order[i] == 'd')
679 else if (fmt_token_order[i] == 'm')
681 else if (fmt_token_order[i] == 'y')
683 }
684 free(str_copy);
685
687 {
689 return -1;
690 }
691
693 {
695 return -1;
696 }
697
699 {
701 return -1;
702 }
703
705 {
707 return -1;
708 }
709
711
712 return 0;
713}
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
void j2date(int jd, int *year, int *month, int *day)
void GetCurrentDateTime(struct pg_tm *tm)
const char *const months[]
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, DateTimeErrorExtra *extra)
int date2j(int year, int month, int day)
void GetEpochTime(struct pg_tm *tm)
#define TIMESTAMP_NOT_FINITE(j)
char * pgtypes_date_months[]
char * pgtypes_date_weekdays_short[]
char * pgtypes_strdup(const char *str)
char * pgtypes_alloc(long size)
#define PGTYPES_DATE_MONTH_MAXLENGTH
date PGTYPESdate_from_timestamp(timestamp dt)
int PGTYPESdate_dayofweek(date dDate)
char * PGTYPESdate_to_asc(date dDate)
void PGTYPESdate_today(date *d)
#define PGTYPES_FMTDATE_DAY_DIGITS_LZ
date PGTYPESdate_from_asc(char *str, char **endptr)
int PGTYPESdate_fmt_asc(date dDate, const char *fmtstring, char *outbuf)
#define PGTYPES_FMTDATE_MONTH_DIGITS_LZ
int PGTYPESdate_defmt_asc(date *d, const char *fmt, const char *str)
void PGTYPESdate_julmdy(date jd, int *mdy)
void PGTYPESdate_free(date *d)
void PGTYPESdate_mdyjul(int *mdy, date *jdate)
date * PGTYPESdate_new(void)
#define PGTYPES_FMTDATE_DOW_LITERAL_SHORT
#define PGTYPES_FMTDATE_YEAR_DIGITS_LONG
#define PGTYPES_FMTDATE_YEAR_DIGITS_SHORT
#define PGTYPES_DATE_NUM_MAX_DIGITS
#define PGTYPES_FMTDATE_MONTH_LITERAL_SHORT
#define PGTYPES_DATE_ERR_ENOTDMY
#define PGTYPES_DATE_BAD_DAY
#define PGTYPES_DATE_BAD_DATE
#define PGTYPES_DATE_ERR_ENOSHORTDATE
#define PGTYPES_DATE_ERR_EARGS
#define PGTYPES_DATE_BAD_MONTH
#define PGTYPES_TYPE_STRING_CONSTANT
#define PGTYPES_TYPE_UINT
#define PGTYPES_TYPE_STRING_MALLOCED
#define PGTYPES_TYPE_UINT_4_LZ
#define PGTYPES_TYPE_UINT_2_LZ
unsigned char pg_tolower(unsigned char ch)