blob: 79109c3915183cd6a80a587e31055e43571e8993 [file] [log] [blame]
// { dg-do run { target c++20 } }
// { dg-require-namedlocale "aa_DJ.UTF-8" }
// { dg-require-namedlocale "ar_SA.UTF-8" }
// { dg-require-namedlocale "ca_AD.UTF-8" }
// { dg-require-namedlocale "az_IR.UTF-8" }
// { dg-require-namedlocale "my_MM.UTF-8" }
#include <chrono>
#include <locale>
#include <span>
#include <testsuite_hooks.h>
template<typename ChronoType>
void
test_locale_formats(const ChronoType& t,
std::span<const char* const> test_specifiers)
{
const char *test_locales[] = {
"aa_DJ.UTF-8",
"ar_SA.UTF-8",
"ca_AD.UTF-8",
"az_IR.UTF-8",
"my_MM.UTF-8",
};
auto format_args = std::make_format_args(t);
for (auto locale_name : test_locales)
{
std::locale loc(locale_name);
for (auto specifier : test_specifiers)
{
auto s = std::vformat(loc, specifier, format_args);
VERIFY( !s.empty() );
}
}
}
void
test_locale_formats()
{
using namespace std::chrono;
const char* test_specifiers[] = {
"{:L%x}", "{:L%Ex}",
"{:L%c}", "{:L%Ec}",
"{:L%X}", "{:L%EX}",
"{:L%r}",
};
auto date_time_specifiers = std::span(test_specifiers);
auto date_specifiers = date_time_specifiers.subspan(0, 2);
auto time_specifiers = date_time_specifiers.subspan(4);
auto ymd = 2020y/November/12d;
test_locale_formats(ymd, date_specifiers);
auto tod = 25h + 10min + 12s;
test_locale_formats(tod, time_specifiers);
auto tp = sys_days(ymd) + tod;
test_locale_formats(tp, date_time_specifiers);
}
#include <stdlib.h>
#include <time.h>
extern "C++" int tzset(int);
template<typename T = void>
void maybe_set_tz()
{
#ifdef _GLIBCXX_HAVE_SETENV
// True if a function 'T tzset()' has been declared.
if constexpr (requires (T (*p)()) { p = &tzset; })
{
setenv("TZ", "GMT0", 1);
tzset(); // Set C library's global time zone to GMT0
}
#endif
}
void
test_c_zoned()
{
#if _GLIBCXX_USE_CXX11_ABI
maybe_set_tz();
using namespace std::chrono;
auto time = sys_days(2025y/March/19) + 15h;
zoned_time z("America/New_York", time);
auto s = std::format(std::locale("aa_DJ.UTF-8"), "{:L%c}", z);
VERIFY( s.find("11:00") != s.npos );
// We should not print an incorrect time zone.
VERIFY( s.find("GMT") == s.npos );
VERIFY( s.find("UTC") == s.npos );
#ifdef _GLIBCXX_HAVE_STRUCT_TM_TM_ZONE
// When tm.tm_zone is supported, we do print the correct time zone.
VERIFY( s.find(z.get_info().abbrev) != s.npos );
#endif
#endif
}
void
test_c_local()
{
maybe_set_tz();
std::locale("aa_DJ.UTF-8");
using namespace std::chrono;
auto time = local_days(2025y/March/19) + 11h;
auto s = std::format(std::locale("aa_DJ.UTF-8"), "{:L%c}", time);
// __builtin_printf("%s\n", s.c_str()); return;
VERIFY( s.find("11:00") != s.npos );
// We should not print any time zone.
VERIFY( s.find("GMT") == s.npos );
VERIFY( s.find("UTC") == s.npos );
#if _GLIBCXX_USE_CXX11_ABI
zoned_time z(system_clock::now());
VERIFY( s.find(z.get_info().abbrev) == s.npos );
#endif
}
int main()
{
test_locale_formats();
test_c_zoned();
test_c_local();
}