* We've seen a digit. Time? Year? Date? */
| 669 | * We've seen a digit. Time? Year? Date? |
| 670 | */ |
| 671 | static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt) |
| 672 | { |
| 673 | int n; |
| 674 | char *end; |
| 675 | timestamp_t num; |
| 676 | |
| 677 | num = parse_timestamp(date, &end, 10); |
| 678 | |
| 679 | /* |
| 680 | * Seconds since 1970? We trigger on that for any numbers with |
| 681 | * more than 8 digits. This is because we don't want to rule out |
| 682 | * numbers like 20070606 as a YYYYMMDD date. |
| 683 | */ |
| 684 | if (num >= 100000000 && nodate(tm)) { |
| 685 | time_t time = num; |
| 686 | if (gmtime_r(&time, tm)) { |
| 687 | *tm_gmt = 1; |
| 688 | return end - date; |
| 689 | } |
| 690 | } |
| 691 | |
| 692 | /* |
| 693 | * Check for special formats: num[-.:/]num[same]num |
| 694 | */ |
| 695 | switch (*end) { |
| 696 | case ':': |
| 697 | case '.': |
| 698 | case '/': |
| 699 | case '-': |
| 700 | if (isdigit(end[1])) { |
| 701 | int match = match_multi_number(num, *end, date, end, tm, 0); |
| 702 | if (match) |
| 703 | return match; |
| 704 | } |
| 705 | } |
| 706 | |
| 707 | /* |
| 708 | * None of the special formats? Try to guess what |
| 709 | * the number meant. We use the number of digits |
| 710 | * to make a more educated guess.. |
| 711 | */ |
| 712 | n = 0; |
| 713 | do { |
| 714 | n++; |
| 715 | } while (isdigit(date[n])); |
| 716 | |
| 717 | /* 8 digits, compact style of ISO-8601's date: YYYYmmDD */ |
| 718 | /* 6 digits, compact style of ISO-8601's time: HHMMSS */ |
| 719 | if (n == 8 || n == 6) { |
| 720 | unsigned int num1 = num / 10000; |
| 721 | unsigned int num2 = (num % 10000) / 100; |
| 722 | unsigned int num3 = num % 100; |
| 723 | if (n == 8) |
| 724 | set_date(num1, num2, num3, NULL, time(NULL), tm); |
| 725 | else if (n == 6 && set_time(num1, num2, num3, tm) == 0 && |
| 726 | *end == '.' && isdigit(end[1])) |
| 727 | strtoul(end + 1, &end, 10); |
| 728 | return end - date; |
no test coverage detected