summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qlocale.cpp137
-rw-r--r--src/corelib/tools/qlocale_p.h3
-rw-r--r--tests/auto/corelib/tools/qlocale/tst_qlocale.cpp100
3 files changed, 163 insertions, 77 deletions
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index e8e4c9ad67..060b220a4a 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -1574,7 +1574,7 @@ QString QLocale::toString(qulonglong i) const
QString QLocale::toString(const QDate &date, const QString &format) const
{
- return d->dateTimeToString(format, &date, 0, this);
+ return d->dateTimeToString(format, QDateTime(), date, QTime(), this);
}
/*!
@@ -1618,33 +1618,6 @@ static bool timeFormatContainsAP(const QString &format)
return false;
}
-static QString timeZone()
-{
-#if defined(Q_OS_WINCE)
- TIME_ZONE_INFORMATION info;
- DWORD res = GetTimeZoneInformation(&info);
- if (res == TIME_ZONE_ID_UNKNOWN)
- return QString();
- return QString::fromWCharArray(info.StandardName);
-#elif defined(Q_OS_WIN)
- _tzset();
-# if defined(_MSC_VER) && _MSC_VER >= 1400
- size_t returnSize = 0;
- char timeZoneName[512];
- if (_get_tzname(&returnSize, timeZoneName, 512, 1))
- return QString();
- return QString::fromLocal8Bit(timeZoneName);
-# else
- return QString::fromLocal8Bit(_tzname[1]);
-# endif
-#elif defined(Q_OS_VXWORKS)
- return QString();
-#else
- tzset();
- return QString::fromLocal8Bit(tzname[1]);
-#endif
-}
-
/*!
Returns a localized string representation of the given \a time according
to the specified \a format.
@@ -1652,7 +1625,7 @@ static QString timeZone()
*/
QString QLocale::toString(const QTime &time, const QString &format) const
{
- return d->dateTimeToString(format, 0, &time, this);
+ return d->dateTimeToString(format, QDateTime(), QDate(), time, this);
}
/*!
@@ -1665,9 +1638,7 @@ QString QLocale::toString(const QTime &time, const QString &format) const
QString QLocale::toString(const QDateTime &dateTime, const QString &format) const
{
- const QDate dt = dateTime.date();
- const QTime tm = dateTime.time();
- return d->dateTimeToString(format, &dt, &tm, this);
+ return d->dateTimeToString(format, dateTime, QDate(), QTime(), this);
}
/*!
@@ -2553,28 +2524,27 @@ QString QLocale::pmText() const
}
-QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *date, const QTime *time,
+QString QLocalePrivate::dateTimeToString(const QString &format, const QDateTime &datetime,
+ const QDate &dateOnly, const QTime &timeOnly,
const QLocale *q) const
{
- Q_ASSERT(date || time);
- if ((date && !date->isValid()) || (time && !time->isValid()))
+ QDate date;
+ QTime time;
+ bool formatDate = false;
+ bool formatTime = false;
+ if (datetime.isValid()) {
+ date = datetime.date();
+ time = datetime.time();
+ formatDate = true;
+ formatTime = true;
+ } else if (dateOnly.isValid()) {
+ date = dateOnly;
+ formatDate = true;
+ } else if (timeOnly.isValid()) {
+ time = timeOnly;
+ formatTime = true;
+ } else {
return QString();
- const bool format_am_pm = time && timeFormatContainsAP(format);
-
- enum { AM, PM } am_pm = AM;
- int hour12 = time ? time->hour() : -1;
- if (time) {
- if (hour12 == 0) {
- am_pm = AM;
- hour12 = 12;
- } else if (hour12 < 12) {
- am_pm = AM;
- } else if (hour12 == 12) {
- am_pm = PM;
- } else {
- am_pm = PM;
- hour12 -= 12;
- }
}
QString result;
@@ -2589,7 +2559,7 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
const QChar c = format.at(i);
int repeat = qt_repeatCount(format, i);
bool used = false;
- if (date) {
+ if (formatDate) {
switch (c.unicode()) {
case 'y':
used = true;
@@ -2599,11 +2569,14 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
repeat = 2;
switch (repeat) {
- case 4:
- result.append(longLongToString(date->year(), -1, 10, 4, QLocalePrivate::ZeroPadded));
+ case 4: {
+ const int yr = date.year();
+ const int len = (yr < 0) ? 5 : 4;
+ result.append(longLongToString(yr, -1, 10, len, QLocalePrivate::ZeroPadded));
break;
+ }
case 2:
- result.append(longLongToString(date->year() % 100, -1, 10, 2,
+ result.append(longLongToString(date.year() % 100, -1, 10, 2,
QLocalePrivate::ZeroPadded));
break;
default:
@@ -2618,16 +2591,16 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
repeat = qMin(repeat, 4);
switch (repeat) {
case 1:
- result.append(longLongToString(date->month()));
+ result.append(longLongToString(date.month()));
break;
case 2:
- result.append(longLongToString(date->month(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(longLongToString(date.month(), -1, 10, 2, QLocalePrivate::ZeroPadded));
break;
case 3:
- result.append(q->monthName(date->month(), QLocale::ShortFormat));
+ result.append(q->monthName(date.month(), QLocale::ShortFormat));
break;
case 4:
- result.append(q->monthName(date->month(), QLocale::LongFormat));
+ result.append(q->monthName(date.month(), QLocale::LongFormat));
break;
}
break;
@@ -2637,16 +2610,16 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
repeat = qMin(repeat, 4);
switch (repeat) {
case 1:
- result.append(longLongToString(date->day()));
+ result.append(longLongToString(date.day()));
break;
case 2:
- result.append(longLongToString(date->day(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(longLongToString(date.day(), -1, 10, 2, QLocalePrivate::ZeroPadded));
break;
case 3:
- result.append(q->dayName(date->dayOfWeek(), QLocale::ShortFormat));
+ result.append(q->dayName(date.dayOfWeek(), QLocale::ShortFormat));
break;
case 4:
- result.append(q->dayName(date->dayOfWeek(), QLocale::LongFormat));
+ result.append(q->dayName(date.dayOfWeek(), QLocale::LongFormat));
break;
}
break;
@@ -2655,12 +2628,18 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
break;
}
}
- if (!used && time) {
+ if (!used && formatTime) {
switch (c.unicode()) {
case 'h': {
used = true;
repeat = qMin(repeat, 2);
- const int hour = format_am_pm ? hour12 : time->hour();
+ int hour = time.hour();
+ if (timeFormatContainsAP(format)) {
+ if (hour > 12)
+ hour -= 12;
+ else if (hour == 0)
+ hour = 12;
+ }
switch (repeat) {
case 1:
@@ -2677,10 +2656,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
repeat = qMin(repeat, 2);
switch (repeat) {
case 1:
- result.append(longLongToString(time->hour()));
+ result.append(longLongToString(time.hour()));
break;
case 2:
- result.append(longLongToString(time->hour(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(longLongToString(time.hour(), -1, 10, 2, QLocalePrivate::ZeroPadded));
break;
}
break;
@@ -2690,10 +2669,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
repeat = qMin(repeat, 2);
switch (repeat) {
case 1:
- result.append(longLongToString(time->minute()));
+ result.append(longLongToString(time.minute()));
break;
case 2:
- result.append(longLongToString(time->minute(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(longLongToString(time.minute(), -1, 10, 2, QLocalePrivate::ZeroPadded));
break;
}
break;
@@ -2703,10 +2682,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
repeat = qMin(repeat, 2);
switch (repeat) {
case 1:
- result.append(longLongToString(time->second()));
+ result.append(longLongToString(time.second()));
break;
case 2:
- result.append(longLongToString(time->second(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(longLongToString(time.second(), -1, 10, 2, QLocalePrivate::ZeroPadded));
break;
}
break;
@@ -2718,7 +2697,7 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
} else {
repeat = 1;
}
- result.append(am_pm == AM ? q->amText().toLower() : q->pmText().toLower());
+ result.append(time.hour() < 12 ? q->amText().toLower() : q->pmText().toLower());
break;
case 'A':
@@ -2728,7 +2707,7 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
} else {
repeat = 1;
}
- result.append(am_pm == AM ? q->amText().toUpper() : q->pmText().toUpper());
+ result.append(time.hour() < 12 ? q->amText().toUpper() : q->pmText().toUpper());
break;
case 'z':
@@ -2740,10 +2719,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
}
switch (repeat) {
case 1:
- result.append(longLongToString(time->msec()));
+ result.append(longLongToString(time.msec()));
break;
case 3:
- result.append(longLongToString(time->msec(), -1, 10, 3, QLocalePrivate::ZeroPadded));
+ result.append(longLongToString(time.msec(), -1, 10, 3, QLocalePrivate::ZeroPadded));
break;
}
break;
@@ -2751,8 +2730,14 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDate *dat
case 't':
used = true;
repeat = 1;
- result.append(timeZone());
+ // If we have a QDateTime use the time spec otherwise use the current system tzname
+ if (formatDate) {
+ result.append(datetime.timeZoneAbbreviation());
+ } else {
+ result.append(QDateTime::currentDateTime().timeZoneAbbreviation());
+ }
break;
+
default:
break;
}
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 34223d5af9..4b4606ffab 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -330,7 +330,8 @@ public:
enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode };
bool validateChars(const QString &str, NumberMode numMode, QByteArray *buff, int decDigits = -1) const;
- QString dateTimeToString(const QString &format, const QDate *date, const QTime *time,
+ QString dateTimeToString(const QString &format, const QDateTime &datetime,
+ const QDate &dateOnly, const QTime &timeOnly,
const QLocale *q) const;
const QLocaleData *m_data;
diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
index 0c4dde4b1a..ea0e90a503 100644
--- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
+++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
@@ -163,6 +163,7 @@ private slots:
void formatTime_data();
void formatDateTime();
void formatDateTime_data();
+ void formatTimeZone();
void toDateTime_data();
void toDateTime();
void negativeNumbers();
@@ -199,6 +200,7 @@ private slots:
private:
QString m_decimal, m_thousand, m_sdate, m_ldate, m_time;
QString m_sysapp;
+ bool europeanTimeZone;
#ifdef Q_OS_BLACKBERRY
int m_languageFd;
@@ -208,6 +210,11 @@ private:
tst_QLocale::tst_QLocale()
{
qRegisterMetaType<QLocale::FormatType>("QLocale::FormatType");
+
+ // Test if in Central European Time zone
+ uint x1 = QDateTime(QDate(1990, 1, 1), QTime()).toTime_t();
+ uint x2 = QDateTime(QDate(1990, 6, 1), QTime()).toTime_t();
+ europeanTimeZone = (x1 == 631148400 && x2 == 644191200);
}
void tst_QLocale::initTestCase()
@@ -1198,6 +1205,59 @@ void tst_QLocale::formatDateTime_data()
QTest::newRow("28no_NO") << "no_NO" << QDateTime()
<< "'\"yymm\"'" << "";
+ QDateTime testLongHour(QDate(1999, 12, 31), QTime(23, 59, 59, 999));
+ QDateTime testShortHour(QDate(1999, 12, 31), QTime(3, 59, 59, 999));
+ QDateTime testZeroHour(QDate(1999, 12, 31), QTime(0, 59, 59, 999));
+
+ QTest::newRow("datetime0") << "en_US" << QDateTime()
+ << QString("dd-MM-yyyy hh:mm:ss") << QString();
+ QTest::newRow("datetime1") << "en_US" << testLongHour
+ << QString("dd-'mmddyy'MM-yyyy hh:mm:ss.zzz")
+ << QString("31-mmddyy12-1999 23:59:59.999");
+ QTest::newRow("datetime2") << "en_US" << testLongHour
+ << QString("dd-'apAP'MM-yyyy hh:mm:ss.zzz")
+ << QString("31-apAP12-1999 23:59:59.999");
+ QTest::newRow("datetime3") << "en_US" << testLongHour
+ << QString("Apdd-MM-yyyy hh:mm:ss.zzz")
+ << QString("PMp31-12-1999 11:59:59.999");
+ QTest::newRow("datetime4") << "en_US" << testLongHour
+ << QString("'ap'apdd-MM-yyyy 'AP'hh:mm:ss.zzz")
+ << QString("appm31-12-1999 AP11:59:59.999");
+ QTest::newRow("datetime5") << "en_US" << testLongHour
+ << QString("'''") << QString("'");
+ QTest::newRow("datetime6") << "en_US" << testLongHour
+ << QString("'ap") << QString("ap");
+ QTest::newRow("datetime7") << "en_US" << testLongHour
+ << QString("' ' 'hh' hh") << QString(" hh 23");
+ QTest::newRow("datetime8") << "en_US" << testLongHour
+ << QString("d'foobar'") << QString("31foobar");
+ QTest::newRow("datetime9") << "en_US" << testShortHour
+ << QString("hhhhh") << QString("03033");
+ QTest::newRow("datetime11") << "en_US" << testLongHour
+ << QString("HHHhhhAaAPap") << QString("23231111PMpmPMpm");
+ QTest::newRow("datetime12") << "en_US" << testShortHour
+ << QString("HHHhhhAaAPap") << QString("033033AMamAMam");
+ QTest::newRow("datetime13") << "en_US" << QDateTime(QDate(1974, 12, 1), QTime(14, 14, 20))
+ << QString("hh''mm''ss dd''MM''yyyy")
+ << QString("14'14'20 01'12'1974");
+ QTest::newRow("AM no p") << "en_US" << testZeroHour
+ << QString("hhAX") << QString("12AMX");
+ QTest::newRow("AM no p, x 2") << "en_US" << testShortHour
+ << QString("hhhhhaA") << QString("03033amAM");
+ QTest::newRow("am 0 hour") << "en_US" << testZeroHour
+ << QString("hAP") << QString("12AM");
+ QTest::newRow("AM zero hour") << "en_US" << testZeroHour
+ << QString("hhAP") << QString("12AM");
+ QTest::newRow("dddd") << "en_US" << testZeroHour
+ << QString("dddd") << QString("Friday");
+ QTest::newRow("ddd") << "en_US" << testZeroHour
+ << QString("ddd") << QString("Fri");
+ QTest::newRow("MMMM") << "en_US" << testZeroHour
+ << QString("MMMM") << QString("December");
+ QTest::newRow("MMM") << "en_US" << testZeroHour
+ << QString("MMM") << QString("Dec");
+ QTest::newRow("empty") << "en_US" << testZeroHour
+ << QString("") << QString("");
}
void tst_QLocale::formatDateTime()
@@ -1211,6 +1271,46 @@ void tst_QLocale::formatDateTime()
QCOMPARE(l.toString(dateTime, format), result);
}
+void tst_QLocale::formatTimeZone()
+{
+ QLocale enUS("en_US");
+
+ QDateTime dt1(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, 60 * 60);
+ QCOMPARE(enUS.toString(dt1, "t"), QString("UTC+01:00"));
+
+ QDateTime dt2(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, -60 * 60);
+ QCOMPARE(enUS.toString(dt2, "t"), QString("UTC-01:00"));
+
+ QDateTime dt3(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::UTC);
+ QCOMPARE(enUS.toString(dt3, "t"), QString("UTC"));
+
+ // LocalTime should vary
+ if (europeanTimeZone) {
+ // Time definitely in Standard Time
+ QDateTime dt4(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::LocalTime);
+#ifdef Q_OS_WIN
+ QEXPECT_FAIL("", "Windows only returns long name (QTBUG-32759)", Continue);
+#endif // Q_OS_WIN
+ QCOMPARE(enUS.toString(dt4, "t"), QString("CET"));
+
+ // Time definitely in Daylight Time
+ QDateTime dt5(QDate(2013, 6, 1), QTime(0, 0, 0), Qt::LocalTime);
+#ifdef Q_OS_WIN
+ QEXPECT_FAIL("", "Windows only returns long name (QTBUG-32759)", Continue);
+#endif // Q_OS_WIN
+ QCOMPARE(enUS.toString(dt5, "t"), QString("CEST"));
+ } else {
+ QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo");
+ }
+
+ // Current datetime should return current abbreviation
+ QCOMPARE(enUS.toString(QDateTime::currentDateTime(), "t"),
+ QDateTime::currentDateTime().timeZoneAbbreviation());
+
+ // Time on its own will always be current local time zone
+ QCOMPARE(enUS.toString(QTime(1, 2, 3), "t"), QDateTime::currentDateTime().timeZoneAbbreviation());
+}
+
void tst_QLocale::toDateTime_data()
{
QTest::addColumn<QString>("localeName");