#include "absl/base/config.h"
#include "absl/time/internal/cctz/include/cctz/time_zone.h"
#if defined(__ANDROID__)
#include <sys/system_properties.h>
#endif
#if defined(__APPLE__)
#include <CoreFoundation/CFTimeZone.h>
#include <vector>
#endif
#if defined(__Fuchsia__)
#include <fuchsia/intl/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/fdio/directory.h>
#include <zircon/types.h>
#endif
#if defined(_WIN32)
#include <sdkddkver.h>
#if ((defined(_WIN32_WINNT_WIN10) && !defined(__MINGW32__)) || \
(defined(NTDDI_WIN10_NI) && NTDDI_VERSION >= NTDDI_WIN10_NI)) && \
(_WIN32_WINNT >= _WIN32_WINNT_WINXP)
#define USE_WIN32_LOCAL_TIME_ZONE
#include <roapi.h>
#include <tchar.h>
#include <wchar.h>
#include <windows.globalization.h>
#include <windows.h>
#endif
#endif
#include <cstdlib>
#include <cstring>
#include <string>
#include "time_zone_fixed.h"
#include "time_zone_impl.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace time_internal {
namespace cctz {
namespace {
#if defined(USE_WIN32_LOCAL_TIME_ZONE)
std::string win32_local_time_zone(const HMODULE combase) {
std::string result;
const auto ro_activate_instance =
reinterpret_cast<decltype(&RoActivateInstance)>(
GetProcAddress(combase, "RoActivateInstance"));
if (!ro_activate_instance) {
return result;
}
const auto windows_create_string_reference =
reinterpret_cast<decltype(&WindowsCreateStringReference)>(
GetProcAddress(combase, "WindowsCreateStringReference"));
if (!windows_create_string_reference) {
return result;
}
const auto windows_delete_string =
reinterpret_cast<decltype(&WindowsDeleteString)>(
GetProcAddress(combase, "WindowsDeleteString"));
if (!windows_delete_string) {
return result;
}
const auto windows_get_string_raw_buffer =
reinterpret_cast<decltype(&WindowsGetStringRawBuffer)>(
GetProcAddress(combase, "WindowsGetStringRawBuffer"));
if (!windows_get_string_raw_buffer) {
return result;
}
HSTRING calendar_class_id;
HSTRING_HEADER calendar_class_id_header;
HRESULT hr = windows_create_string_reference(
RuntimeClass_Windows_Globalization_Calendar,
sizeof(RuntimeClass_Windows_Globalization_Calendar) / sizeof(wchar_t) - 1,
&calendar_class_id_header, &calendar_class_id);
if (FAILED(hr)) {
return result;
}
IInspectable* calendar;
hr = ro_activate_instance(calendar_class_id, &calendar);
if (FAILED(hr)) {
return result;
}
ABI::Windows::Globalization::ITimeZoneOnCalendar* time_zone;
hr = calendar->QueryInterface(IID_PPV_ARGS(&time_zone));
if (FAILED(hr)) {
calendar->Release();
return result;
}
HSTRING tz_hstr;
hr = time_zone->GetTimeZone(&tz_hstr);
if (SUCCEEDED(hr)) {
UINT32 wlen;
const PCWSTR tz_wstr = windows_get_string_raw_buffer(tz_hstr, &wlen);
if (tz_wstr) {
const int size =
WideCharToMultiByte(CP_UTF8, 0, tz_wstr, static_cast<int>(wlen),
nullptr, 0, nullptr, nullptr);
result.resize(static_cast<size_t>(size));
WideCharToMultiByte(CP_UTF8, 0, tz_wstr, static_cast<int>(wlen),
&result[0], size, nullptr, nullptr);
}
windows_delete_string(tz_hstr);
}
time_zone->Release();
calendar->Release();
return result;
}
#endif
}
std::string time_zone::name() const { … }
time_zone::absolute_lookup time_zone::lookup(
const time_point<seconds>& tp) const { … }
time_zone::civil_lookup time_zone::lookup(const civil_second& cs) const { … }
bool time_zone::next_transition(const time_point<seconds>& tp,
civil_transition* trans) const { … }
bool time_zone::prev_transition(const time_point<seconds>& tp,
civil_transition* trans) const { … }
std::string time_zone::version() const { … }
std::string time_zone::description() const { … }
const time_zone::Impl& time_zone::effective_impl() const { … }
bool load_time_zone(const std::string& name, time_zone* tz) { … }
time_zone utc_time_zone() { … }
time_zone fixed_time_zone(const seconds& offset) { … }
time_zone local_time_zone() { … }
}
}
ABSL_NAMESPACE_END
}