| 1640 | } |
| 1641 | |
| 1642 | DateTimeResult DateTimeFormatter::parse(const std::string_view& input) const { |
| 1643 | Date date; |
| 1644 | const char* cur = input.data(); |
| 1645 | const char* end = cur + input.size(); |
| 1646 | |
| 1647 | for (int i = 0; i < tokens_.size(); i++) { |
| 1648 | auto& tok = tokens_[i]; |
| 1649 | switch (tok.type) { |
| 1650 | case DateTimeToken::Type::kLiteral: |
| 1651 | if (tok.literal.size() > end - cur || |
| 1652 | std::memcmp(cur, tok.literal.data(), tok.literal.size()) != 0) { |
| 1653 | return ErrorCode::PARSE_LITERAL_ERROR; |
| 1654 | } |
| 1655 | cur += tok.literal.size(); |
| 1656 | break; |
| 1657 | case DateTimeToken::Type::kPattern: |
| 1658 | if (i + 1 < tokens_.size() && |
| 1659 | tokens_[i + 1].type == DateTimeToken::Type::kPattern) { |
| 1660 | auto errorCode = |
| 1661 | parseFromPattern(tok.pattern, input, cur, end, date, true, type_); |
| 1662 | if (errorCode != ErrorCode::NO_ERROR) { |
| 1663 | return errorCode; |
| 1664 | } |
| 1665 | } else { |
| 1666 | auto errorCode = parseFromPattern( |
| 1667 | tok.pattern, input, cur, end, date, false, type_); |
| 1668 | if (errorCode != ErrorCode::NO_ERROR) { |
| 1669 | return errorCode; |
| 1670 | } |
| 1671 | } |
| 1672 | break; |
| 1673 | } |
| 1674 | } |
| 1675 | |
| 1676 | // Era is BC and year of era is provided |
| 1677 | if (date.isYearOfEra && !date.isAd) { |
| 1678 | date.year = -1 * (date.year - 1); |
| 1679 | } |
| 1680 | |
| 1681 | if (date.isHourOfHalfDay) { |
| 1682 | if (!date.isAm) { |
| 1683 | date.hour += 12; |
| 1684 | } |
| 1685 | } |
| 1686 | |
| 1687 | // Ensure all day of month values are valid for ending month value |
| 1688 | for (int i = 0; i < date.dayOfMonthValues.size(); i++) { |
| 1689 | if (!util::isValidDate(date.year, date.month, date.dayOfMonthValues[i])) { |
| 1690 | return ErrorCode::DAY_OUT_OF_RANGE; |
| 1691 | } |
| 1692 | } |
| 1693 | |
| 1694 | // Ensure all day of year values are valid for ending year value |
| 1695 | for (int i = 0; i < date.dayOfYearValues.size(); i++) { |
| 1696 | if (!util::isValidDayOfYear(date.year, date.dayOfYearValues[i])) { |
| 1697 | return ErrorCode::DAY_OUT_OF_RANGE; |
| 1698 | } |
| 1699 | } |