Skip to content

Commit

Permalink
Add to_iso8601(date) Presto function (#8552)
Browse files Browse the repository at this point in the history
Summary: Pull Request resolved: #8552

Reviewed By: kgpai

Differential Revision: D55694587

Pulled By: mbasmanova

fbshipit-source-id: a3639d9bde41b29ef211f9c74bc2d8dc822c1537
  • Loading branch information
svm1 authored and facebook-github-bot committed Apr 4, 2024
1 parent efb7e77 commit e4f74d3
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 0 deletions.
4 changes: 4 additions & 0 deletions velox/docs/functions/presto/datetime.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ Date and Time Functions
Returns the UNIX timestamp ``unixtime`` as a timestamp with time zone
using ``string`` for the time zone.

.. function:: to_iso8601(x) -> varchar

Formats ``x`` as an ISO 8601 string. Supported types for ``x`` are: DATE.

.. function:: to_unixtime(timestamp) -> double

Returns ``timestamp`` as a UNIX timestamp.
Expand Down
11 changes: 11 additions & 0 deletions velox/functions/prestosql/DateTimeFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -1488,4 +1488,15 @@ struct TimeZoneMinuteFunction : public TimestampWithTimezoneSupport<T> {
}
};

template <typename T>
struct ToISO8601Function {
VELOX_DEFINE_FUNCTION_TYPES(T);

FOLLY_ALWAYS_INLINE void call(
out_type<Varchar>& result,
const arg_type<Date>& date) {
result = DateType::toIso8601(date);
}
};

} // namespace facebook::velox::functions
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ void registerSimpleFunctions(const std::string& prefix) {
registerFunction<FromIso8601Date, Date, Varchar>(
{prefix + "from_iso8601_date"});
registerFunction<CurrentDateFunction, Date>({prefix + "current_date"});
registerFunction<ToISO8601Function, Varchar, Date>({prefix + "to_iso8601"});
}
} // namespace

Expand Down
18 changes: 18 additions & 0 deletions velox/functions/prestosql/tests/DateTimeFunctionsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3996,3 +3996,21 @@ TEST_F(DateTimeFunctionsTest, fromUnixtimeDouble) {
});
assertEqualVectors(expected, actual);
}

TEST_F(DateTimeFunctionsTest, toISO8601Date) {
const auto toISO8601 = [&](const char* dateString) {
return evaluateOnce<std::string, int32_t>(
"to_iso8601(c0)", {DATE()->toDays(dateString)}, {DATE()});
};

EXPECT_EQ("1970-01-01", toISO8601("1970-01-01"));
EXPECT_EQ("2020-02-05", toISO8601("2020-02-05"));
EXPECT_EQ("1919-11-28", toISO8601("1919-11-28"));
EXPECT_EQ("4653-07-01", toISO8601("4653-07-01"));
EXPECT_EQ("1844-10-14", toISO8601("1844-10-14"));
EXPECT_EQ("0001-01-01", toISO8601("1-01-01"));
EXPECT_EQ("9999-12-31", toISO8601("9999-12-31"));
EXPECT_EQ("872343-04-19", toISO8601("872343-04-19"));
EXPECT_EQ("-3492-10-05", toISO8601("-3492-10-05"));
EXPECT_EQ("-0653-07-12", toISO8601("-653-07-12"));
}
6 changes: 6 additions & 0 deletions velox/type/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,10 @@ std::string IntervalYearMonthType::valueToString(int32_t value) const {
}

std::string DateType::toString(int32_t days) const {
return DateType::toIso8601(days);
}

std::string DateType::toIso8601(int32_t days) {
// Find the number of seconds for the days_;
// Casting 86400 to int64 to handle overflows gracefully.
int64_t daySeconds = days * (int64_t)(86400);
Expand All @@ -985,6 +989,8 @@ std::string DateType::toString(int32_t days) const {
days);
TimestampToStringOptions options;
options.mode = TimestampToStringOptions::Mode::kDateOnly;
// Enable zero-padding for year, to ensure compliance with 'YYYY' format.
options.zeroPaddingYear = true;
std::string result;
result.resize(getMaxStringLength(options));
const auto view =
Expand Down
4 changes: 4 additions & 0 deletions velox/type/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,10 @@ class DateType : public IntegerType {

std::string toString(int32_t days) const;

/// Returns a date, represented as days since epoch,
/// as an ISO 8601-formatted string.
static std::string toIso8601(int32_t days);

int32_t toDays(folly::StringPiece in) const;

int32_t toDays(const char* in, size_t len) const;
Expand Down

0 comments on commit e4f74d3

Please sign in to comment.