| 637 | } |
| 638 | |
| 639 | gdv_date64 castDATE_utf8(int64_t context, const char* input, gdv_int32 length) { |
| 640 | using arrow_vendored::date::day; |
| 641 | using arrow_vendored::date::month; |
| 642 | using arrow_vendored::date::sys_days; |
| 643 | using arrow_vendored::date::year; |
| 644 | using arrow_vendored::date::year_month_day; |
| 645 | using gandiva::TimeFields; |
| 646 | // format : 0 is year, 1 is month and 2 is day. |
| 647 | int dateFields[3]; |
| 648 | int dateIndex = 0, index = 0, value = 0; |
| 649 | int year_str_len = 0; |
| 650 | while (dateIndex < 3 && index < length) { |
| 651 | if (!isdigit(input[index])) { |
| 652 | dateFields[dateIndex++] = value; |
| 653 | value = 0; |
| 654 | } else { |
| 655 | value = (value * 10) + (input[index] - '0'); |
| 656 | if (dateIndex == TimeFields::kYear) { |
| 657 | year_str_len++; |
| 658 | } |
| 659 | } |
| 660 | index++; |
| 661 | } |
| 662 | |
| 663 | if (dateIndex < 3) { |
| 664 | // If we reached the end of input, we would have not encountered a separator |
| 665 | // store the last value |
| 666 | dateFields[dateIndex++] = value; |
| 667 | } |
| 668 | const char* msg = "Not a valid date value "; |
| 669 | if (dateIndex != 3) { |
| 670 | set_error_for_date(length, input, msg, context); |
| 671 | return 0; |
| 672 | } |
| 673 | |
| 674 | /* Handle two digit years |
| 675 | * If range of two digits is between 70 - 99 then year = 1970 - 1999 |
| 676 | * Else if two digits is between 00 - 69 = 2000 - 2069 |
| 677 | */ |
| 678 | if (dateFields[TimeFields::kYear] < 100 && year_str_len < 4) { |
| 679 | if (dateFields[TimeFields::kYear] < 70) { |
| 680 | dateFields[TimeFields::kYear] += 2000; |
| 681 | } else { |
| 682 | dateFields[TimeFields::kYear] += 1900; |
| 683 | } |
| 684 | } |
| 685 | year_month_day date = year(dateFields[TimeFields::kYear]) / |
| 686 | month(dateFields[TimeFields::kMonth]) / |
| 687 | day(dateFields[TimeFields::kDay]); |
| 688 | if (!date.ok()) { |
| 689 | set_error_for_date(length, input, msg, context); |
| 690 | return 0; |
| 691 | } |
| 692 | return std::chrono::time_point_cast<std::chrono::milliseconds>(sys_days(date)) |
| 693 | .time_since_epoch() |
| 694 | .count(); |
| 695 | } |
| 696 | |