Merge pull request #4099 from yunusshaikh7/fix/libc-asctime-years-before-1900-windows
fix(libc): format years before 1900 in asctime on Windows
This commit is contained in:
commit
256cc9f976
|
|
@ -17,6 +17,9 @@
|
|||
|
||||
namespace {
|
||||
|
||||
constexpr const char* WEEKDAY_NAMES[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
||||
constexpr const char* MONTH_NAMES[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
constexpr std::size_t ASCTIME_SIZE = sizeof("Sun Jan-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n");
|
||||
constexpr std::int64_t SECONDS_PER_DAY = 86400;
|
||||
constexpr std::int64_t DAYS_FROM_MARCH_TO_YEAR_END = 306;
|
||||
|
||||
|
|
@ -324,8 +327,12 @@ size_t APS5_VABI libc_strftime_nid_postfix(char* str, size_t count, const char*
|
|||
}
|
||||
|
||||
char* APS5_VABI asctime_nid_postfix(const GuestTm* timeptr) {
|
||||
const std::tm host = toHostTm(*timeptr);
|
||||
return std::asctime(&host);
|
||||
static thread_local char result[ASCTIME_SIZE];
|
||||
const char* weekday = timeptr->tm_wday >= 0 && timeptr->tm_wday < 7 ? WEEKDAY_NAMES[timeptr->tm_wday] : "???";
|
||||
const char* month = timeptr->tm_mon >= 0 && timeptr->tm_mon < 12 ? MONTH_NAMES[timeptr->tm_mon] : "???";
|
||||
std::snprintf(result, sizeof(result), "%s %s%3d %.2d:%.2d:%.2d %lld\n", weekday, month, timeptr->tm_mday,
|
||||
timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec, 1900LL + timeptr->tm_year);
|
||||
return result;
|
||||
}
|
||||
|
||||
char* APS5_VABI ctime_nid_postfix(const int64_t* timer) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ GuestTm* APS5_VABI libc_localtime_nid_postfix(const std::int64_t*);
|
|||
GuestTm* APS5_VABI localtime_nid_postfix(const std::int64_t*);
|
||||
GuestTm* APS5_VABI gmtime_s_nid_postfix(const std::int64_t*, GuestTm*);
|
||||
GuestTm* APS5_VABI localtime_s_nid_postfix(const std::int64_t*, GuestTm*);
|
||||
char* APS5_VABI asctime_nid_postfix(const GuestTm*);
|
||||
std::int64_t APS5_VABI mktime_nid_postfix(GuestTm*);
|
||||
std::size_t APS5_VABI strftime_nid_postfix(char*, std::size_t, const char*, const GuestTm*);
|
||||
void APS5_VABI tzset_nid_postfix(void);
|
||||
|
|
@ -68,6 +69,17 @@ static void CheckConcurrent(Converter convert, BufferedConverter buffered, const
|
|||
Require(convert(&invalid) == nullptr, "Unrepresentable time was accepted");
|
||||
}
|
||||
|
||||
static GuestTm UtcTime(std::int64_t timer) {
|
||||
GuestTm utc{};
|
||||
Require(gmtime_s_nid_postfix(&timer, &utc) == &utc, "UTC conversion failed");
|
||||
return utc;
|
||||
}
|
||||
|
||||
static void CheckAsctime(const GuestTm& brokenDown, const char* expected) {
|
||||
const char* text = asctime_nid_postfix(&brokenDown);
|
||||
Require(text != nullptr && std::strcmp(text, expected) == 0, "asctime did not format the broken-down time");
|
||||
}
|
||||
|
||||
struct UtcCase {
|
||||
std::int64_t timer;
|
||||
int year;
|
||||
|
|
@ -249,6 +261,14 @@ int main() {
|
|||
GuestTm scratch{};
|
||||
Require(gmtime_s_nid_postfix(&underflow, &scratch) == nullptr, "Unrepresentable negative time was accepted");
|
||||
|
||||
CheckAsctime(UtcTime(0), "Thu Jan 1 00:00:00 1970\n");
|
||||
CheckAsctime(UtcTime(-2208988801), "Sun Dec 31 23:59:59 1899\n");
|
||||
CheckAsctime(UtcTime(-30610224000), "Wed Jan 1 00:00:00 1000\n");
|
||||
GuestTm pastMonthEnd = UtcTime(983404800);
|
||||
pastMonthEnd.tm_mon = 1;
|
||||
pastMonthEnd.tm_mday = 29;
|
||||
CheckAsctime(pastMonthEnd, "Thu Feb 29 00:00:00 2001\n");
|
||||
|
||||
const std::int64_t epoch = 0;
|
||||
GuestTm local{};
|
||||
std::memset(&local, 0xAA, sizeof(local));
|
||||
|
|
|
|||
Loading…
Reference in New Issue