#include "hdr/types/struct_tm.h"
#include "src/__support/CPP/array.h"
#include "src/__support/integer_to_string.h"
#include "src/time/strftime.h"
#include "src/time/time_constants.h"
#include "test/UnitTest/Test.h"
#define EXPECT_STREQ_LEN(actual_written, actual_str, expected_str) \
EXPECT_EQ(actual_written, sizeof(expected_str) - 1); \
EXPECT_STREQ(actual_str, expected_str);
constexpr int get_adjusted_year(int year) {
return year - LIBC_NAMESPACE::time_constants::TIME_YEAR_BASE;
}
class SimplePaddedNum {
static constexpr int BUFF_LEN = 16;
char buff[BUFF_LEN];
size_t cur_len;
void clear_buff() {
for (int i = 0; i < BUFF_LEN; ++i)
buff[i] = '\0';
}
public:
SimplePaddedNum() = default;
char *get_padded_num(int num, size_t min_width, char padding_char = '0') {
clear_buff();
LIBC_NAMESPACE::IntegerToString<int> raw(num);
auto str = raw.view();
int leading_zeroes = static_cast<int>(min_width - raw.size());
int i = 0;
for (; static_cast<int>(i) < leading_zeroes; ++i)
buff[i] = padding_char;
for (size_t str_cur = 0, e = str.size(); str_cur < e; ++i, ++str_cur)
buff[i] = str[str_cur];
cur_len = i;
return buff;
}
size_t get_str_len() { return cur_len; }
};
TEST(LlvmLibcStrftimeTest, ConstantConversions) {
struct tm time;
char buffer[100];
size_t written = 0;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%n", &time);
EXPECT_STREQ_LEN(written, buffer, "\n");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%t", &time);
EXPECT_STREQ_LEN(written, buffer, "\t");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%%", &time);
EXPECT_STREQ_LEN(written, buffer, "%");
}
TEST(LlvmLibcStrftimeTest, CenturyTests) {
struct tm time;
char buffer[100];
size_t written = 0;
time.tm_year = get_adjusted_year(2022);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%C", &time);
EXPECT_STREQ_LEN(written, buffer, "20");
time.tm_year = get_adjusted_year(11900);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%C", &time);
EXPECT_STREQ_LEN(written, buffer, "119");
time.tm_year = get_adjusted_year(1900);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%C", &time);
EXPECT_STREQ_LEN(written, buffer, "19");
time.tm_year = get_adjusted_year(900);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%C", &time);
EXPECT_STREQ_LEN(written, buffer, "09");
time.tm_year = get_adjusted_year(0);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%C", &time);
EXPECT_STREQ_LEN(written, buffer, "00");
time.tm_year = get_adjusted_year(-1);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%C", &time);
EXPECT_STREQ_LEN(written, buffer, "00");
time.tm_year = get_adjusted_year(-101);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%C", &time);
EXPECT_STREQ_LEN(written, buffer, "-1");
time.tm_year = get_adjusted_year(-9001);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%C", &time);
EXPECT_STREQ_LEN(written, buffer, "-90");
time.tm_year = get_adjusted_year(-10001);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%C", &time);
EXPECT_STREQ_LEN(written, buffer, "-100");
time.tm_year = get_adjusted_year(2023);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01C", &time);
EXPECT_STREQ_LEN(written, buffer, "20");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02C", &time);
EXPECT_STREQ_LEN(written, buffer, "20");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05C", &time);
EXPECT_STREQ_LEN(written, buffer, "00020");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010C", &time);
EXPECT_STREQ_LEN(written, buffer, "0000000020");
time.tm_year = get_adjusted_year(900);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01C", &time);
EXPECT_STREQ_LEN(written, buffer, "9");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02C", &time);
EXPECT_STREQ_LEN(written, buffer, "09");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05C", &time);
EXPECT_STREQ_LEN(written, buffer, "00009");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010C", &time);
EXPECT_STREQ_LEN(written, buffer, "0000000009");
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01C", &time);
EXPECT_STREQ_LEN(written, buffer, "123");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02C", &time);
EXPECT_STREQ_LEN(written, buffer, "123");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05C", &time);
EXPECT_STREQ_LEN(written, buffer, "00123");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010C", &time);
EXPECT_STREQ_LEN(written, buffer, "0000000123");
time.tm_year = get_adjusted_year(-123);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01C", &time);
EXPECT_STREQ_LEN(written, buffer, "-1");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02C", &time);
EXPECT_STREQ_LEN(written, buffer, "-1");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05C", &time);
EXPECT_STREQ_LEN(written, buffer, "-0001");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010C", &time);
EXPECT_STREQ_LEN(written, buffer, "-000000001");
time.tm_year = get_adjusted_year(2023);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+1C", &time);
EXPECT_STREQ_LEN(written, buffer, "20");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+2C", &time);
EXPECT_STREQ_LEN(written, buffer, "20");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+5C", &time);
EXPECT_STREQ_LEN(written, buffer, "+0020");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+10C", &time);
EXPECT_STREQ_LEN(written, buffer, "+000000020");
time.tm_year = get_adjusted_year(900);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+1C", &time);
EXPECT_STREQ_LEN(written, buffer, "9");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+2C", &time);
EXPECT_STREQ_LEN(written, buffer, "09");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+5C", &time);
EXPECT_STREQ_LEN(written, buffer, "+0009");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+10C", &time);
EXPECT_STREQ_LEN(written, buffer, "+000000009");
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+1C", &time);
EXPECT_STREQ_LEN(written, buffer, "+123");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+2C", &time);
EXPECT_STREQ_LEN(written, buffer, "+123");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+5C", &time);
EXPECT_STREQ_LEN(written, buffer, "+0123");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+10C", &time);
EXPECT_STREQ_LEN(written, buffer, "+000000123");
time.tm_year = get_adjusted_year(-123);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+1C", &time);
EXPECT_STREQ_LEN(written, buffer, "-1");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+2C", &time);
EXPECT_STREQ_LEN(written, buffer, "-1");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+5C", &time);
EXPECT_STREQ_LEN(written, buffer, "-0001");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+10C", &time);
EXPECT_STREQ_LEN(written, buffer, "-000000001");
time.tm_year = get_adjusted_year(17);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%C", &time);
EXPECT_STREQ_LEN(written, buffer, "00");
time.tm_year = get_adjusted_year(270);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%C", &time);
EXPECT_STREQ_LEN(written, buffer, "02");
time.tm_year = get_adjusted_year(270);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+3C", &time);
EXPECT_STREQ_LEN(written, buffer, "+02");
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+3C", &time);
EXPECT_STREQ_LEN(written, buffer, "+123");
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%04C", &time);
EXPECT_STREQ_LEN(written, buffer, "0123");
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+4C", &time);
EXPECT_STREQ_LEN(written, buffer, "+123");
time.tm_year = get_adjusted_year(123456);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%06C", &time);
EXPECT_STREQ_LEN(written, buffer, "001234");
time.tm_year = get_adjusted_year(123456);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+6C", &time);
EXPECT_STREQ_LEN(written, buffer, "+01234");
}
TEST(LlvmLibcStrftimeTest, TwoDigitDayOfMonth) {
using LIBC_NAMESPACE::time_constants::MAX_DAYS_PER_MONTH;
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
for (int i = 1; i <= MAX_DAYS_PER_MONTH; ++i) {
time.tm_mday = i;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%d", &time);
char *result = spn.get_padded_num(i, 2);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, size_t(2));
}
time.tm_mday = 5;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01d", &time);
EXPECT_STREQ_LEN(written, buffer, "5");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02d", &time);
EXPECT_STREQ_LEN(written, buffer, "05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05d", &time);
EXPECT_STREQ_LEN(written, buffer, "00005");
time.tm_mday = 31;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01d", &time);
EXPECT_STREQ_LEN(written, buffer, "31");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02d", &time);
EXPECT_STREQ_LEN(written, buffer, "31");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05d", &time);
EXPECT_STREQ_LEN(written, buffer, "00031");
}
TEST(LlvmLibcStrftimeTest, MinDigitDayOfMonth) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
for (int i = 1; i < 32; ++i) {
time.tm_mday = i;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%e", &time);
char *result = spn.get_padded_num(i, 2, ' ');
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
}
time.tm_mday = 5;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01e", &time);
EXPECT_STREQ_LEN(written, buffer, "5");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02e", &time);
EXPECT_STREQ_LEN(written, buffer, "05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05e", &time);
EXPECT_STREQ_LEN(written, buffer, "00005");
time.tm_mday = 31;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01e", &time);
EXPECT_STREQ_LEN(written, buffer, "31");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02e", &time);
EXPECT_STREQ_LEN(written, buffer, "31");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05e", &time);
EXPECT_STREQ_LEN(written, buffer, "00031");
}
TEST(LlvmLibcStrftimeTest, ISOYearOfCentury) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
time.tm_wday = 0;
time.tm_yday = 100;
for (int i = 0; i < 102; ++i) {
time.tm_year = i;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%g", &time);
char *result = spn.get_padded_num(i % 100, 2);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
}
time.tm_year = 99;
This table has an X for each day that should be in the previous year,
everywhere else should be in the current year.
yday
0123456
i 1 Monday
s 2 Tuesday
o 3 Wednesday
w 4 Thursday
d 5 X Friday
a 6 XX Saturday
y 7 XXX Sunday
*/
for (int yday = 0; yday < 5; ++yday) {
for (int iso_wday = LIBC_NAMESPACE::time_constants::MONDAY; iso_wday < 8;
++iso_wday) {
time.tm_wday = iso_wday % LIBC_NAMESPACE::time_constants::DAYS_PER_WEEK;
time.tm_yday = yday;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%g", &time);
if (iso_wday <= LIBC_NAMESPACE::time_constants::THURSDAY || yday >= 3) {
EXPECT_STREQ_LEN(written, buffer, "99");
} else {
const int days_since_thursday =
iso_wday - LIBC_NAMESPACE::time_constants::THURSDAY;
if (days_since_thursday > yday) {
EXPECT_STREQ_LEN(written, buffer, "98");
} else {
EXPECT_STREQ_LEN(written, buffer, "99");
}
}
}
}
Similar to above, but the Xs represent being in the NEXT year. Also the
top counts down until the end of the year.
year end - yday
6543210
i 1 XXX Monday
s 2 XX Tuesday
o 3 X Wednesday
w 4 Thursday
d 5 Friday
a 6 Saturday
y 7 Sunday
If we place the charts next to each other, you can more easily see the
pattern:
year end - yday yday
6543210 0123456
i 1 XXX Monday
s 2 XX Tuesday
o 3 X Wednesday
w 4 Thursday
d 5 X Friday
a 6 XX Saturday
y 7 XXX Sunday
From this we can see that thursday is always in the same ISO and regular
year, because the ISO year starts on the week with the 4th. Since Thursday
is at least 3 days from either edge of the ISO week, the first thursday of
the year is always in the first ISO week of the year.
*/
struct tm time_leap_year;
char buffer_leap_year[100];
size_t written_leap_year = 0;
time_leap_year = time;
time_leap_year.tm_year = 100;
for (int days_left = 0; days_left < 5; ++days_left) {
for (int iso_wday = LIBC_NAMESPACE::time_constants::MONDAY; iso_wday < 8;
++iso_wday) {
time.tm_wday = iso_wday % LIBC_NAMESPACE::time_constants::DAYS_PER_WEEK;
time.tm_yday = LIBC_NAMESPACE::time_constants::DAYS_PER_NON_LEAP_YEAR -
1 - days_left;
time_leap_year.tm_wday =
iso_wday % LIBC_NAMESPACE::time_constants::DAYS_PER_WEEK;
time_leap_year.tm_yday =
LIBC_NAMESPACE::time_constants::LAST_DAY_OF_LEAP_YEAR - days_left;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%g", &time);
written_leap_year = LIBC_NAMESPACE::strftime(
buffer_leap_year, sizeof(buffer_leap_year), "%g", &time_leap_year);
if (iso_wday >= LIBC_NAMESPACE::time_constants::THURSDAY ||
days_left >= 3) {
EXPECT_STREQ_LEN(written, buffer, "99");
EXPECT_STREQ_LEN(written_leap_year, buffer_leap_year, "00");
} else {
if (iso_wday + days_left <= 3) {
EXPECT_STREQ_LEN(written, buffer, "00");
EXPECT_STREQ_LEN(written_leap_year, buffer_leap_year, "01");
} else {
EXPECT_STREQ_LEN(written, buffer, "99");
EXPECT_STREQ_LEN(written_leap_year, buffer_leap_year, "00");
}
}
}
}
time.tm_year = 5;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01g", &time);
EXPECT_STREQ_LEN(written, buffer, "5");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02g", &time);
EXPECT_STREQ_LEN(written, buffer, "05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05g", &time);
EXPECT_STREQ_LEN(written, buffer, "00005");
time.tm_year = 31;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01g", &time);
EXPECT_STREQ_LEN(written, buffer, "31");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02g", &time);
EXPECT_STREQ_LEN(written, buffer, "31");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05g", &time);
EXPECT_STREQ_LEN(written, buffer, "00031");
}
TEST(LlvmLibcStrftimeTest, ISOYear) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
time.tm_wday = 0;
time.tm_yday = 100;
for (int i = 1; i < 10000; ++i) {
time.tm_year = get_adjusted_year(i);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%G", &time);
char *result = spn.get_padded_num(i, 4);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
}
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%G", &time);
EXPECT_STREQ_LEN(written, buffer, "12345");
time.tm_year = get_adjusted_year(1999);
for (int yday = 0; yday < 5; ++yday) {
for (int iso_wday = 1; iso_wday < 8; ++iso_wday) {
time.tm_wday = iso_wday % LIBC_NAMESPACE::time_constants::DAYS_PER_WEEK;
time.tm_yday = yday;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%G", &time);
if (iso_wday <= LIBC_NAMESPACE::time_constants::THURSDAY || yday >= 4) {
EXPECT_STREQ_LEN(written, buffer, "1999");
} else {
const int days_since_thursday =
iso_wday - LIBC_NAMESPACE::time_constants::THURSDAY;
if (days_since_thursday > yday) {
EXPECT_STREQ_LEN(written, buffer, "1998");
} else {
EXPECT_STREQ_LEN(written, buffer, "1999");
}
}
}
}
struct tm time_leap_year;
char buffer_leap_year[100];
size_t written_leap_year = 0;
time_leap_year = time;
time_leap_year.tm_year = 100;
for (int days_left = 0; days_left < 5; ++days_left) {
for (int iso_wday = 1; iso_wday < 8; ++iso_wday) {
time.tm_wday = iso_wday % LIBC_NAMESPACE::time_constants::DAYS_PER_WEEK;
time.tm_yday =
LIBC_NAMESPACE::time_constants::LAST_DAY_OF_NON_LEAP_YEAR - days_left;
time_leap_year.tm_wday =
iso_wday % LIBC_NAMESPACE::time_constants::DAYS_PER_WEEK;
time_leap_year.tm_yday =
LIBC_NAMESPACE::time_constants::LAST_DAY_OF_LEAP_YEAR - days_left;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%G", &time);
written_leap_year = LIBC_NAMESPACE::strftime(
buffer_leap_year, sizeof(buffer_leap_year), "%G", &time_leap_year);
if (iso_wday >= 4 || days_left >= 3) {
EXPECT_STREQ_LEN(written, buffer, "1999");
EXPECT_STREQ_LEN(written_leap_year, buffer_leap_year, "2000");
} else {
if (iso_wday + days_left <= 3) {
EXPECT_STREQ_LEN(written, buffer, "2000");
EXPECT_STREQ_LEN(written_leap_year, buffer_leap_year, "2001");
} else {
EXPECT_STREQ_LEN(written, buffer, "1999");
EXPECT_STREQ_LEN(written_leap_year, buffer_leap_year, "2000");
}
}
}
}
time.tm_year = get_adjusted_year(5);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01G", &time);
EXPECT_STREQ_LEN(written, buffer, "5");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02G", &time);
EXPECT_STREQ_LEN(written, buffer, "05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05G", &time);
EXPECT_STREQ_LEN(written, buffer, "00005");
time.tm_year = get_adjusted_year(31);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01G", &time);
EXPECT_STREQ_LEN(written, buffer, "31");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02G", &time);
EXPECT_STREQ_LEN(written, buffer, "31");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05G", &time);
EXPECT_STREQ_LEN(written, buffer, "00031");
time.tm_year = get_adjusted_year(2001);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01G", &time);
EXPECT_STREQ_LEN(written, buffer, "2001");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02G", &time);
EXPECT_STREQ_LEN(written, buffer, "2001");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05G", &time);
EXPECT_STREQ_LEN(written, buffer, "02001");
}
TEST(LlvmLibcStrftimeTest, TwentyFourHour) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
for (int i = 0; i < 24; ++i) {
time.tm_hour = i;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%H", &time);
char *result = spn.get_padded_num(i, 2);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
}
time.tm_hour = 5;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01H", &time);
EXPECT_STREQ_LEN(written, buffer, "5");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02H", &time);
EXPECT_STREQ_LEN(written, buffer, "05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05H", &time);
EXPECT_STREQ_LEN(written, buffer, "00005");
time.tm_hour = 23;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01H", &time);
EXPECT_STREQ_LEN(written, buffer, "23");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02H", &time);
EXPECT_STREQ_LEN(written, buffer, "23");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05H", &time);
EXPECT_STREQ_LEN(written, buffer, "00023");
}
TEST(LlvmLibcStrftimeTest, TwelveHour) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
time.tm_hour = 0;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%I", &time);
EXPECT_STREQ_LEN(written, buffer, "12");
for (int i = 1; i <= 12; ++i) {
char *result = spn.get_padded_num(i, 2);
time.tm_hour = i;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%I", &time);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
time.tm_hour = i + 12;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%I", &time);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
}
time.tm_hour = 5;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01I", &time);
EXPECT_STREQ_LEN(written, buffer, "5");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02I", &time);
EXPECT_STREQ_LEN(written, buffer, "05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05I", &time);
EXPECT_STREQ_LEN(written, buffer, "00005");
time.tm_hour = 23;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01I", &time);
EXPECT_STREQ_LEN(written, buffer, "11");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02I", &time);
EXPECT_STREQ_LEN(written, buffer, "11");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05I", &time);
EXPECT_STREQ_LEN(written, buffer, "00011");
}
TEST(LlvmLibcStrftimeTest, DayOfYear) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
for (int i = 0; i < LIBC_NAMESPACE::time_constants::DAYS_PER_LEAP_YEAR; ++i) {
time.tm_yday = i;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%j", &time);
char *result = spn.get_padded_num(i + 1, 3);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
}
time.tm_yday = 5 - 1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01j", &time);
EXPECT_STREQ_LEN(written, buffer, "5");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02j", &time);
EXPECT_STREQ_LEN(written, buffer, "05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05j", &time);
EXPECT_STREQ_LEN(written, buffer, "00005");
time.tm_yday = 123 - 1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01j", &time);
EXPECT_STREQ_LEN(written, buffer, "123");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02j", &time);
EXPECT_STREQ_LEN(written, buffer, "123");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05j", &time);
EXPECT_STREQ_LEN(written, buffer, "00123");
}
TEST(LlvmLibcStrftimeTest, MonthOfYear) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
for (int i = 0; i < LIBC_NAMESPACE::time_constants::MONTHS_PER_YEAR; ++i) {
time.tm_mon = i;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%m", &time);
char *result = spn.get_padded_num(i + 1, 2);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
}
time.tm_mon = 5 - 1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01m", &time);
EXPECT_STREQ_LEN(written, buffer, "5");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02m", &time);
EXPECT_STREQ_LEN(written, buffer, "05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05m", &time);
EXPECT_STREQ_LEN(written, buffer, "00005");
time.tm_mon = 11 - 1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01m", &time);
EXPECT_STREQ_LEN(written, buffer, "11");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02m", &time);
EXPECT_STREQ_LEN(written, buffer, "11");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05m", &time);
EXPECT_STREQ_LEN(written, buffer, "00011");
}
TEST(LlvmLibcStrftimeTest, MinuteOfHour) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
for (int i = 0; i < LIBC_NAMESPACE::time_constants::MINUTES_PER_HOUR; ++i) {
time.tm_min = i;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%M", &time);
char *result = spn.get_padded_num(i, 2);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
}
time.tm_min = 5;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01M", &time);
EXPECT_STREQ_LEN(written, buffer, "5");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02M", &time);
EXPECT_STREQ_LEN(written, buffer, "05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05M", &time);
EXPECT_STREQ_LEN(written, buffer, "00005");
time.tm_min = 11;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01M", &time);
EXPECT_STREQ_LEN(written, buffer, "11");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02M", &time);
EXPECT_STREQ_LEN(written, buffer, "11");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05M", &time);
EXPECT_STREQ_LEN(written, buffer, "00011");
}
TEST(LlvmLibcStrftimeTest, SecondsSinceEpoch) {
struct tm time;
char buffer[100];
size_t written = 0;
time.tm_year = get_adjusted_year(1970);
time.tm_mon = 0;
time.tm_mday = 1;
time.tm_hour = 0;
time.tm_min = 0;
time.tm_sec = 1;
time.tm_isdst = 0;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%s", &time);
EXPECT_STREQ_LEN(written, buffer, "1");
time.tm_year = get_adjusted_year(2025);
time.tm_mon = 1;
time.tm_mday = 4;
time.tm_hour = 11;
time.tm_min = 8;
time.tm_sec = 41;
time.tm_isdst = 0;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%s", &time);
EXPECT_STREQ_LEN(written, buffer, "1738667321");
time.tm_year = get_adjusted_year(1970);
time.tm_mon = 0;
time.tm_mday = 1;
time.tm_hour = 0;
time.tm_min = 0;
time.tm_sec = 5;
time.tm_isdst = 0;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01s", &time);
EXPECT_STREQ_LEN(written, buffer, "5");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02s", &time);
EXPECT_STREQ_LEN(written, buffer, "05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05s", &time);
EXPECT_STREQ_LEN(written, buffer, "00005");
time.tm_min = 11;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01s", &time);
EXPECT_STREQ_LEN(written, buffer, "665");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02s", &time);
EXPECT_STREQ_LEN(written, buffer, "665");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05s", &time);
EXPECT_STREQ_LEN(written, buffer, "00665");
}
TEST(LlvmLibcStrftimeTest, SecondOfMinute) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
for (int i = 0; i < LIBC_NAMESPACE::time_constants::SECONDS_PER_MIN; ++i) {
time.tm_sec = i;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%S", &time);
char *result = spn.get_padded_num(i, 2);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
}
time.tm_sec = 5;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01S", &time);
EXPECT_STREQ_LEN(written, buffer, "5");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02S", &time);
EXPECT_STREQ_LEN(written, buffer, "05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05S", &time);
EXPECT_STREQ_LEN(written, buffer, "00005");
time.tm_sec = 11;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01S", &time);
EXPECT_STREQ_LEN(written, buffer, "11");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02S", &time);
EXPECT_STREQ_LEN(written, buffer, "11");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05S", &time);
EXPECT_STREQ_LEN(written, buffer, "00011");
}
TEST(LlvmLibcStrftimeTest, ISODayOfWeek) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
time.tm_wday = LIBC_NAMESPACE::time_constants::SUNDAY;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%u", &time);
EXPECT_STREQ_LEN(written, buffer, "7");
for (int i = LIBC_NAMESPACE::time_constants::MONDAY;
i <= LIBC_NAMESPACE::time_constants::SATURDAY; ++i) {
time.tm_wday = i;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%u", &time);
char *result = spn.get_padded_num(i, 1);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
}
time.tm_wday = 5;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01u", &time);
EXPECT_STREQ_LEN(written, buffer, "5");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02u", &time);
EXPECT_STREQ_LEN(written, buffer, "05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05u", &time);
EXPECT_STREQ_LEN(written, buffer, "00005");
}
TEST(LlvmLibcStrftimeTest, WeekOfYearStartingSunday) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
time.tm_year = get_adjusted_year(2000);
const int WEEK_START = LIBC_NAMESPACE::time_constants::SUNDAY;
for (int first_weekday = LIBC_NAMESPACE::time_constants::SUNDAY;
first_weekday <= LIBC_NAMESPACE::time_constants::SATURDAY;
++first_weekday) {
time.tm_wday = first_weekday;
int cur_week = 0;
for (int yday = 0;
yday < LIBC_NAMESPACE::time_constants::DAYS_PER_LEAP_YEAR; ++yday) {
time.tm_yday = yday;
if (time.tm_wday == WEEK_START)
++cur_week;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%U", &time);
char *result = spn.get_padded_num(cur_week, 2);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
time.tm_wday =
(time.tm_wday + 1) % LIBC_NAMESPACE::time_constants::DAYS_PER_WEEK;
}
}
time.tm_wday = LIBC_NAMESPACE::time_constants::SUNDAY;
time.tm_yday = 22;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01U", &time);
EXPECT_STREQ_LEN(written, buffer, "4");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02U", &time);
EXPECT_STREQ_LEN(written, buffer, "04");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05U", &time);
EXPECT_STREQ_LEN(written, buffer, "00004");
time.tm_wday = LIBC_NAMESPACE::time_constants::SUNDAY;
time.tm_yday = 78;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01U", &time);
EXPECT_STREQ_LEN(written, buffer, "12");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02U", &time);
EXPECT_STREQ_LEN(written, buffer, "12");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05U", &time);
EXPECT_STREQ_LEN(written, buffer, "00012");
}
TEST(LlvmLibcStrftimeTest, ISOWeekOfYear) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
const int starting_year = get_adjusted_year(1999);
const int days_to_check =
LIBC_NAMESPACE::time_constants::DAYS_PER_NON_LEAP_YEAR +
LIBC_NAMESPACE::time_constants::DAYS_PER_LEAP_YEAR +
LIBC_NAMESPACE::time_constants::DAYS_PER_NON_LEAP_YEAR;
const int WEEK_START = LIBC_NAMESPACE::time_constants::MONDAY;
for (int first_weekday = LIBC_NAMESPACE::time_constants::SUNDAY;
first_weekday <= LIBC_NAMESPACE::time_constants::SATURDAY;
++first_weekday) {
time.tm_year = starting_year;
time.tm_wday = first_weekday;
time.tm_yday = 0;
int cur_week = 1;
if (first_weekday == LIBC_NAMESPACE::time_constants::SUNDAY ||
first_weekday == LIBC_NAMESPACE::time_constants::SATURDAY)
cur_week = 52;
else if (first_weekday == LIBC_NAMESPACE::time_constants::FRIDAY)
cur_week = 53;
for (size_t cur_day = 0; cur_day < days_to_check; ++cur_day) {
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%V", &time);
char *result = spn.get_padded_num(cur_week, 2);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
++time.tm_yday;
if (time.tm_yday ==
(time.tm_year == get_adjusted_year(2000)
? LIBC_NAMESPACE::time_constants::DAYS_PER_LEAP_YEAR
: LIBC_NAMESPACE::time_constants::DAYS_PER_NON_LEAP_YEAR)) {
time.tm_yday = 0;
++time.tm_year;
}
time.tm_wday =
(time.tm_wday + 1) % LIBC_NAMESPACE::time_constants::DAYS_PER_WEEK;
if (time.tm_wday == WEEK_START) {
++cur_week;
const int days_left_in_year =
(time.tm_year == get_adjusted_year(2000)
? LIBC_NAMESPACE::time_constants::LAST_DAY_OF_LEAP_YEAR
: LIBC_NAMESPACE::time_constants::LAST_DAY_OF_NON_LEAP_YEAR) -
time.tm_yday;
if (days_left_in_year < 3 || (cur_week > 51 && time.tm_yday < 10))
cur_week = 1;
}
}
}
time.tm_wday = LIBC_NAMESPACE::time_constants::SUNDAY;
time.tm_yday = 22;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01U", &time);
EXPECT_STREQ_LEN(written, buffer, "4");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02U", &time);
EXPECT_STREQ_LEN(written, buffer, "04");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05U", &time);
EXPECT_STREQ_LEN(written, buffer, "00004");
time.tm_wday = LIBC_NAMESPACE::time_constants::SUNDAY;
time.tm_yday = 78;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01U", &time);
EXPECT_STREQ_LEN(written, buffer, "12");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02U", &time);
EXPECT_STREQ_LEN(written, buffer, "12");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05U", &time);
EXPECT_STREQ_LEN(written, buffer, "00012");
}
TEST(LlvmLibcStrftimeTest, DayOfWeek) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
for (int i = LIBC_NAMESPACE::time_constants::SUNDAY;
i <= LIBC_NAMESPACE::time_constants::SATURDAY; ++i) {
time.tm_wday = i;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%w", &time);
char *result = spn.get_padded_num(i, 1);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
}
time.tm_wday = 5;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01w", &time);
EXPECT_STREQ_LEN(written, buffer, "5");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02w", &time);
EXPECT_STREQ_LEN(written, buffer, "05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05w", &time);
EXPECT_STREQ_LEN(written, buffer, "00005");
}
TEST(LlvmLibcStrftimeTest, WeekOfYearStartingMonday) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
time.tm_year = get_adjusted_year(2000);
const int WEEK_START = LIBC_NAMESPACE::time_constants::MONDAY;
for (int first_weekday = LIBC_NAMESPACE::time_constants::SUNDAY;
first_weekday <= LIBC_NAMESPACE::time_constants::SATURDAY;
++first_weekday) {
time.tm_wday = first_weekday;
int cur_week = 0;
for (int yday = 0;
yday < LIBC_NAMESPACE::time_constants::DAYS_PER_LEAP_YEAR; ++yday) {
time.tm_yday = yday;
if (time.tm_wday == WEEK_START)
++cur_week;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%W", &time);
char *result = spn.get_padded_num(cur_week, 2);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
time.tm_wday =
(time.tm_wday + 1) % LIBC_NAMESPACE::time_constants::DAYS_PER_WEEK;
}
}
time.tm_wday = LIBC_NAMESPACE::time_constants::MONDAY;
time.tm_yday = 22;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01W", &time);
EXPECT_STREQ_LEN(written, buffer, "4");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02W", &time);
EXPECT_STREQ_LEN(written, buffer, "04");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05W", &time);
EXPECT_STREQ_LEN(written, buffer, "00004");
time.tm_wday = LIBC_NAMESPACE::time_constants::MONDAY;
time.tm_yday = 78;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01W", &time);
EXPECT_STREQ_LEN(written, buffer, "12");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02W", &time);
EXPECT_STREQ_LEN(written, buffer, "12");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05W", &time);
EXPECT_STREQ_LEN(written, buffer, "00012");
}
TEST(LlvmLibcStrftimeTest, YearOfCentury) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
time.tm_year = get_adjusted_year(2000);
for (int year = 1900; year < 2001; ++year) {
time.tm_year = get_adjusted_year(year);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%y", &time);
char *result = spn.get_padded_num(year % 100, 2);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
}
time.tm_year = get_adjusted_year(2004);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01y", &time);
EXPECT_STREQ_LEN(written, buffer, "4");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02y", &time);
EXPECT_STREQ_LEN(written, buffer, "04");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05y", &time);
EXPECT_STREQ_LEN(written, buffer, "00004");
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01y", &time);
EXPECT_STREQ_LEN(written, buffer, "45");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%02y", &time);
EXPECT_STREQ_LEN(written, buffer, "45");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05y", &time);
EXPECT_STREQ_LEN(written, buffer, "00045");
}
TEST(LlvmLibcStrftimeTest, FullYearTests) {
struct tm time;
char buffer[100];
size_t written = 0;
SimplePaddedNum spn;
for (int i = 1; i < 10000; ++i) {
time.tm_year = get_adjusted_year(i);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%Y", &time);
char *result = spn.get_padded_num(i, 4);
ASSERT_STREQ(buffer, result);
ASSERT_EQ(written, spn.get_str_len());
}
time.tm_year = get_adjusted_year(11900);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%Y", &time);
EXPECT_STREQ_LEN(written, buffer, "11900");
time.tm_year = get_adjusted_year(0);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%Y", &time);
EXPECT_STREQ_LEN(written, buffer, "0000");
time.tm_year = get_adjusted_year(-1);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%Y", &time);
EXPECT_STREQ_LEN(written, buffer, "-001");
time.tm_year = get_adjusted_year(-9001);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%Y", &time);
EXPECT_STREQ_LEN(written, buffer, "-9001");
time.tm_year = get_adjusted_year(-10001);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%Y", &time);
EXPECT_STREQ_LEN(written, buffer, "-10001");
time.tm_year = get_adjusted_year(2023);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01Y", &time);
EXPECT_STREQ_LEN(written, buffer, "2023");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%04Y", &time);
EXPECT_STREQ_LEN(written, buffer, "2023");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05Y", &time);
EXPECT_STREQ_LEN(written, buffer, "02023");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010Y", &time);
EXPECT_STREQ_LEN(written, buffer, "0000002023");
time.tm_year = get_adjusted_year(900);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01Y", &time);
EXPECT_STREQ_LEN(written, buffer, "900");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%04Y", &time);
EXPECT_STREQ_LEN(written, buffer, "0900");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05Y", &time);
EXPECT_STREQ_LEN(written, buffer, "00900");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010Y", &time);
EXPECT_STREQ_LEN(written, buffer, "0000000900");
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01Y", &time);
EXPECT_STREQ_LEN(written, buffer, "12345");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%04Y", &time);
EXPECT_STREQ_LEN(written, buffer, "12345");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05Y", &time);
EXPECT_STREQ_LEN(written, buffer, "12345");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010Y", &time);
EXPECT_STREQ_LEN(written, buffer, "0000012345");
time.tm_year = get_adjusted_year(-123);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01Y", &time);
EXPECT_STREQ_LEN(written, buffer, "-123");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%04Y", &time);
EXPECT_STREQ_LEN(written, buffer, "-123");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05Y", &time);
EXPECT_STREQ_LEN(written, buffer, "-0123");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010Y", &time);
EXPECT_STREQ_LEN(written, buffer, "-000000123");
time.tm_year = get_adjusted_year(2023);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+1Y", &time);
EXPECT_STREQ_LEN(written, buffer, "2023");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+4Y", &time);
EXPECT_STREQ_LEN(written, buffer, "2023");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+5Y", &time);
EXPECT_STREQ_LEN(written, buffer, "+2023");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+10Y", &time);
EXPECT_STREQ_LEN(written, buffer, "+000002023");
time.tm_year = get_adjusted_year(900);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+1Y", &time);
EXPECT_STREQ_LEN(written, buffer, "900");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+4Y", &time);
EXPECT_STREQ_LEN(written, buffer, "0900");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+5Y", &time);
EXPECT_STREQ_LEN(written, buffer, "+0900");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+10Y", &time);
EXPECT_STREQ_LEN(written, buffer, "+000000900");
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+1Y", &time);
EXPECT_STREQ_LEN(written, buffer, "+12345");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+4Y", &time);
EXPECT_STREQ_LEN(written, buffer, "+12345");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+5Y", &time);
EXPECT_STREQ_LEN(written, buffer, "+12345");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+10Y", &time);
EXPECT_STREQ_LEN(written, buffer, "+000012345");
time.tm_year = get_adjusted_year(-123);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+1Y", &time);
EXPECT_STREQ_LEN(written, buffer, "-123");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+4Y", &time);
EXPECT_STREQ_LEN(written, buffer, "-123");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+5Y", &time);
EXPECT_STREQ_LEN(written, buffer, "-0123");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+10Y", &time);
EXPECT_STREQ_LEN(written, buffer, "-000000123");
time.tm_year = get_adjusted_year(1970);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%Y", &time);
EXPECT_STREQ_LEN(written, buffer, "1970");
time.tm_year = get_adjusted_year(1970);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+4Y", &time);
EXPECT_STREQ_LEN(written, buffer, "1970");
time.tm_year = get_adjusted_year(27);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%Y", &time);
EXPECT_STREQ_LEN(written, buffer, "0027");
time.tm_year = get_adjusted_year(270);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%Y", &time);
EXPECT_STREQ_LEN(written, buffer, "0270");
time.tm_year = get_adjusted_year(270);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+4Y", &time);
EXPECT_STREQ_LEN(written, buffer, "0270");
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%Y", &time);
EXPECT_STREQ_LEN(written, buffer, "12345");
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+4Y", &time);
EXPECT_STREQ_LEN(written, buffer, "+12345");
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05Y", &time);
EXPECT_STREQ_LEN(written, buffer, "12345");
time.tm_year = get_adjusted_year(270);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+5Y", &time);
EXPECT_STREQ_LEN(written, buffer, "+0270");
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+5Y", &time);
EXPECT_STREQ_LEN(written, buffer, "+12345");
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%06Y", &time);
EXPECT_STREQ_LEN(written, buffer, "012345");
time.tm_year = get_adjusted_year(12345);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+6Y", &time);
EXPECT_STREQ_LEN(written, buffer, "+12345");
time.tm_year = get_adjusted_year(123456);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%08Y", &time);
EXPECT_STREQ_LEN(written, buffer, "00123456");
time.tm_year = get_adjusted_year(123456);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+8Y", &time);
EXPECT_STREQ_LEN(written, buffer, "+0123456");
}
struct num_str_pair {
int num;
LIBC_NAMESPACE::cpp::string_view str;
};
TEST(LlvmLibcStrftimeTest, ShortWeekdayName) {
struct tm time;
char buffer[100];
size_t written = 0;
constexpr LIBC_NAMESPACE::cpp::array<
num_str_pair, LIBC_NAMESPACE::time_constants::DAYS_PER_WEEK>
WEEKDAY_PAIRS = {{
{LIBC_NAMESPACE::time_constants::SUNDAY, "Sun"},
{LIBC_NAMESPACE::time_constants::MONDAY, "Mon"},
{LIBC_NAMESPACE::time_constants::TUESDAY, "Tue"},
{LIBC_NAMESPACE::time_constants::WEDNESDAY, "Wed"},
{LIBC_NAMESPACE::time_constants::THURSDAY, "Thu"},
{LIBC_NAMESPACE::time_constants::FRIDAY, "Fri"},
{LIBC_NAMESPACE::time_constants::SATURDAY, "Sat"},
}};
for (size_t i = 0; i < WEEKDAY_PAIRS.size(); ++i) {
time.tm_wday = WEEKDAY_PAIRS[i].num;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%a", &time);
EXPECT_STREQ(buffer, WEEKDAY_PAIRS[i].str.data());
EXPECT_EQ(written, WEEKDAY_PAIRS[i].str.size());
}
time.tm_wday = -1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%a", &time);
EXPECT_STREQ_LEN(written, buffer, "?");
time.tm_wday = LIBC_NAMESPACE::time_constants::SATURDAY + 1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%a", &time);
EXPECT_STREQ_LEN(written, buffer, "?");
time.tm_wday = LIBC_NAMESPACE::time_constants::THURSDAY;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%1a", &time);
EXPECT_STREQ_LEN(written, buffer, "Thu");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%3a", &time);
EXPECT_STREQ_LEN(written, buffer, "Thu");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%10a", &time);
EXPECT_STREQ_LEN(written, buffer, " Thu");
time.tm_wday = -1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%1a", &time);
EXPECT_STREQ_LEN(written, buffer, "?");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%3a", &time);
EXPECT_STREQ_LEN(written, buffer, " ?");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%10a", &time);
EXPECT_STREQ_LEN(written, buffer, " ?");
}
TEST(LlvmLibcStrftimeTest, FullWeekdayName) {
struct tm time;
char buffer[100];
size_t written = 0;
constexpr LIBC_NAMESPACE::cpp::array<
num_str_pair, LIBC_NAMESPACE::time_constants::DAYS_PER_WEEK>
WEEKDAY_PAIRS = {{
{LIBC_NAMESPACE::time_constants::SUNDAY, "Sunday"},
{LIBC_NAMESPACE::time_constants::MONDAY, "Monday"},
{LIBC_NAMESPACE::time_constants::TUESDAY, "Tuesday"},
{LIBC_NAMESPACE::time_constants::WEDNESDAY, "Wednesday"},
{LIBC_NAMESPACE::time_constants::THURSDAY, "Thursday"},
{LIBC_NAMESPACE::time_constants::FRIDAY, "Friday"},
{LIBC_NAMESPACE::time_constants::SATURDAY, "Saturday"},
}};
for (size_t i = 0; i < WEEKDAY_PAIRS.size(); ++i) {
time.tm_wday = WEEKDAY_PAIRS[i].num;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%A", &time);
EXPECT_STREQ(buffer, WEEKDAY_PAIRS[i].str.data());
EXPECT_EQ(written, WEEKDAY_PAIRS[i].str.size());
}
time.tm_wday = -1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%A", &time);
EXPECT_STREQ_LEN(written, buffer, "?");
time.tm_wday = LIBC_NAMESPACE::time_constants::SATURDAY + 1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%A", &time);
EXPECT_STREQ_LEN(written, buffer, "?");
time.tm_wday = LIBC_NAMESPACE::time_constants::THURSDAY;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%1A", &time);
EXPECT_STREQ_LEN(written, buffer, "Thursday");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%3A", &time);
EXPECT_STREQ_LEN(written, buffer, "Thursday");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%10A", &time);
EXPECT_STREQ_LEN(written, buffer, " Thursday");
time.tm_wday = -1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%1A", &time);
EXPECT_STREQ_LEN(written, buffer, "?");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%3A", &time);
EXPECT_STREQ_LEN(written, buffer, " ?");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%10A", &time);
EXPECT_STREQ_LEN(written, buffer, " ?");
}
TEST(LlvmLibcStrftimeTest, ShortMonthName) {
struct tm time;
char buffer[100];
size_t written = 0;
constexpr LIBC_NAMESPACE::cpp::array<
num_str_pair, LIBC_NAMESPACE::time_constants::MONTHS_PER_YEAR>
MONTH_PAIRS = {{
{LIBC_NAMESPACE::time_constants::JANUARY, "Jan"},
{LIBC_NAMESPACE::time_constants::FEBRUARY, "Feb"},
{LIBC_NAMESPACE::time_constants::MARCH, "Mar"},
{LIBC_NAMESPACE::time_constants::APRIL, "Apr"},
{LIBC_NAMESPACE::time_constants::MAY, "May"},
{LIBC_NAMESPACE::time_constants::JUNE, "Jun"},
{LIBC_NAMESPACE::time_constants::JULY, "Jul"},
{LIBC_NAMESPACE::time_constants::AUGUST, "Aug"},
{LIBC_NAMESPACE::time_constants::SEPTEMBER, "Sep"},
{LIBC_NAMESPACE::time_constants::OCTOBER, "Oct"},
{LIBC_NAMESPACE::time_constants::NOVEMBER, "Nov"},
{LIBC_NAMESPACE::time_constants::DECEMBER, "Dec"},
}};
for (size_t i = 0; i < MONTH_PAIRS.size(); ++i) {
time.tm_mon = MONTH_PAIRS[i].num;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%b", &time);
EXPECT_STREQ(buffer, MONTH_PAIRS[i].str.data());
EXPECT_EQ(written, MONTH_PAIRS[i].str.size());
}
time.tm_mon = -1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%b", &time);
EXPECT_STREQ_LEN(written, buffer, "?");
time.tm_mon = LIBC_NAMESPACE::time_constants::DECEMBER + 1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%b", &time);
EXPECT_STREQ_LEN(written, buffer, "?");
time.tm_mon = LIBC_NAMESPACE::time_constants::OCTOBER;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%h", &time);
EXPECT_STREQ_LEN(written, buffer, "Oct");
time.tm_mon = LIBC_NAMESPACE::time_constants::OCTOBER;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%1b", &time);
EXPECT_STREQ_LEN(written, buffer, "Oct");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%3b", &time);
EXPECT_STREQ_LEN(written, buffer, "Oct");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%10b", &time);
EXPECT_STREQ_LEN(written, buffer, " Oct");
time.tm_mon = -1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%1b", &time);
EXPECT_STREQ_LEN(written, buffer, "?");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%3b", &time);
EXPECT_STREQ_LEN(written, buffer, " ?");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%10b", &time);
EXPECT_STREQ_LEN(written, buffer, " ?");
}
TEST(LlvmLibcStrftimeTest, FullMonthName) {
struct tm time;
char buffer[100];
size_t written = 0;
constexpr LIBC_NAMESPACE::cpp::array<
num_str_pair, LIBC_NAMESPACE::time_constants::MONTHS_PER_YEAR>
MONTH_PAIRS = {{
{LIBC_NAMESPACE::time_constants::JANUARY, "January"},
{LIBC_NAMESPACE::time_constants::FEBRUARY, "February"},
{LIBC_NAMESPACE::time_constants::MARCH, "March"},
{LIBC_NAMESPACE::time_constants::APRIL, "April"},
{LIBC_NAMESPACE::time_constants::MAY, "May"},
{LIBC_NAMESPACE::time_constants::JUNE, "June"},
{LIBC_NAMESPACE::time_constants::JULY, "July"},
{LIBC_NAMESPACE::time_constants::AUGUST, "August"},
{LIBC_NAMESPACE::time_constants::SEPTEMBER, "September"},
{LIBC_NAMESPACE::time_constants::OCTOBER, "October"},
{LIBC_NAMESPACE::time_constants::NOVEMBER, "November"},
{LIBC_NAMESPACE::time_constants::DECEMBER, "December"},
}};
for (size_t i = 0; i < MONTH_PAIRS.size(); ++i) {
time.tm_mon = MONTH_PAIRS[i].num;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%B", &time);
EXPECT_STREQ(buffer, MONTH_PAIRS[i].str.data());
EXPECT_EQ(written, MONTH_PAIRS[i].str.size());
}
time.tm_mon = -1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%B", &time);
EXPECT_STREQ_LEN(written, buffer, "?");
time.tm_mon = LIBC_NAMESPACE::time_constants::DECEMBER + 1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%B", &time);
EXPECT_STREQ_LEN(written, buffer, "?");
time.tm_mon = LIBC_NAMESPACE::time_constants::OCTOBER;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%1B", &time);
EXPECT_STREQ_LEN(written, buffer, "October");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%3B", &time);
EXPECT_STREQ_LEN(written, buffer, "October");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%10B", &time);
EXPECT_STREQ_LEN(written, buffer, " October");
time.tm_mon = -1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%1B", &time);
EXPECT_STREQ_LEN(written, buffer, "?");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%3B", &time);
EXPECT_STREQ_LEN(written, buffer, " ?");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%10B", &time);
EXPECT_STREQ_LEN(written, buffer, " ?");
}
TEST(LlvmLibcStrftimeTest, AM_PM) {
struct tm time;
char buffer[100];
size_t written = 0;
time.tm_hour = 0;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%p", &time);
EXPECT_STREQ_LEN(written, buffer, "AM");
time.tm_hour = 6;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%p", &time);
EXPECT_STREQ_LEN(written, buffer, "AM");
time.tm_hour = 12;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%p", &time);
EXPECT_STREQ_LEN(written, buffer, "PM");
time.tm_hour = 18;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%p", &time);
EXPECT_STREQ_LEN(written, buffer, "PM");
time.tm_hour = 6;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%1p", &time);
EXPECT_STREQ_LEN(written, buffer, "AM");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%2p", &time);
EXPECT_STREQ_LEN(written, buffer, "AM");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%10p", &time);
EXPECT_STREQ_LEN(written, buffer, " AM");
time.tm_hour = 18;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%1p", &time);
EXPECT_STREQ_LEN(written, buffer, "PM");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%2p", &time);
EXPECT_STREQ_LEN(written, buffer, "PM");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%10p", &time);
EXPECT_STREQ_LEN(written, buffer, " PM");
}
TEST(LlvmLibcStrftimeTest, DateFormatUS) {
struct tm time;
char buffer[100];
size_t written = 0;
time.tm_mon = 0;
time.tm_mday = 2;
time.tm_year = get_adjusted_year(1903);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%D", &time);
EXPECT_STREQ_LEN(written, buffer, "01/02/03");
time.tm_mon = 11;
time.tm_mday = 31;
time.tm_year = get_adjusted_year(1999);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%D", &time);
EXPECT_STREQ_LEN(written, buffer, "12/31/99");
time.tm_mon = 8;
time.tm_mday = 16;
time.tm_year = get_adjusted_year(2019);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%D", &time);
EXPECT_STREQ_LEN(written, buffer, "09/16/19");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%x", &time);
EXPECT_STREQ_LEN(written, buffer, "09/16/19");
time.tm_mon = 1;
time.tm_mday = 5;
time.tm_year = get_adjusted_year(2025);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01D", &time);
EXPECT_STREQ_LEN(written, buffer, "2/05/25");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%07D", &time);
EXPECT_STREQ_LEN(written, buffer, "2/05/25");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010D", &time);
EXPECT_STREQ_LEN(written, buffer, "0002/05/25");
time.tm_mon = 9;
time.tm_mday = 2;
time.tm_year = get_adjusted_year(2000);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01D", &time);
EXPECT_STREQ_LEN(written, buffer, "10/02/00");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%07D", &time);
EXPECT_STREQ_LEN(written, buffer, "10/02/00");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010D", &time);
EXPECT_STREQ_LEN(written, buffer, "0010/02/00");
}
TEST(LlvmLibcStrftimeTest, DateFormatISO) {
struct tm time;
char buffer[100];
size_t written = 0;
time.tm_year = get_adjusted_year(1901);
time.tm_mon = 1;
time.tm_mday = 3;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%F", &time);
EXPECT_STREQ_LEN(written, buffer, "1901-02-03");
time.tm_year = get_adjusted_year(1999);
time.tm_mon = 11;
time.tm_mday = 31;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%F", &time);
EXPECT_STREQ_LEN(written, buffer, "1999-12-31");
time.tm_year = get_adjusted_year(2019);
time.tm_mon = 8;
time.tm_mday = 16;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%F", &time);
EXPECT_STREQ_LEN(written, buffer, "2019-09-16");
time.tm_year = get_adjusted_year(123);
time.tm_mon = 3;
time.tm_mday = 5;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%F", &time);
EXPECT_STREQ_LEN(written, buffer, "0123-04-05");
time.tm_year = get_adjusted_year(67);
time.tm_mon = 7;
time.tm_mday = 9;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%F", &time);
EXPECT_STREQ_LEN(written, buffer, "0067-08-09");
time.tm_year = get_adjusted_year(2);
time.tm_mon = 1;
time.tm_mday = 14;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%F", &time);
EXPECT_STREQ_LEN(written, buffer, "0002-02-14");
time.tm_year = get_adjusted_year(-543);
time.tm_mon = 1;
time.tm_mday = 1;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%F", &time);
EXPECT_STREQ_LEN(written, buffer, "-543-02-01");
time.tm_year = get_adjusted_year(2025);
time.tm_mon = 1;
time.tm_mday = 5;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01F", &time);
EXPECT_STREQ_LEN(written, buffer, "2025-02-05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010F", &time);
EXPECT_STREQ_LEN(written, buffer, "2025-02-05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%012F", &time);
EXPECT_STREQ_LEN(written, buffer, "002025-02-05");
time.tm_year = get_adjusted_year(12345);
time.tm_mon = 11;
time.tm_mday = 25;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01F", &time);
EXPECT_STREQ_LEN(written, buffer, "12345-12-25");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010F", &time);
EXPECT_STREQ_LEN(written, buffer, "12345-12-25");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%012F", &time);
EXPECT_STREQ_LEN(written, buffer, "012345-12-25");
time.tm_year = get_adjusted_year(476);
time.tm_mon = 8;
time.tm_mday = 4;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01F", &time);
EXPECT_STREQ_LEN(written, buffer, "476-09-04");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010F", &time);
EXPECT_STREQ_LEN(written, buffer, "0476-09-04");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%012F", &time);
EXPECT_STREQ_LEN(written, buffer, "000476-09-04");
time.tm_year = get_adjusted_year(-100);
time.tm_mon = 9;
time.tm_mday = 31;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01F", &time);
EXPECT_STREQ_LEN(written, buffer, "-100-10-31");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010F", &time);
EXPECT_STREQ_LEN(written, buffer, "-100-10-31");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%012F", &time);
EXPECT_STREQ_LEN(written, buffer, "-00100-10-31");
time.tm_year = get_adjusted_year(2025);
time.tm_mon = 1;
time.tm_mday = 5;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+1F", &time);
EXPECT_STREQ_LEN(written, buffer, "2025-02-05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+10F", &time);
EXPECT_STREQ_LEN(written, buffer, "2025-02-05");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+12F", &time);
EXPECT_STREQ_LEN(written, buffer, "+02025-02-05");
time.tm_year = get_adjusted_year(12345);
time.tm_mon = 11;
time.tm_mday = 25;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+1F", &time);
EXPECT_STREQ_LEN(written, buffer, "+12345-12-25");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+10F", &time);
EXPECT_STREQ_LEN(written, buffer, "+12345-12-25");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+12F", &time);
EXPECT_STREQ_LEN(written, buffer, "+12345-12-25");
time.tm_year = get_adjusted_year(476);
time.tm_mon = 8;
time.tm_mday = 4;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+1F", &time);
EXPECT_STREQ_LEN(written, buffer, "476-09-04");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+10F", &time);
EXPECT_STREQ_LEN(written, buffer, "0476-09-04");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+12F", &time);
EXPECT_STREQ_LEN(written, buffer, "+00476-09-04");
time.tm_year = get_adjusted_year(-100);
time.tm_mon = 9;
time.tm_mday = 31;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+1F", &time);
EXPECT_STREQ_LEN(written, buffer, "-100-10-31");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+10F", &time);
EXPECT_STREQ_LEN(written, buffer, "-100-10-31");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%+12F", &time);
EXPECT_STREQ_LEN(written, buffer, "-00100-10-31");
}
TEST(LlvmLibcStrftimeTest, TimeFormatAMPM) {
struct tm time;
char buffer[100];
size_t written = 0;
time.tm_hour = 0;
time.tm_min = 0;
time.tm_sec = 0;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%r", &time);
EXPECT_STREQ_LEN(written, buffer, "12:00:00 AM");
time.tm_hour = 1;
time.tm_min = 23;
time.tm_sec = 45;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%r", &time);
EXPECT_STREQ_LEN(written, buffer, "01:23:45 AM");
time.tm_hour = 18;
time.tm_min = 6;
time.tm_sec = 2;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%r", &time);
EXPECT_STREQ_LEN(written, buffer, "06:06:02 PM");
time.tm_hour = 10;
time.tm_min = 9;
time.tm_sec = 59;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01r", &time);
EXPECT_STREQ_LEN(written, buffer, "10:09:59 AM");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%011r", &time);
EXPECT_STREQ_LEN(written, buffer, "10:09:59 AM");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%013r", &time);
EXPECT_STREQ_LEN(written, buffer, "0010:09:59 AM");
time.tm_hour = 16;
time.tm_min = 56;
time.tm_sec = 9;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01r", &time);
EXPECT_STREQ_LEN(written, buffer, "4:56:09 PM");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%011r", &time);
EXPECT_STREQ_LEN(written, buffer, "04:56:09 PM");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%013r", &time);
EXPECT_STREQ_LEN(written, buffer, "0004:56:09 PM");
}
TEST(LlvmLibcStrftimeTest, TimeFormatMinute) {
struct tm time;
char buffer[100];
size_t written = 0;
time.tm_hour = 0;
time.tm_min = 0;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%R", &time);
EXPECT_STREQ_LEN(written, buffer, "00:00");
time.tm_hour = 1;
time.tm_min = 23;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%R", &time);
EXPECT_STREQ_LEN(written, buffer, "01:23");
time.tm_hour = 18;
time.tm_min = 6;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%R", &time);
EXPECT_STREQ_LEN(written, buffer, "18:06");
time.tm_hour = 10;
time.tm_min = 9;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01R", &time);
EXPECT_STREQ_LEN(written, buffer, "10:09");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05R", &time);
EXPECT_STREQ_LEN(written, buffer, "10:09");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%07R", &time);
EXPECT_STREQ_LEN(written, buffer, "0010:09");
time.tm_hour = 4;
time.tm_min = 56;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01R", &time);
EXPECT_STREQ_LEN(written, buffer, "4:56");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%05R", &time);
EXPECT_STREQ_LEN(written, buffer, "04:56");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%07R", &time);
EXPECT_STREQ_LEN(written, buffer, "0004:56");
}
TEST(LlvmLibcStrftimeTest, TimeFormatSecond) {
struct tm time;
char buffer[100];
size_t written = 0;
time.tm_hour = 0;
time.tm_min = 0;
time.tm_sec = 0;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%T", &time);
EXPECT_STREQ_LEN(written, buffer, "00:00:00");
time.tm_hour = 1;
time.tm_min = 23;
time.tm_sec = 45;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%T", &time);
EXPECT_STREQ_LEN(written, buffer, "01:23:45");
time.tm_hour = 18;
time.tm_min = 6;
time.tm_sec = 2;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%T", &time);
EXPECT_STREQ_LEN(written, buffer, "18:06:02");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%X", &time);
EXPECT_STREQ_LEN(written, buffer, "18:06:02");
time.tm_hour = 10;
time.tm_min = 9;
time.tm_sec = 59;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01T", &time);
EXPECT_STREQ_LEN(written, buffer, "10:09:59");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%08T", &time);
EXPECT_STREQ_LEN(written, buffer, "10:09:59");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010T", &time);
EXPECT_STREQ_LEN(written, buffer, "0010:09:59");
time.tm_hour = 4;
time.tm_min = 56;
time.tm_sec = 9;
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%01T", &time);
EXPECT_STREQ_LEN(written, buffer, "4:56:09");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%08T", &time);
EXPECT_STREQ_LEN(written, buffer, "04:56:09");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%010T", &time);
EXPECT_STREQ_LEN(written, buffer, "0004:56:09");
}
TEST(LlvmLibcStrftimeTest, TimeFormatFullDateTime) {
struct tm time;
char buffer[100];
size_t written = 0;
time.tm_wday = 0;
time.tm_mon = 0;
time.tm_mday = 1;
time.tm_hour = 0;
time.tm_min = 0;
time.tm_sec = 0;
time.tm_year = get_adjusted_year(1900);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%c", &time);
EXPECT_STREQ_LEN(written, buffer, "Sun Jan 1 00:00:00 1900");
time.tm_wday = 3;
time.tm_mon = 5;
time.tm_mday = 15;
time.tm_hour = 14;
time.tm_min = 13;
time.tm_sec = 12;
time.tm_year = get_adjusted_year(2011);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%c", &time);
EXPECT_STREQ_LEN(written, buffer, "Wed Jun 15 14:13:12 2011");
time.tm_wday = 4;
time.tm_mon = 1;
time.tm_mday = 6;
time.tm_hour = 12;
time.tm_min = 57;
time.tm_sec = 50;
time.tm_year = get_adjusted_year(2025);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%c", &time);
EXPECT_STREQ_LEN(written, buffer, "Thu Feb 6 12:57:50 2025");
time.tm_wday = 5;
time.tm_mon = 8;
time.tm_mday = 4;
time.tm_hour = 16;
time.tm_min = 57;
time.tm_sec = 18;
time.tm_year = get_adjusted_year(476);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%c", &time);
EXPECT_STREQ_LEN(written, buffer, "Fri Sep 4 16:57:18 0476");
time.tm_wday = 5;
time.tm_mon = 8;
time.tm_mday = 4;
time.tm_hour = 16;
time.tm_min = 57;
time.tm_sec = 18;
time.tm_year = get_adjusted_year(476);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%1c", &time);
EXPECT_STREQ_LEN(written, buffer, "Fri Sep 4 16:57:18 0476");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%24c", &time);
EXPECT_STREQ_LEN(written, buffer, "Fri Sep 4 16:57:18 0476");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%26c", &time);
EXPECT_STREQ_LEN(written, buffer, " Fri Sep 4 16:57:18 0476");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%026c", &time);
EXPECT_STREQ_LEN(written, buffer, " Fri Sep 04 16:57:18 0476");
time.tm_wday = 3;
time.tm_mon = 5;
time.tm_mday = 15;
time.tm_hour = 14;
time.tm_min = 13;
time.tm_sec = 12;
time.tm_year = get_adjusted_year(2011);
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%1c", &time);
EXPECT_STREQ_LEN(written, buffer, "Wed Jun 15 14:13:12 2011");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%24c", &time);
EXPECT_STREQ_LEN(written, buffer, "Wed Jun 15 14:13:12 2011");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%26c", &time);
EXPECT_STREQ_LEN(written, buffer, " Wed Jun 15 14:13:12 2011");
written = LIBC_NAMESPACE::strftime(buffer, sizeof(buffer), "%026c", &time);
EXPECT_STREQ_LEN(written, buffer, " Wed Jun 15 14:13:12 2011");
}
TEST(LlvmLibcStrftimeTest, BufferTooSmall) {
struct tm time;
char tiny_buffer[1];
time.tm_year = get_adjusted_year(2025);
time.tm_mon = 10;
time.tm_mday = 24;
size_t written =
LIBC_NAMESPACE::strftime(tiny_buffer, sizeof(tiny_buffer), "%F", &time);
EXPECT_EQ(written, size_t{0});
char small_buffer[10];
written =
LIBC_NAMESPACE::strftime(small_buffer, sizeof(small_buffer), "%F", &time);
EXPECT_EQ(written, size_t{0});
}