Files
radiantwave/src/timezone_helper.cpp
T
2026-08-07 14:51:41 -05:00

151 lines
4.1 KiB
C++

#include "timezone_helper.h"
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <mutex>
#include <sstream>
namespace radiantwave::timezone {
namespace {
static std::mutex g_tz_mutex;
const std::vector<CountryTimeZones> 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<CountryTimeZones>& getStandardTimeZones() {
return G_COUNTRIES;
}
std::string formatUtcToTimezone(time_t utc_time, const std::string& iana_code, const std::string& format) {
std::lock_guard<std::mutex> 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