#include "timezone_helper.h" #include #include #include #include #include namespace radiantwave::timezone { namespace { static std::mutex g_tz_mutex; const std::vector G_COUNTRIES = { { "United States", { {"Eastern Time (New York, Miami)", "America/New_York"}, {"Central Time (Chicago, Dallas)", "America/Chicago"}, {"Mountain Time (Denver)", "America/Denver"}, {"Pacific Time (Los Angeles, Seattle)", "America/Los_Angeles"}, {"Alaska Time (Anchorage)", "America/Anchorage"}, {"Hawaii Time (Honolulu)", "Pacific/Honolulu"}, {"Arizona (No DST)", "America/Phoenix"}, {"Indiana (Indianapolis)", "America/Indiana/Indianapolis"} } }, { "Canada", { {"Eastern Time (Toronto)", "America/Toronto"}, {"Central Time (Winnipeg)", "America/Winnipeg"}, {"Mountain Time (Edmonton)", "America/Edmonton"}, {"Pacific Time (Vancouver)", "America/Vancouver"}, {"Atlantic Time (Halifax)", "America/Halifax"}, {"Newfoundland Time (St. Johns)", "America/St_Johns"} } }, { "United Kingdom & Ireland", { {"London / Dublin (GMT/BST)", "Europe/London"} } }, { "Australia", { {"Eastern Time (Sydney, Melbourne)", "Australia/Sydney"}, {"Central Time (Adelaide)", "Australia/Adelaide"}, {"Western Time (Perth)", "Australia/Perth"}, {"Queensland (Brisbane)", "Australia/Brisbane"}, {"Northern Territory (Darwin)", "Australia/Darwin"} } }, { "Europe (Mainland)", { {"Central European Time (Berlin, Paris, Rome)", "Europe/Berlin"}, {"Western European Time (Lisbon, Amsterdam)", "Europe/Paris"}, {"Eastern European Time (Athens, Helsinki)", "Europe/Helsinki"} } }, { "Japan & East Asia", { {"Japan Standard Time (Tokyo)", "Asia/Tokyo"}, {"China Standard Time (Beijing, Shanghai)", "Asia/Shanghai"}, {"Hong Kong Time", "Asia/Hong_Kong"}, {"Korea Standard Time (Seoul)", "Asia/Seoul"}, {"Singapore Time", "Asia/Singapore"} } }, { "India & South Asia", { {"India Standard Time (Kolkata, Mumbai)", "Asia/Kolkata"} } }, { "Latin America", { {"Brazil (Sao Paulo)", "America/Sao_Paulo"}, {"Mexico (Mexico City)", "America/Mexico_City"}, {"Argentina (Buenos Aires)", "America/Argentina/Buenos_Aires"} } }, { "Coordinated Universal Time", { {"UTC (Universal Time)", "UTC"} } } }; } // anonymous namespace const std::vector& getStandardTimeZones() { return G_COUNTRIES; } std::string formatUtcToTimezone(time_t utc_time, const std::string& iana_code, const std::string& format) { std::lock_guard lock(g_tz_mutex); const char* old_tz = std::getenv("TZ"); std::string old_tz_str = old_tz ? old_tz : ""; // Set target timezone temporarily if (!iana_code.empty()) { setenv("TZ", iana_code.c_str(), 1); } else { setenv("TZ", "UTC", 1); } tzset(); struct tm tm_buf; #if defined(_WIN32) localtime_s(&tm_buf, &utc_time); #else localtime_r(&utc_time, &tm_buf); #endif char buf[128]; std::strftime(buf, sizeof(buf), format.c_str(), &tm_buf); // Restore original process TZ if (!old_tz_str.empty()) { setenv("TZ", old_tz_str.c_str(), 1); } else { unsetenv("TZ"); } tzset(); return std::string(buf); } std::string getUtcTimestampIso() { time_t now = std::time(nullptr); struct tm gmt_buf; #if defined(_WIN32) gmtime_s(&gmt_buf, &now); #else gmtime_r(&now, &gmt_buf); #endif char buf[64]; std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S UTC", &gmt_buf); return std::string(buf); } } // namespace radiantwave::timezone