Add conversion functions for QTimeZone and CFTimeZone/NSTimeZone

Change-Id: I3a2e18d69577296bf612e13e40414bce1daa6a71
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Jake Petroules 2017-01-05 16:28:53 -08:00
parent decab46c23
commit 4b507e8257
7 changed files with 174 additions and 7 deletions

View File

@ -46,6 +46,13 @@
#include <QtCore/qbytearray.h>
#include <QtCore/qrect.h>
#if QT_CONFIG(timezone) && !defined(QT_NO_SYSTEMLOCALE)
#include <QtCore/qtimezone.h>
#include <QtCore/private/qtimezoneprivate_p.h>
#include <QtCore/private/qcore_mac_p.h>
#endif
#import <CoreFoundation/CoreFoundation.h>
#import <Foundation/Foundation.h>
#if defined(QT_PLATFORM_UIKIT)
@ -422,6 +429,67 @@ NSDate *QDateTime::toNSDate() const
// ----------------------------------------------------------------------------
#if QT_CONFIG(timezone) && !defined(QT_NO_SYSTEMLOCALE)
/*!
\since 5.9
Constructs a new QTimeZone containing a copy of the CFTimeZone \a timeZone.
\sa toCFTimeZone()
*/
QTimeZone QTimeZone::fromCFTimeZone(CFTimeZoneRef timeZone)
{
if (!timeZone)
return QTimeZone();
return QTimeZone(QString::fromCFString(CFTimeZoneGetName(timeZone)).toLatin1());
}
/*!
\since 5.9
Creates a CFTimeZone from a QTimeZone. The caller owns the CFTimeZone object
and is responsible for releasing it.
\sa fromCFTimeZone()
*/
CFTimeZoneRef QTimeZone::toCFTimeZone() const
{
#ifndef QT_NO_DYNAMIC_CAST
Q_ASSERT(dynamic_cast<const QMacTimeZonePrivate *>(d.data()));
#endif
const QMacTimeZonePrivate *p = static_cast<const QMacTimeZonePrivate *>(d.data());
return reinterpret_cast<CFTimeZoneRef>([p->nsTimeZone() copy]);
}
/*!
\since 5.9
Constructs a new QTimeZone containing a copy of the NSTimeZone \a timeZone.
\sa toNSTimeZone()
*/
QTimeZone QTimeZone::fromNSTimeZone(const NSTimeZone *timeZone)
{
if (!timeZone)
return QTimeZone();
return QTimeZone(QString::fromNSString(timeZone.name).toLatin1());
}
/*!
\since 5.9
Creates an NSTimeZone from a QTimeZone. The NSTimeZone object is autoreleased.
\sa fromNSTimeZone()
*/
NSTimeZone *QTimeZone::toNSTimeZone() const
{
return [static_cast<NSTimeZone *>(toCFTimeZone()) autorelease];
}
#endif
// ----------------------------------------------------------------------------
/*!
\since 5.8

View File

@ -47,6 +47,11 @@
QT_REQUIRE_CONFIG(timezone);
#if (defined(Q_OS_DARWIN) || defined(Q_QDOC)) && !defined(QT_NO_SYSTEMLOCALE)
Q_FORWARD_DECLARE_CF_TYPE(CFTimeZone);
Q_FORWARD_DECLARE_OBJC_CLASS(NSTimeZone);
#endif
QT_BEGIN_NAMESPACE
class QTimeZonePrivate;
@ -142,6 +147,13 @@ public:
static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId,
QLocale::Country country);
#if (defined(Q_OS_DARWIN) || defined(Q_QDOC)) && !defined(QT_NO_SYSTEMLOCALE)
static QTimeZone fromCFTimeZone(CFTimeZoneRef timeZone);
CFTimeZoneRef toCFTimeZone() const Q_DECL_CF_RETURNS_RETAINED;
static QTimeZone fromNSTimeZone(const NSTimeZone *timeZone);
NSTimeZone *toNSTimeZone() const Q_DECL_NS_RETURNS_AUTORELEASED;
#endif
private:
QTimeZone(QTimeZonePrivate &dd);
#ifndef QT_NO_DATASTREAM

View File

@ -273,4 +273,9 @@ QList<QByteArray> QMacTimeZonePrivate::availableTimeZoneIds() const
return list;
}
NSTimeZone *QMacTimeZonePrivate::nsTimeZone() const
{
return m_nstz;
}
QT_END_NAMESPACE

View File

@ -60,13 +60,9 @@
#include <unicode/ucal.h>
#endif
#ifdef Q_OS_MAC
#ifdef __OBJC__
@class NSTimeZone;
#else
class NSTimeZone;
#endif // __OBJC__
#endif // Q_OS_MAC
#ifdef Q_OS_DARWIN
Q_FORWARD_DECLARE_OBJC_CLASS(NSTimeZone);
#endif // Q_OS_DARWIN
#ifdef Q_OS_WIN
#include <qt_windows.h>
@ -380,6 +376,8 @@ public:
QList<QByteArray> availableTimeZoneIds() const Q_DECL_OVERRIDE;
NSTimeZone *nsTimeZone() const;
private:
void init(const QByteArray &zoneId);

View File

@ -5,3 +5,8 @@ SOURCES = tst_qtimezone.cpp
qtConfig(icu) {
DEFINES += QT_USE_ICU
}
darwin {
OBJECTIVE_SOURCES += tst_qtimezone_darwin.mm
LIBS += -framework Foundation
}

View File

@ -56,6 +56,7 @@ private slots:
void icuTest();
void tzTest();
void macTest();
void darwinTypes();
void winTest();
private:
@ -955,6 +956,16 @@ void tst_QTimeZone::macTest()
#endif // Q_OS_MAC
}
void tst_QTimeZone::darwinTypes()
{
#ifndef Q_OS_DARWIN
QSKIP("This is an Apple-only test");
#else
extern void tst_QTimeZone_darwinTypes(); // in tst_qtimezone_darwin.mm
tst_QTimeZone_darwinTypes();
#endif
}
void tst_QTimeZone::winTest()
{
#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_WIN)

View File

@ -0,0 +1,68 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore/QTimeZone>
#include <QtTest/QtTest>
#include <CoreFoundation/CoreFoundation.h>
#include <Foundation/Foundation.h>
void tst_QTimeZone_darwinTypes()
{
#if !defined(QT_NO_SYSTEMLOCALE)
// QTimeZone <-> CFTimeZone
{
QTimeZone qtTimeZone("America/Los_Angeles");
const CFTimeZoneRef cfTimeZone = qtTimeZone.toCFTimeZone();
QCOMPARE(QTimeZone::fromCFTimeZone(cfTimeZone), qtTimeZone);
CFRelease(cfTimeZone);
}
{
CFTimeZoneRef cfTimeZone = CFTimeZoneCreateWithName(kCFAllocatorDefault,
CFSTR("America/Los_Angeles"), false);
const QTimeZone qtTimeZone = QTimeZone::fromCFTimeZone(cfTimeZone);
QVERIFY(CFEqual(qtTimeZone.toCFTimeZone(), cfTimeZone));
CFRelease(cfTimeZone);
}
// QTimeZone <-> NSTimeZone
{
NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
QTimeZone qtTimeZone("America/Los_Angeles");
const NSTimeZone *nsTimeZone = qtTimeZone.toNSTimeZone();
QCOMPARE(QTimeZone::fromNSTimeZone(nsTimeZone), qtTimeZone);
[autoreleasepool release];
}
{
NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
NSTimeZone *nsTimeZone = [NSTimeZone timeZoneWithName:@"America/Los_Angeles"];
const QTimeZone qtTimeZone = QTimeZone::fromNSTimeZone(nsTimeZone);
QVERIFY([qtTimeZone.toNSTimeZone() isEqual:nsTimeZone]);
[autoreleasepool release];
}
#endif
}