43 {QLatin1String(
"Australia/Darwin"), QLatin1String(
"AUS Central Standard Time")},
44 {QLatin1String(
"Australia/Sydney"), QLatin1String(
"AUS Eastern Standard Time")},
45 {QLatin1String(
"Asia/Kabul"), QLatin1String(
"Afghanistan Standard Time")},
46 {QLatin1String(
"America/Anchorage"), QLatin1String(
"Alaskan Standard Time")},
47 {QLatin1String(
"Asia/Riyadh"), QLatin1String(
"Arab Standard Time")},
48 {QLatin1String(
"Asia/Dubai"), QLatin1String(
"Arabian Standard Time")},
49 {QLatin1String(
"Asia/Baghdad"), QLatin1String(
"Arabic Standard Time")},
50 {QLatin1String(
"America/Buenos_Aires"), QLatin1String(
"Argentina Standard Time")},
51 {QLatin1String(
"Asia/Yerevan"), QLatin1String(
"Armenian Standard Time")},
52 {QLatin1String(
"America/Halifax"), QLatin1String(
"Atlantic Standard Time")},
53 {QLatin1String(
"Asia/Baku"), QLatin1String(
"Azerbaijan Standard Time")},
54 {QLatin1String(
"Atlantic/Azores"), QLatin1String(
"Azores Standard Time")},
55 {QLatin1String(
"America/Regina"), QLatin1String(
"Canada Central Standard Time")},
56 {QLatin1String(
"Atlantic/Cape_Verde"), QLatin1String(
"Cape Verde Standard Time")},
57 {QLatin1String(
"Asia/Yerevan"), QLatin1String(
"Caucasus Standard Time")},
58 {QLatin1String(
"Australia/Adelaide"), QLatin1String(
"Cen. Australia Standard Time")},
59 {QLatin1String(
"America/Guatemala"), QLatin1String(
"Central America Standard Time")},
60 {QLatin1String(
"Asia/Dhaka"), QLatin1String(
"Central Asia Standard Time")},
61 {QLatin1String(
"America/Manaus"), QLatin1String(
"Central Brazilian Standard Time")},
62 {QLatin1String(
"Europe/Budapest"), QLatin1String(
"Central Europe Standard Time")},
63 {QLatin1String(
"Europe/Warsaw"), QLatin1String(
"Central European Standard Time")},
64 {QLatin1String(
"Pacific/Guadalcanal"), QLatin1String(
"Central Pacific Standard Time")},
65 {QLatin1String(
"America/Chicago"), QLatin1String(
"Central Standard Time")},
66 {QLatin1String(
"America/Mexico_City"), QLatin1String(
"Central Standard Time (Mexico)")},
67 {QLatin1String(
"Asia/Shanghai"), QLatin1String(
"China Standard Time")},
68 {QLatin1String(
"Etc/GMT+12"), QLatin1String(
"Dateline Standard Time")},
69 {QLatin1String(
"Africa/Nairobi"), QLatin1String(
"E. Africa Standard Time")},
70 {QLatin1String(
"Australia/Brisbane"), QLatin1String(
"E. Australia Standard Time")},
71 {QLatin1String(
"Europe/Minsk"), QLatin1String(
"E. Europe Standard Time")},
72 {QLatin1String(
"America/Sao_Paulo"), QLatin1String(
"E. South America Standard Time")},
73 {QLatin1String(
"America/New_York"), QLatin1String(
"Eastern Standard Time")},
74 {QLatin1String(
"Africa/Cairo"), QLatin1String(
"Egypt Standard Time")},
75 {QLatin1String(
"Asia/Yekaterinburg"), QLatin1String(
"Ekaterinburg Standard Time")},
76 {QLatin1String(
"Europe/Kiev"), QLatin1String(
"FLE Standard Time")},
77 {QLatin1String(
"Pacific/Fiji"), QLatin1String(
"Fiji Standard Time")},
78 {QLatin1String(
"Europe/London"), QLatin1String(
"GMT Standard Time")},
79 {QLatin1String(
"Europe/Istanbul"), QLatin1String(
"GTB Standard Time")},
80 {QLatin1String(
"Etc/GMT-3"), QLatin1String(
"Georgian Standard Time")},
81 {QLatin1String(
"America/Godthab"), QLatin1String(
"Greenland Standard Time")},
82 {QLatin1String(
"Atlantic/Reykjavik"), QLatin1String(
"Greenwich Standard Time")},
83 {QLatin1String(
"Pacific/Honolulu"), QLatin1String(
"Hawaiian Standard Time")},
84 {QLatin1String(
"Asia/Calcutta"), QLatin1String(
"India Standard Time")},
85 {QLatin1String(
"Asia/Tehran"), QLatin1String(
"Iran Standard Time")},
86 {QLatin1String(
"Asia/Jerusalem"), QLatin1String(
"Israel Standard Time")},
87 {QLatin1String(
"Asia/Amman"), QLatin1String(
"Jordan Standard Time")},
88 {QLatin1String(
"Asia/Seoul"), QLatin1String(
"Korea Standard Time")},
89 {QLatin1String(
"Indian/Mauritius"), QLatin1String(
"Mauritius Standard Time")},
90 {QLatin1String(
"America/Mexico_City"), QLatin1String(
"Mexico Standard Time")},
91 {QLatin1String(
"America/Chihuahua"), QLatin1String(
"Mexico Standard Time 2")},
92 {QLatin1String(
"Atlantic/South_Georgia"), QLatin1String(
"Mid-Atlantic Standard Time")},
93 {QLatin1String(
"Asia/Beirut"), QLatin1String(
"Middle East Standard Time")},
94 {QLatin1String(
"America/Montevideo"), QLatin1String(
"Montevideo Standard Time")},
95 {QLatin1String(
"Africa/Casablanca"), QLatin1String(
"Morocco Standard Time")},
96 {QLatin1String(
"America/Denver"), QLatin1String(
"Mountain Standard Time")},
97 {QLatin1String(
"America/Chihuahua"), QLatin1String(
"Mountain Standard Time (Mexico)")},
98 {QLatin1String(
"Asia/Rangoon"), QLatin1String(
"Myanmar Standard Time")},
99 {QLatin1String(
"Asia/Novosibirsk"), QLatin1String(
"N. Central Asia Standard Time")},
100 {QLatin1String(
"Africa/Windhoek"), QLatin1String(
"Namibia Standard Time")},
101 {QLatin1String(
"Asia/Katmandu"), QLatin1String(
"Nepal Standard Time")},
102 {QLatin1String(
"Pacific/Auckland"), QLatin1String(
"New Zealand Standard Time")},
103 {QLatin1String(
"America/St_Johns"), QLatin1String(
"Newfoundland Standard Time")},
104 {QLatin1String(
"Asia/Irkutsk"), QLatin1String(
"North Asia East Standard Time")},
105 {QLatin1String(
"Asia/Krasnoyarsk"), QLatin1String(
"North Asia Standard Time")},
106 {QLatin1String(
"America/Santiago"), QLatin1String(
"Pacific SA Standard Time")},
107 {QLatin1String(
"America/Los_Angeles"), QLatin1String(
"Pacific Standard Time")},
108 {QLatin1String(
"America/Tijuana"), QLatin1String(
"Pacific Standard Time (Mexico)")},
109 {QLatin1String(
"Asia/Karachi"), QLatin1String(
"Pakistan Standard Time")},
110 {QLatin1String(
"Europe/Paris"), QLatin1String(
"Romance Standard Time")},
111 {QLatin1String(
"Europe/Moscow"), QLatin1String(
"Russian Standard Time")},
112 {QLatin1String(
"Etc/GMT+3"), QLatin1String(
"SA Eastern Standard Time")},
113 {QLatin1String(
"America/Bogota"), QLatin1String(
"SA Pacific Standard Time")},
114 {QLatin1String(
"America/La_Paz"), QLatin1String(
"SA Western Standard Time")},
115 {QLatin1String(
"Asia/Bangkok"), QLatin1String(
"SE Asia Standard Time")},
116 {QLatin1String(
"Pacific/Apia"), QLatin1String(
"Samoa Standard Time")},
117 {QLatin1String(
"Asia/Singapore"), QLatin1String(
"Singapore Standard Time")},
118 {QLatin1String(
"Africa/Johannesburg"), QLatin1String(
"South Africa Standard Time")},
119 {QLatin1String(
"Asia/Colombo"), QLatin1String(
"Sri Lanka Standard Time")},
120 {QLatin1String(
"Asia/Taipei"), QLatin1String(
"Taipei Standard Time")},
121 {QLatin1String(
"Australia/Hobart"), QLatin1String(
"Tasmania Standard Time")},
122 {QLatin1String(
"Asia/Tokyo"), QLatin1String(
"Tokyo Standard Time")},
123 {QLatin1String(
"Pacific/Tongatapu"), QLatin1String(
"Tonga Standard Time")},
124 {QLatin1String(
"Etc/GMT+5"), QLatin1String(
"US Eastern Standard Time")},
125 {QLatin1String(
"America/Phoenix"), QLatin1String(
"US Mountain Standard Time")},
126 {QLatin1String(
"America/Caracas"), QLatin1String(
"Venezuela Standard Time")},
127 {QLatin1String(
"Asia/Vladivostok"), QLatin1String(
"Vladivostok Standard Time")},
128 {QLatin1String(
"Australia/Perth"), QLatin1String(
"W. Australia Standard Time")},
129 {QLatin1String(
"Africa/Lagos"), QLatin1String(
"W. Central Africa Standard Time")},
130 {QLatin1String(
"Europe/Berlin"), QLatin1String(
"W. Europe Standard Time")},
131 {QLatin1String(
"Asia/Tashkent"), QLatin1String(
"West Asia Standard Time")},
132 {QLatin1String(
"Pacific/Port_Moresby"), QLatin1String(
"West Pacific Standard Time")},
133 {QLatin1String(
"Asia/Yakutsk"), QLatin1String(
"Yakutsk Standard Time")}
138 for (
int i = 0; i <
sizeof(
ZoneTbl) /
sizeof(
ZoneTbl[0]); ++i ) {
139 if (
ZoneTbl[i].zoneOlson == name) {
147typedef BOOL (WINAPI *PtrTzSpecificLocalTimeToSystemTime )(LPTIME_ZONE_INFORMATION lpTimeZoneInformation,
156 Q_DISABLE_COPY( HKeyCloser )
158 explicit HKeyCloser( HKEY hk ) : hkey( hk ) {}
159 ~HKeyCloser() { RegCloseKey( hkey ); }
166 SYSTEMTIME StandardDate;
167 SYSTEMTIME DaylightDate;
175 return QString::fromUtf16(
reinterpret_cast<const ushort*
>( str ) );
179 return reinterpret_cast<const TCHAR*
>( str.utf16() );
189 return QString::fromLocal8Bit( str );
193 return str.toLocal8Bit().constData();
202static const TCHAR
timeZonesKey[] = TEXT(
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones");
204 return QDateTime( QDate( st.wYear, st.wMonth, st.wDay ),
205 QTime( st.wHour, st.wMinute, st.wSecond, st.wMilliseconds ) );
209 const QDate d = dt.date();
210 const QTime t = dt.time();
211 const SYSTEMTIME st = {
225 SYSTEMTIME *i_stLocal,
226 SYSTEMTIME *o_stUniversal )
232 QLibrary kernelLib(QLatin1String(
"kernel32"));
247 TIME_ZONE_INFORMATION currentTimeZone;
248 result = GetTimeZoneInformation(¤tTimeZone);
249 if ( result == TIME_ZONE_ID_INVALID ) {
250 kWarning(161) <<
"Getting time zone information failed";
253 result = SetTimeZoneInformation(tz);
255 kWarning(161) <<
"Setting temporary time zone failed";
258 result = SystemTimeToFileTime(i_stLocal, &ft);
260 kWarning(161) <<
"SysteTimeToFileTime failed";
263 result = LocalFileTimeToFileTime(&ft, &ft_utc);
265 kWarning(161) <<
"LocalFileTimeToFileTime failed";
268 result = FileTimeToSystemTime(&ft_utc,o_stUniversal);
270 kWarning(161) <<
"FileTimeToSystemTime failed";
273 result = SetTimeZoneInformation(¤tTimeZone);
275 kWarning(161) <<
"Re-setting time zone information failed";
284static bool get_binary_value( HKEY key,
const TCHAR * value,
void * data, DWORD numData, DWORD * outNumData=0 ) {
285 DWORD size = numData;
286 DWORD type = REG_BINARY;
287 if ( RegQueryValueEx( key, value, 0, &type, (LPBYTE)data, &size ) != ERROR_SUCCESS )
289 assert( type == REG_BINARY );
290 if ( type != REG_BINARY )
297static bool get_string_value( HKEY key,
const TCHAR * value, TCHAR * dest, DWORD destSizeInBytes ) {
298 DWORD size = destSizeInBytes;
301 if ( RegQueryValueEx( key, value, 0, &type, (LPBYTE)dest, &size ) != ERROR_SUCCESS )
304 assert( type == REG_SZ );
305 if ( type != REG_SZ )
317 return caller && caller->
isValid() && dt.isValid() && dt.timeSpec() == spec ;
329 return tz.StandardDate.wMonth != 0 && tz.DaylightDate.wMonth != 0 ;
334 return wdow ? wdow : 7 ;
346 const QDate first( year, month, 1 );
347 const int actualDayOfWeek = first.dayOfWeek();
348 QDate candidate = first.addDays( ( nth - 1 ) * 7 + dayOfWeek - actualDayOfWeek );
349 assert( candidate.dayOfWeek() == dayOfWeek );
351 if ( candidate.month() != month )
352 candidate = candidate.addDays( -7 );
353 assert( candidate.month() == month );
358 assert( st.wYear == 0 );
359 assert( st.wMonth != 0 );
361 QTime( st.wHour, st.wMinute, st.wSecond, st.wMilliseconds ) );
368Transitions
transitions(
const TIME_ZONE_INFORMATION & tz,
int year ) {
369 const Transitions t = {
380 DWORD numSubKeys = 0;
383 if ( RegQueryInfoKey( key, 0, 0, 0, &numSubKeys, 0, 0, 0, 0, 0, 0, 0 ) == ERROR_SUCCESS )
384 for ( DWORD i = 0 ; i < numSubKeys ; ++i ) {
387 if ( RegEnumKeyEx( key, i, name, &nameLen, 0, 0, 0, 0 ) == ERROR_SUCCESS )
400 if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
timeZonesKey, 0, KEY_READ, &timeZones ) == ERROR_SUCCESS )
404 path += TEXT(
"\\" );
406 const HKeyCloser closer( timeZones );
407 Q_FOREACH(
const QString & keyname, keys ) {
409 std::basic_string<TCHAR> keypath(path);
412 if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, keypath.c_str(), 0, KEY_READ, &key ) != ERROR_SUCCESS ) {
413 return standardNames;
416 const HKeyCloser closer( key );
418 TIME_ZONE_INFORMATION tz;
419 get_string_value( key, L
"Std", tz.StandardName,
sizeof( tz.StandardName ) );
424 for (
int i = 0; i <
sizeof(
ZoneTbl) /
sizeof(
ZoneTbl[0]); ++i ) {
425 standardNames <<
ZoneTbl[i].zoneOlson;
428 return standardNames;
434 path += TEXT(
"\\" );
442 if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
timeZonesKey, 0, KEY_READ, &timeZones ) == ERROR_SUCCESS )
445 const HKeyCloser closer( timeZones );
446 Q_FOREACH(
const QString & keyname, keys ) {
448 std::basic_string<TCHAR> keypath(path);
451 if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, keypath.c_str(), 0, KEY_READ, &key ) != ERROR_SUCCESS ) {
455 const HKeyCloser closer( key );
457 TIME_ZONE_INFORMATION tz;
458 get_string_value( key, L
"Std", tz.StandardName,
sizeof( tz.StandardName ) );
471class KSystemTimeZoneSourceWindowsPrivate
474 KSystemTimeZoneSourceWindowsPrivate() {}
475 ~KSystemTimeZoneSourceWindowsPrivate() {}
485 ~KSystemTimeZoneBackendWindows() {}
487 KSystemTimeZoneBackendWindows *
clone()
const;
489 QByteArray type()
const;
491 int offsetAtZoneTime(
const KTimeZone *caller,
const QDateTime &zoneDateTime,
int *secondOffset)
const;
493 int offset(
const KTimeZone *caller, time_t t)
const;
495 bool isDst(
const KTimeZone *caller, time_t t)
const;
501 KSystemTimeZoneDataWindows()
506 TIME_ZONE_INFORMATION _tzi;
509 const TIME_ZONE_INFORMATION & tzi(
int year = 0 )
const { Q_UNUSED( year );
return _tzi; }
513:d( new KSystemTimeZoneSourceWindowsPrivate )
519 KSystemTimeZoneDataWindows* data =
new KSystemTimeZoneDataWindows();
524 if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_READ, &key ) != ERROR_SUCCESS ) {
529 const HKeyCloser closer( key );
538 get_string_value( key, L
"Std", data->_tzi.StandardName,
sizeof( data->_tzi.StandardName ) );
539 get_string_value( key, L
"Dlt", data->_tzi.DaylightName,
sizeof( data->_tzi.DaylightName ) );
545#define COPY( name ) data->_tzi.name = tzi.name
547 COPY( StandardBias );
548 COPY( StandardDate );
549 COPY( DaylightBias );
550 COPY( DaylightDate );
557 return transitions(
static_cast<const KSystemTimeZoneDataWindows*
>( caller->
data(
true) )->tzi( year ), year );
560static bool is_dst(
const TIME_ZONE_INFORMATION & tzi,
const QDateTime & utc,
int year ) {
563 const Transitions trans =
transitions( tzi, year );
564 if ( trans.stdStart < trans.dstStart )
565 return trans.dstStart <= utc || utc < trans.stdStart ;
567 return trans.dstStart <= utc && utc < trans.stdStart ;
573 const int year = utc.date().year();
574 const TIME_ZONE_INFORMATION & tzi =
static_cast<const KSystemTimeZoneDataWindows*
>( caller->
data(
true) )->tzi( year );
575 return is_dst( tzi, utc, year );
582 bias += tz.DaylightBias;
584 bias += tz.StandardBias;
591 const int year = utc.date().year();
592 const TIME_ZONE_INFORMATION & tz =
static_cast<const KSystemTimeZoneDataWindows*
>( caller->
data(
true) )->tzi( year );
598static int difference(
const SYSTEMTIME & st1,
const SYSTEMTIME & st2 ) {
605 assert(caller->
data(
true));
606 const KSystemTimeZoneDataWindows *
const data =
static_cast<const KSystemTimeZoneDataWindows*
>( caller->
data(
true) );
607 const TIME_ZONE_INFORMATION & tz = data->tzi( zone.wYear );
615 if ( secondOffset ) {
618 SYSTEMTIME zoneplus1, zoneminus1;
619 if ( !SystemTimeToTzSpecificLocalTime(
const_cast<LPTIME_ZONE_INFORMATION
>( &tz ),
const_cast<LPSYSTEMTIME
>( &utcplus1 ), &zoneplus1 ) ||
620 !SystemTimeToTzSpecificLocalTime(
const_cast<LPTIME_ZONE_INFORMATION
>( &tz ),
const_cast<LPSYSTEMTIME
>( &utcminus1 ), &zoneminus1 ) )
626 if ( result < *secondOffset )
627 qSwap( result, *secondOffset );
636KSystemTimeZoneBackendWindows * KSystemTimeZoneBackendWindows::clone()
const
638 return new KSystemTimeZoneBackendWindows(*
this);
641QByteArray KSystemTimeZoneBackendWindows::type()
const
643 return "KSystemTimeZoneWindows";
646int KSystemTimeZoneBackendWindows::offsetAtZoneTime(
const KTimeZone *caller,
const QDateTime &zoneDateTime,
int *secondOffset)
const
648 if (!caller->
isValid() || !zoneDateTime.isValid() || zoneDateTime.timeSpec() != Qt::LocalTime)
656int KSystemTimeZoneBackendWindows::offsetAtUtc(
const KTimeZone *caller,
const QDateTime &utcDateTime)
const
658 if (!caller->
isValid() || !utcDateTime.isValid())
665int KSystemTimeZoneBackendWindows::offset(
const KTimeZone *caller, time_t t)
const
672bool KSystemTimeZoneBackendWindows::isDstAtUtc(
const KTimeZone *caller,
const QDateTime &utcDateTime)
const
674 return check_utc( caller, utcDateTime ) &&
is_dst( caller, utcDateTime );
678bool KSystemTimeZoneBackendWindows::isDst(
const KTimeZone *caller, time_t t)
const
684:
KTimeZone(new KSystemTimeZoneBackendWindows(source, name))
KTimeZoneData * parse(const KTimeZone &zone) const
Retrieves and parses the Windows registry information to extract detailed information for one time zo...
KSystemTimeZoneSourceWindows()
Constructs a time zone source.
KSystemTimeZoneWindows(KTimeZoneSource *source, const QString &name)
Creates a time zone.
static QStringList listTimeZones()
Static helper method that lists all availalbe timezones on the system as per the information in the W...
Base backend class for KTimeZone classes.
virtual KTimeZoneBackend * clone() const
Creates a copy of this instance.
Base class for the parsed data returned by a KTimeZoneSource class.
Base class representing a source of time zone information.
Base class representing a time zone.
static const time_t InvalidTime_t
Indicates an invalid time_t value.
const KTimeZoneData * data(bool create=false) const
Returns the detailed parsed data for the time zone.
QString name() const
Returns the name of the time zone.
bool isValid() const
Checks whether the instance is valid.
static QDateTime fromTime_t(time_t t)
Converts a UTC time, measured in seconds since 00:00:00 UTC 1st January 1970 (as returned by time(2))...
static SYSTEMTIME qdatetime_to_systemtime(const QDateTime &dt)
static int effective_offset(const TIME_ZONE_INFORMATION &tz, bool isDst)
static const int MAX_KEY_LENGTH
static QDate find_nth_weekday_in_month_of_year(int nth, int dayOfWeek, int month, int year)
static int qt_dayofweek_to_win_dayofweek(int qdow)
static const TCHAR timeZonesKey[]
LPSYSTEMTIME LPSYSTEMTIME lpUniversalTime
static bool check_prereq(const KTimeZone *caller, const QDateTime &dt, Qt::TimeSpec spec)
static QStringList list_key(HKEY key)
static std::basic_string< TCHAR > pathFromZoneName(const KTimeZone &zone)
static bool check_utc(const KTimeZone *caller, const QDateTime &dt)
static QStringList list_standard_names()
static bool check_local(const KTimeZone *caller, const QDateTime &dt)
static const ZoneKey ZoneTbl[]
static QString getWinZoneName(const QString &name)
static bool is_dst(const TIME_ZONE_INFORMATION &tzi, const QDateTime &utc, int year)
static int win_dayofweek_to_qt_dayofweek(int wdow)
static int offset_at_zone_time(const KTimeZone *caller, const SYSTEMTIME &zone, int *secondOffset)
static int difference(const SYSTEMTIME &st1, const SYSTEMTIME &st2)
static bool TzSpecificLocalTimeToSystemTime_Portable(TIME_ZONE_INFORMATION *tz, SYSTEMTIME *i_stLocal, SYSTEMTIME *o_stUniversal)
static bool get_string_value(HKEY key, const TCHAR *value, TCHAR *dest, DWORD destSizeInBytes)
static QDateTime transition(const SYSTEMTIME &st, int year)
static std::basic_string< TCHAR > qstring_to_tcharstring(const QString &str)
static const TCHAR * qstring_to_tchar(const QString &str)
typedef BOOL(WINAPI *PtrTzSpecificLocalTimeToSystemTime)(LPTIME_ZONE_INFORMATION lpTimeZoneInformation
static int offset_at_utc(const KTimeZone *caller, const QDateTime &utc)
static bool get_binary_value(HKEY key, const TCHAR *value, void *data, DWORD numData, DWORD *outNumData=0)
static QString tchar_to_qstring(const TCHAR *str)
Transitions transitions(const TIME_ZONE_INFORMATION &tz, int year)
static bool has_transition(const TIME_ZONE_INFORMATION &tz)
static QDateTime systemtime_to_qdatetime(const SYSTEMTIME &st)
static PtrTzSpecificLocalTimeToSystemTime pTzSpecificLocalTimeToSystemTime