\brief Returns time since the UNIX epoch in the requested unit
| 807 | |
| 808 | /// \brief Returns time since the UNIX epoch in the requested unit |
| 809 | static inline bool ParseTimestampStrptime(const char* buf, size_t length, |
| 810 | const char* format, bool ignore_time_in_day, |
| 811 | bool allow_trailing_chars, TimeUnit::type unit, |
| 812 | int64_t* out) { |
| 813 | // NOTE: strptime() is more than 10x faster than arrow_vendored::date::parse(). |
| 814 | // The buffer may not be nul-terminated |
| 815 | std::string clean_copy(buf, length); |
| 816 | struct tm result; |
| 817 | memset(&result, 0, sizeof(struct tm)); |
| 818 | #ifdef _WIN32 |
| 819 | char* ret = arrow_strptime(clean_copy.c_str(), format, &result); |
| 820 | #else |
| 821 | char* ret = strptime(clean_copy.c_str(), format, &result); |
| 822 | #endif |
| 823 | if (ret == NULLPTR) { |
| 824 | return false; |
| 825 | } |
| 826 | if (!allow_trailing_chars && static_cast<size_t>(ret - clean_copy.c_str()) != length) { |
| 827 | return false; |
| 828 | } |
| 829 | // ignore the time part |
| 830 | arrow_vendored::date::sys_seconds secs = |
| 831 | arrow_vendored::date::sys_days(arrow_vendored::date::year(result.tm_year + 1900) / |
| 832 | (result.tm_mon + 1) / std::max(result.tm_mday, 1)); |
| 833 | if (!ignore_time_in_day) { |
| 834 | secs += (std::chrono::hours(result.tm_hour) + std::chrono::minutes(result.tm_min) + |
| 835 | std::chrono::seconds(result.tm_sec)); |
| 836 | #if !defined(_WIN32) && !defined(_AIX) |
| 837 | secs -= std::chrono::seconds(result.tm_gmtoff); |
| 838 | #endif |
| 839 | } |
| 840 | return util::CastSecondsToUnit(unit, secs.time_since_epoch().count(), out); |
| 841 | } |
| 842 | |
| 843 | template <> |
| 844 | struct StringConverter<TimestampType> { |