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;

209 struct tm tm;

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;

346 struct tm tm;

347

349

350 if (!d || str || !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;

419 for (i = 0; str[i]; i++)

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

432 i = strlen(str);

433 if (i != 8 && i != 6)

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

483 for (i = 0; i < 3; i++)

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 }

576 for (i = 0; list[i]; i++)

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 {

630 if (list[i + 1] == NULL)

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

665 for (i = 0; i < 3; i++)

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)