summaryrefslogtreecommitdiffstats
path: root/intl/icu/source/i18n/wintzimpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'intl/icu/source/i18n/wintzimpl.cpp')
-rw-r--r--intl/icu/source/i18n/wintzimpl.cpp161
1 files changed, 161 insertions, 0 deletions
diff --git a/intl/icu/source/i18n/wintzimpl.cpp b/intl/icu/source/i18n/wintzimpl.cpp
new file mode 100644
index 0000000000..8f2961f8f0
--- /dev/null
+++ b/intl/icu/source/i18n/wintzimpl.cpp
@@ -0,0 +1,161 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+********************************************************************************
+* Copyright (C) 2009-2013, International Business Machines
+* Corporation and others. All Rights Reserved.
+********************************************************************************
+*
+* File WINTZIMPL.CPP
+*
+********************************************************************************
+*/
+
+#include "unicode/utypes.h"
+
+#if U_PLATFORM_USES_ONLY_WIN32_API && !UCONFIG_NO_FORMATTING
+
+#include "wintzimpl.h"
+
+#include "unicode/unistr.h"
+#include "unicode/timezone.h"
+#include "unicode/basictz.h"
+#include "putilimp.h"
+#include "uassert.h"
+#include "cmemory.h"
+
+#ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+# define VC_EXTRALEAN
+# define NOUSER
+# define NOSERVICE
+# define NOIME
+# define NOMCX
+
+#include <windows.h>
+
+U_NAMESPACE_USE
+
+static UBool getSystemTimeInformation(TimeZone *tz, SYSTEMTIME &daylightDate, SYSTEMTIME &standardDate, int32_t &bias, int32_t &daylightBias, int32_t &standardBias) {
+ UErrorCode status = U_ZERO_ERROR;
+ UBool result = true;
+ BasicTimeZone *btz = (BasicTimeZone*)tz; // we should check type
+ InitialTimeZoneRule *initial = nullptr;
+ AnnualTimeZoneRule *std = nullptr, *dst = nullptr;
+
+ btz->getSimpleRulesNear(uprv_getUTCtime(), initial, std, dst, status);
+ if (U_SUCCESS(status)) {
+ if (std == nullptr || dst == nullptr) {
+ bias = -1 * (initial->getRawOffset()/60000);
+ standardBias = 0;
+ daylightBias = 0;
+ // Do not use DST. Set 0 to all stadardDate/daylightDate fields
+ standardDate.wYear = standardDate.wMonth = standardDate.wDayOfWeek = standardDate.wDay =
+ standardDate.wHour = standardDate.wMinute = standardDate.wSecond = standardDate.wMilliseconds = 0;
+ daylightDate.wYear = daylightDate.wMonth = daylightDate.wDayOfWeek = daylightDate.wDay =
+ daylightDate.wHour = daylightDate.wMinute = daylightDate.wSecond = daylightDate.wMilliseconds = 0;
+ } else {
+ U_ASSERT(std->getRule()->getDateRuleType() == DateTimeRule::DOW);
+ U_ASSERT(dst->getRule()->getDateRuleType() == DateTimeRule::DOW);
+
+ bias = -1 * (std->getRawOffset()/60000);
+ standardBias = 0;
+ daylightBias = -1 * (dst->getDSTSavings()/60000);
+ // Always use DOW type rule
+ int32_t hour, min, sec, mil;
+ standardDate.wYear = 0;
+ standardDate.wMonth = static_cast<WORD>(std->getRule()->getRuleMonth()) + 1;
+ standardDate.wDay = static_cast<WORD>(std->getRule()->getRuleWeekInMonth());
+ if (standardDate.wDay < 0) {
+ standardDate.wDay = 5;
+ }
+ standardDate.wDayOfWeek = static_cast<WORD>(std->getRule()->getRuleDayOfWeek()) - 1;
+
+ mil = std->getRule()->getRuleMillisInDay();
+ hour = mil/3600000;
+ mil %= 3600000;
+ min = mil/60000;
+ mil %= 60000;
+ sec = mil/1000;
+ mil %= 1000;
+
+ standardDate.wHour = static_cast<WORD>(hour);
+ standardDate.wMinute = static_cast<WORD>(min);
+ standardDate.wSecond = static_cast<WORD>(sec);
+ standardDate.wMilliseconds = static_cast<WORD>(mil);
+
+ daylightDate.wYear = 0;
+ daylightDate.wMonth = static_cast<WORD>(dst->getRule()->getRuleMonth()) + 1;
+ daylightDate.wDay = static_cast<WORD>(dst->getRule()->getRuleWeekInMonth());
+ if (daylightDate.wDay < 0) {
+ daylightDate.wDay = 5;
+ }
+ daylightDate.wDayOfWeek = static_cast<WORD>(dst->getRule()->getRuleDayOfWeek()) - 1;
+
+ mil = dst->getRule()->getRuleMillisInDay();
+ hour = mil/3600000;
+ mil %= 3600000;
+ min = mil/60000;
+ mil %= 60000;
+ sec = mil/1000;
+ mil %= 1000;
+
+ daylightDate.wHour = static_cast<WORD>(hour);
+ daylightDate.wMinute = static_cast<WORD>(min);
+ daylightDate.wSecond = static_cast<WORD>(sec);
+ daylightDate.wMilliseconds = static_cast<WORD>(mil);
+ }
+ } else {
+ result = false;
+ }
+
+ delete initial;
+ delete std;
+ delete dst;
+
+ return result;
+}
+
+static UBool getWindowsTimeZoneInfo(TIME_ZONE_INFORMATION *zoneInfo, const char16_t *icuid, int32_t length) {
+ UBool result = false;
+ UnicodeString id = UnicodeString(icuid, length);
+ TimeZone *tz = TimeZone::createTimeZone(id);
+
+ if (tz != nullptr) {
+ int32_t bias;
+ int32_t daylightBias;
+ int32_t standardBias;
+ SYSTEMTIME daylightDate;
+ SYSTEMTIME standardDate;
+
+ if (getSystemTimeInformation(tz, daylightDate, standardDate, bias, daylightBias, standardBias)) {
+ uprv_memset(zoneInfo, 0, sizeof(TIME_ZONE_INFORMATION)); // We do not set standard/daylight names, so nullify first.
+ zoneInfo->Bias = bias;
+ zoneInfo->DaylightBias = daylightBias;
+ zoneInfo->StandardBias = standardBias;
+ zoneInfo->DaylightDate = daylightDate;
+ zoneInfo->StandardDate = standardDate;
+
+ result = true;
+ }
+ }
+
+ return result;
+}
+
+/*
+ * Given the timezone icuid, fill in zoneInfo by calling auxiliary functions that creates a timezone and extract the
+ * information to put into zoneInfo. This includes bias and standard time date and daylight saving date.
+ */
+U_CAPI UBool U_EXPORT2
+uprv_getWindowsTimeZoneInfo(TIME_ZONE_INFORMATION *zoneInfo, const char16_t *icuid, int32_t length)
+{
+ if (getWindowsTimeZoneInfo(zoneInfo, icuid, length)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+#endif