Skip to content

Commit

Permalink
feat: added anytime to date module ##936 (#947)
Browse files Browse the repository at this point in the history
* feat: added anytime to date module

* broken tests addressed

* broken tests addressed

* removed out of scope changes

* removed out of scope changes

---------

Co-authored-by: Tony Cao <[email protected]>
  • Loading branch information
tonykcao and tonykcao authored Oct 5, 2024
1 parent 37ee841 commit 62d5a58
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
13 changes: 13 additions & 0 deletions include/faker-cxx/date.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@ enum class DateFormat
Timestamp,
};

/**
* @brief Generates a random date between UNIX epoch and 200 years from now
*
* @returns ISO formatted string.
*
* @code
* faker::date::anytime() // "2023-12-08T19:31:32Z"
* faker::date::anytime(DateFormat::ISO) // "2020-06-16T15:24:09Z"
* faker::date::anytime(DateFormat::Timestamp) // "1592321049"
* @endcode
*/
FAKER_CXX_EXPORT std::string anytime(DateFormat dateFormat = DateFormat::ISO);

/**
* @brief Generates a random date in the past.
*
Expand Down
34 changes: 34 additions & 0 deletions src/modules/date.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,40 @@ std::string betweenDate(const auto& from, const auto& to, DateFormat dateFormat)
const auto numberOfHoursInDay = 24;
const auto numberOfDaysInYear = 365;

std::string anytime(DateFormat dateFormat)
{
constexpr int64_t total_seconds = 3600LL * 24LL* 365LL * 200LL; // sec/hr * hr/d * d/yr * years

int64_t now_seconds = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
int64_t max_seconds = now_seconds + total_seconds;

std::random_device rd;
std::mt19937_64 gen(rd());
std::uniform_int_distribution<int64_t> dis(0, max_seconds);

int64_t random_seconds = dis(gen);

auto timePoint = std::chrono::system_clock::time_point{std::chrono::seconds{random_seconds}};
std::string result;

if (dateFormat == DateFormat::Timestamp)
{
result = std::to_string(random_seconds);
}
else
{
time_t timePointTimeT = std::chrono::system_clock::to_time_t(timePoint);

std::tm utcTime = *std::gmtime(&timePointTimeT);

std::stringstream ss;
ss << std::put_time(&utcTime, "%Y-%m-%dT%H:%M:%SZ");
result = ss.str();
}

return result;
}

std::string futureDate(int years, DateFormat dateFormat)
{
const auto startDate = std::chrono::system_clock::now() + std::chrono::hours{1};
Expand Down
36 changes: 36 additions & 0 deletions tests/modules/date_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,42 @@ TEST_F(DateTest, shouldGenerateFutureDateTimestamp)
EXPECT_TRUE(std::chrono::duration_cast<std::chrono::seconds>(futureDate - currentDate).count() < secondsInYear);
EXPECT_TRUE(futureDate > currentDate);
}
TEST_F(DateTest, shouldGenerateAnytimeISO)
{
const auto currentDate = std::chrono::system_clock::now();
const auto unixEpoch = std::chrono::system_clock::time_point{};

for (int i = 0; i < 100; ++i)
{
const auto anytimeISO = anytime(DateFormat::ISO);
const auto generatedDate = parseISOFormattedStringToTimePoint(anytimeISO);
EXPECT_GT(generatedDate, unixEpoch);

auto duration = generatedDate - currentDate;
double durationInYears = static_cast<double>(std::chrono::duration_cast<std::chrono::seconds>(duration).count()) / (365.25 * 24 * 3600);
durationInYears = std::abs(durationInYears);
EXPECT_LT(durationInYears, 201);
}
}

TEST_F(DateTest, shouldGenerateAnytimeTimestamp)
{
const auto currentDate = std::chrono::system_clock::now();
const auto unixEpoch = std::chrono::system_clock::time_point{};

for (int i = 0; i < 100; ++i)
{
const auto anytimeTimestamp = anytime(DateFormat::Timestamp);
int64_t timestampSeconds = std::stoll(anytimeTimestamp);
auto generatedDate = std::chrono::system_clock::time_point{std::chrono::seconds{timestampSeconds}};
EXPECT_GT(generatedDate, unixEpoch);

auto duration = generatedDate - currentDate;
double durationInYears = static_cast<double>(std::chrono::duration_cast<std::chrono::seconds>(duration).count()) / (365.25 * 24 * 3600);
durationInYears = std::abs(durationInYears);
EXPECT_LT(durationInYears, 201);
}
}

TEST_F(DateTest, shouldGenerateSoonDateISO)
{
Expand Down

0 comments on commit 62d5a58

Please sign in to comment.