diff --git a/autotests/kformattest.cpp b/autotests/kformattest.cpp index 15080be..118609a 100644 --- a/autotests/kformattest.cpp +++ b/autotests/kformattest.cpp @@ -1,350 +1,355 @@ /* This file is part of the KDE Frameworks Copyright (C) 2013 John Layt , Copyright (C) 2010 Michael Leupold Copyright (C) 2009 Michael Pyne Copyright (C) 2008 Albert Astals Cid This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kformattest.h" #include #include "kformat.h" void KFormatTest::formatByteSize() { QLocale locale(QLocale::c()); locale.setNumberOptions(QLocale::DefaultNumberOptions); // Qt >= 5.6 sets QLocale::OmitGroupSeparator for the C locale KFormat format(locale); QCOMPARE(format.formatByteSize(0), QStringLiteral("0 B")); QCOMPARE(format.formatByteSize(50), QStringLiteral("50 B")); QCOMPARE(format.formatByteSize(500), QStringLiteral("500 B")); QCOMPARE(format.formatByteSize(5000), QStringLiteral("4.9 KiB")); QCOMPARE(format.formatByteSize(50000), QStringLiteral("48.8 KiB")); QCOMPARE(format.formatByteSize(500000), QStringLiteral("488.3 KiB")); QCOMPARE(format.formatByteSize(5000000), QStringLiteral("4.8 MiB")); QCOMPARE(format.formatByteSize(50000000), QStringLiteral("47.7 MiB")); QCOMPARE(format.formatByteSize(500000000), QStringLiteral("476.8 MiB")); #if (defined(__WORDSIZE) && (__WORDSIZE == 64)) || defined (_LP64) || defined(__LP64__) || defined(__ILP64__) QCOMPARE(format.formatByteSize(5000000000), QStringLiteral("4.7 GiB")); QCOMPARE(format.formatByteSize(50000000000), QStringLiteral("46.6 GiB")); QCOMPARE(format.formatByteSize(500000000000), QStringLiteral("465.7 GiB")); QCOMPARE(format.formatByteSize(5000000000000), QStringLiteral("4.5 TiB")); QCOMPARE(format.formatByteSize(50000000000000), QStringLiteral("45.5 TiB")); QCOMPARE(format.formatByteSize(500000000000000), QStringLiteral("454.7 TiB")); #endif QCOMPARE(format.formatByteSize(1024.0, 1, KFormat::IECBinaryDialect), QStringLiteral("1.0 KiB")); QCOMPARE(format.formatByteSize(1023.0, 1, KFormat::IECBinaryDialect), QStringLiteral("1,023 B")); QCOMPARE(format.formatByteSize(1163000.0, 1, KFormat::IECBinaryDialect), QStringLiteral("1.1 MiB")); // 1.2 metric QCOMPARE(format.formatByteSize(-1024.0, 1, KFormat::IECBinaryDialect), QStringLiteral("-1.0 KiB")); QCOMPARE(format.formatByteSize(-1023.0, 1, KFormat::IECBinaryDialect), QStringLiteral("-1,023 B")); QCOMPARE(format.formatByteSize(-1163000.0, 1, KFormat::IECBinaryDialect), QStringLiteral("-1.1 MiB")); // 1.2 metric QCOMPARE(format.formatByteSize(1024.0, 1, KFormat::JEDECBinaryDialect), QStringLiteral("1.0 KB")); QCOMPARE(format.formatByteSize(1023.0, 1, KFormat::JEDECBinaryDialect), QStringLiteral("1,023 B")); QCOMPARE(format.formatByteSize(1163000.0, 1, KFormat::JEDECBinaryDialect), QStringLiteral("1.1 MB")); QCOMPARE(format.formatByteSize(-1024.0, 1, KFormat::JEDECBinaryDialect), QStringLiteral("-1.0 KB")); QCOMPARE(format.formatByteSize(-1023.0, 1, KFormat::JEDECBinaryDialect), QStringLiteral("-1,023 B")); QCOMPARE(format.formatByteSize(-1163000.0, 1, KFormat::JEDECBinaryDialect), QStringLiteral("-1.1 MB")); QCOMPARE(format.formatByteSize(1024.0, 1, KFormat::MetricBinaryDialect), QStringLiteral("1.0 kB")); QCOMPARE(format.formatByteSize(1023.0, 1, KFormat::MetricBinaryDialect), QStringLiteral("1.0 kB")); QCOMPARE(format.formatByteSize(1163000.0, 1, KFormat::MetricBinaryDialect), QStringLiteral("1.2 MB")); QCOMPARE(format.formatByteSize(-1024.0, 1, KFormat::MetricBinaryDialect), QStringLiteral("-1.0 kB")); QCOMPARE(format.formatByteSize(-1023.0, 1, KFormat::MetricBinaryDialect), QStringLiteral("-1.0 kB")); QCOMPARE(format.formatByteSize(-1163000.0, 1, KFormat::MetricBinaryDialect), QStringLiteral("-1.2 MB")); // Ensure all units are represented QCOMPARE(format.formatByteSize(2.0e9, 1, KFormat::MetricBinaryDialect), QStringLiteral("2.0 GB")); QCOMPARE(format.formatByteSize(3.2e12, 1, KFormat::MetricBinaryDialect), QStringLiteral("3.2 TB")); QCOMPARE(format.formatByteSize(4.1e15, 1, KFormat::MetricBinaryDialect), QStringLiteral("4.1 PB")); QCOMPARE(format.formatByteSize(6.7e18, 2, KFormat::MetricBinaryDialect), QStringLiteral("6.70 EB")); QCOMPARE(format.formatByteSize(5.6e20, 2, KFormat::MetricBinaryDialect), QStringLiteral("560.00 EB")); QCOMPARE(format.formatByteSize(2.3e22, 2, KFormat::MetricBinaryDialect), QStringLiteral("23.00 ZB")); QCOMPARE(format.formatByteSize(1.0e27, 1, KFormat::MetricBinaryDialect), QStringLiteral("1,000.0 YB")); // Spattering of specific units QCOMPARE(format.formatByteSize(823000, 3, KFormat::IECBinaryDialect, KFormat::UnitMegaByte), QStringLiteral("0.785 MiB")); QCOMPARE(format.formatByteSize(1234034.0, 4, KFormat::JEDECBinaryDialect, KFormat::UnitByte), QStringLiteral("1,234,034 B")); + + // Check examples from the documentation + QCOMPARE(format.formatByteSize(1000, 1, KFormat::MetricBinaryDialect, KFormat::UnitKiloByte), QStringLiteral("1.0 kB")); + QCOMPARE(format.formatByteSize(1000, 1, KFormat::IECBinaryDialect, KFormat::UnitKiloByte), QStringLiteral("1.0 KiB")); + QCOMPARE(format.formatByteSize(1000, 1, KFormat::JEDECBinaryDialect, KFormat::UnitKiloByte), QStringLiteral("1.0 KB")); } enum TimeConstants { MSecsInDay = 86400000, MSecsInHour = 3600000, MSecsInMinute = 60000, MSecsInSecond = 1000 }; void KFormatTest::formatDuration() { KFormat format(QLocale::c()); quint64 singleSecond = 3 * MSecsInSecond + 700; quint64 doubleSecond = 33 * MSecsInSecond + 700; quint64 singleMinute = 8 * MSecsInMinute + 3 * MSecsInSecond + 700; quint64 doubleMinute = 38 * MSecsInMinute + 3 * MSecsInSecond + 700; quint64 singleHour = 5 * MSecsInHour + 8 * MSecsInMinute + 3 * MSecsInSecond + 700; quint64 doubleHour = 15 * MSecsInHour + 8 * MSecsInMinute + 3 * MSecsInSecond + 700; quint64 singleDay = 1 * MSecsInDay + 5 * MSecsInHour + 8 * MSecsInMinute + 3 * MSecsInSecond + 700; quint64 doubleDay = 10 * MSecsInDay + 5 * MSecsInHour + 8 * MSecsInMinute + 3 * MSecsInSecond + 700; quint64 roundingIssues = 2* MSecsInHour + 59 * MSecsInMinute + 59 * MSecsInSecond + 900; // Default format QCOMPARE(format.formatDuration(singleSecond), QStringLiteral("0:00:04")); QCOMPARE(format.formatDuration(doubleSecond), QStringLiteral("0:00:34")); QCOMPARE(format.formatDuration(singleMinute), QStringLiteral("0:08:04")); QCOMPARE(format.formatDuration(doubleMinute), QStringLiteral("0:38:04")); QCOMPARE(format.formatDuration(singleHour), QStringLiteral("5:08:04")); QCOMPARE(format.formatDuration(doubleHour), QStringLiteral("15:08:04")); QCOMPARE(format.formatDuration(singleDay), QStringLiteral("29:08:04")); QCOMPARE(format.formatDuration(doubleDay), QStringLiteral("245:08:04")); QCOMPARE(format.formatDuration(roundingIssues), QStringLiteral("3:00:00")); // ShowMilliseconds format KFormat::DurationFormatOptions options = KFormat::ShowMilliseconds; QCOMPARE(format.formatDuration(singleSecond, options), QStringLiteral("0:00:03.700")); QCOMPARE(format.formatDuration(doubleSecond, options), QStringLiteral("0:00:33.700")); QCOMPARE(format.formatDuration(singleMinute, options), QStringLiteral("0:08:03.700")); QCOMPARE(format.formatDuration(doubleMinute, options), QStringLiteral("0:38:03.700")); QCOMPARE(format.formatDuration(singleHour, options), QStringLiteral("5:08:03.700")); QCOMPARE(format.formatDuration(doubleHour, options), QStringLiteral("15:08:03.700")); QCOMPARE(format.formatDuration(singleDay, options), QStringLiteral("29:08:03.700")); QCOMPARE(format.formatDuration(doubleDay, options), QStringLiteral("245:08:03.700")); QCOMPARE(format.formatDuration(roundingIssues, options), QStringLiteral("2:59:59.900")); // HideSeconds format options = KFormat::HideSeconds; QCOMPARE(format.formatDuration(singleSecond, options), QStringLiteral("0:00")); QCOMPARE(format.formatDuration(doubleSecond, options), QStringLiteral("0:01")); QCOMPARE(format.formatDuration(singleMinute, options), QStringLiteral("0:08")); QCOMPARE(format.formatDuration(doubleMinute, options), QStringLiteral("0:38")); QCOMPARE(format.formatDuration(singleHour, options), QStringLiteral("5:08")); QCOMPARE(format.formatDuration(doubleHour, options), QStringLiteral("15:08")); QCOMPARE(format.formatDuration(singleDay, options), QStringLiteral("29:08")); QCOMPARE(format.formatDuration(doubleDay, options), QStringLiteral("245:08")); QCOMPARE(format.formatDuration(roundingIssues, options), QStringLiteral("3:00")); // FoldHours format options = KFormat::FoldHours; QCOMPARE(format.formatDuration(singleSecond, options), QStringLiteral("0:04")); QCOMPARE(format.formatDuration(doubleSecond, options), QStringLiteral("0:34")); QCOMPARE(format.formatDuration(singleMinute, options), QStringLiteral("8:04")); QCOMPARE(format.formatDuration(doubleMinute, options), QStringLiteral("38:04")); QCOMPARE(format.formatDuration(singleHour, options), QStringLiteral("308:04")); QCOMPARE(format.formatDuration(doubleHour, options), QStringLiteral("908:04")); QCOMPARE(format.formatDuration(singleDay, options), QStringLiteral("1748:04")); QCOMPARE(format.formatDuration(doubleDay, options), QStringLiteral("14708:04")); QCOMPARE(format.formatDuration(roundingIssues, options), QStringLiteral("180:00")); // FoldHours ShowMilliseconds format options = KFormat::FoldHours; options = options | KFormat::ShowMilliseconds; QCOMPARE(format.formatDuration(singleSecond, options), QStringLiteral("0:03.700")); QCOMPARE(format.formatDuration(doubleSecond, options), QStringLiteral("0:33.700")); QCOMPARE(format.formatDuration(singleMinute, options), QStringLiteral("8:03.700")); QCOMPARE(format.formatDuration(doubleMinute, options), QStringLiteral("38:03.700")); QCOMPARE(format.formatDuration(singleHour, options), QStringLiteral("308:03.700")); QCOMPARE(format.formatDuration(doubleHour, options), QStringLiteral("908:03.700")); QCOMPARE(format.formatDuration(singleDay, options), QStringLiteral("1748:03.700")); QCOMPARE(format.formatDuration(doubleDay, options), QStringLiteral("14708:03.700")); QCOMPARE(format.formatDuration(roundingIssues, options), QStringLiteral("179:59.900")); // InitialDuration format options = KFormat::InitialDuration; QCOMPARE(format.formatDuration(singleSecond, options), QStringLiteral("0h00m04s")); QCOMPARE(format.formatDuration(doubleSecond, options), QStringLiteral("0h00m34s")); QCOMPARE(format.formatDuration(singleMinute, options), QStringLiteral("0h08m04s")); QCOMPARE(format.formatDuration(doubleMinute, options), QStringLiteral("0h38m04s")); QCOMPARE(format.formatDuration(singleHour, options), QStringLiteral("5h08m04s")); QCOMPARE(format.formatDuration(doubleHour, options), QStringLiteral("15h08m04s")); QCOMPARE(format.formatDuration(singleDay, options), QStringLiteral("29h08m04s")); QCOMPARE(format.formatDuration(doubleDay, options), QStringLiteral("245h08m04s")); QCOMPARE(format.formatDuration(roundingIssues, options), QStringLiteral("3h00m00s")); // InitialDuration and ShowMilliseconds format options = KFormat::InitialDuration; options = options | KFormat::ShowMilliseconds; QCOMPARE(format.formatDuration(singleSecond, options), QStringLiteral("0h00m03.700s")); QCOMPARE(format.formatDuration(doubleSecond, options), QStringLiteral("0h00m33.700s")); QCOMPARE(format.formatDuration(singleMinute, options), QStringLiteral("0h08m03.700s")); QCOMPARE(format.formatDuration(doubleMinute, options), QStringLiteral("0h38m03.700s")); QCOMPARE(format.formatDuration(singleHour, options), QStringLiteral("5h08m03.700s")); QCOMPARE(format.formatDuration(doubleHour, options), QStringLiteral("15h08m03.700s")); QCOMPARE(format.formatDuration(singleDay, options), QStringLiteral("29h08m03.700s")); QCOMPARE(format.formatDuration(doubleDay, options), QStringLiteral("245h08m03.700s")); QCOMPARE(format.formatDuration(roundingIssues, options), QStringLiteral("2h59m59.900s")); // InitialDuration and HideSeconds format options = KFormat::InitialDuration; options = options | KFormat::HideSeconds; QCOMPARE(format.formatDuration(singleSecond, options), QStringLiteral("0h00m")); QCOMPARE(format.formatDuration(doubleSecond, options), QStringLiteral("0h01m")); QCOMPARE(format.formatDuration(singleMinute, options), QStringLiteral("0h08m")); QCOMPARE(format.formatDuration(doubleMinute, options), QStringLiteral("0h38m")); QCOMPARE(format.formatDuration(singleHour, options), QStringLiteral("5h08m")); QCOMPARE(format.formatDuration(doubleHour, options), QStringLiteral("15h08m")); QCOMPARE(format.formatDuration(singleDay, options), QStringLiteral("29h08m")); QCOMPARE(format.formatDuration(doubleDay, options), QStringLiteral("245h08m")); QCOMPARE(format.formatDuration(roundingIssues, options), QStringLiteral("3h00m")); // InitialDuration and FoldHours format options = KFormat::InitialDuration; options = options | KFormat::FoldHours; QCOMPARE(format.formatDuration(singleSecond, options), QStringLiteral("0m04s")); QCOMPARE(format.formatDuration(doubleSecond, options), QStringLiteral("0m34s")); QCOMPARE(format.formatDuration(singleMinute, options), QStringLiteral("8m04s")); QCOMPARE(format.formatDuration(doubleMinute, options), QStringLiteral("38m04s")); QCOMPARE(format.formatDuration(singleHour, options), QStringLiteral("308m04s")); QCOMPARE(format.formatDuration(doubleHour, options), QStringLiteral("908m04s")); QCOMPARE(format.formatDuration(singleDay, options), QStringLiteral("1748m04s")); QCOMPARE(format.formatDuration(doubleDay, options), QStringLiteral("14708m04s")); QCOMPARE(format.formatDuration(roundingIssues, options), QStringLiteral("180m00s")); // InitialDuration and FoldHours and ShowMilliseconds format options = KFormat::InitialDuration; options = options | KFormat::FoldHours | KFormat::ShowMilliseconds; QCOMPARE(format.formatDuration(singleSecond, options), QStringLiteral("0m03.700s")); QCOMPARE(format.formatDuration(doubleSecond, options), QStringLiteral("0m33.700s")); QCOMPARE(format.formatDuration(singleMinute, options), QStringLiteral("8m03.700s")); QCOMPARE(format.formatDuration(doubleMinute, options), QStringLiteral("38m03.700s")); QCOMPARE(format.formatDuration(singleHour, options), QStringLiteral("308m03.700s")); QCOMPARE(format.formatDuration(doubleHour, options), QStringLiteral("908m03.700s")); QCOMPARE(format.formatDuration(singleDay, options), QStringLiteral("1748m03.700s")); QCOMPARE(format.formatDuration(doubleDay, options), QStringLiteral("14708m03.700s")); QCOMPARE(format.formatDuration(roundingIssues, options), QStringLiteral("179m59.900s")); } void KFormatTest::formatDecimalDuration() { KFormat format(QLocale::c()); QCOMPARE(format.formatDecimalDuration(10), QStringLiteral("10 millisecond(s)")); QCOMPARE(format.formatDecimalDuration(10, 3), QStringLiteral("10 millisecond(s)")); QCOMPARE(format.formatDecimalDuration(1 * MSecsInSecond + 10), QStringLiteral("1.01 seconds")); QCOMPARE(format.formatDecimalDuration(1 * MSecsInSecond + 1, 3), QStringLiteral("1.001 seconds")); QCOMPARE(format.formatDecimalDuration(1 * MSecsInMinute + 10 * MSecsInSecond), QStringLiteral("1.17 minutes")); QCOMPARE(format.formatDecimalDuration(1 * MSecsInMinute + 10 * MSecsInSecond, 3), QStringLiteral("1.167 minutes")); QCOMPARE(format.formatDecimalDuration(1 * MSecsInHour + 10 * MSecsInMinute), QStringLiteral("1.17 hours")); QCOMPARE(format.formatDecimalDuration(1 * MSecsInHour + 10 * MSecsInMinute, 3), QStringLiteral("1.167 hours")); QCOMPARE(format.formatDecimalDuration(1 * MSecsInDay + 10 * MSecsInHour), QStringLiteral("1.42 days")); QCOMPARE(format.formatDecimalDuration(1 * MSecsInDay + 10 * MSecsInHour, 3), QStringLiteral("1.417 days")); } void KFormatTest::formatSpelloutDuration() { KFormat format(QLocale::c()); QCOMPARE(format.formatSpelloutDuration(1000), QStringLiteral("1 second(s)")); QCOMPARE(format.formatSpelloutDuration(5000), QStringLiteral("5 second(s)")); QCOMPARE(format.formatSpelloutDuration(60000), QStringLiteral("1 minute(s)")); QCOMPARE(format.formatSpelloutDuration(300000), QStringLiteral("5 minute(s)")); QCOMPARE(format.formatSpelloutDuration(3600000), QStringLiteral("1 hour(s)")); QCOMPARE(format.formatSpelloutDuration(18000000), QStringLiteral("5 hour(s)")); QCOMPARE(format.formatSpelloutDuration(75000), QStringLiteral("1 minute(s) and 15 second(s)")); // Problematic case #1 (there is a reference to this case on kformat.cpp) QCOMPARE(format.formatSpelloutDuration(119999), QStringLiteral("2 minute(s)")); // This case is strictly 2 hours, 15 minutes and 59 seconds. However, since the range is // pretty high between hours and seconds, formatSpelloutDuration always omits seconds when there // are hours in scene. QCOMPARE(format.formatSpelloutDuration(8159000), QStringLiteral("2 hour(s) and 15 minute(s)")); // This case is strictly 1 hour and 10 seconds. For the same reason, formatSpelloutDuration // detects that 10 seconds is just garbage compared to 1 hour, and omits it on the result. QCOMPARE(format.formatSpelloutDuration(3610000), QStringLiteral("1 hour(s)")); } void KFormatTest::formatRelativeDate() { KFormat format(QLocale::c()); QDate testDate = QDate::currentDate(); QCOMPARE(format.formatRelativeDate(testDate, QLocale::LongFormat), QStringLiteral("Today")); QCOMPARE(format.formatRelativeDate(testDate, QLocale::ShortFormat), QStringLiteral("Today")); QCOMPARE(format.formatRelativeDate(testDate, QLocale::NarrowFormat), QStringLiteral("Today")); testDate = QDate::currentDate().addDays(1); QCOMPARE(format.formatRelativeDate(testDate, QLocale::LongFormat), QStringLiteral("Tomorrow")); QCOMPARE(format.formatRelativeDate(testDate, QLocale::ShortFormat), QStringLiteral("Tomorrow")); QCOMPARE(format.formatRelativeDate(testDate, QLocale::NarrowFormat), QStringLiteral("Tomorrow")); testDate = QDate::currentDate().addDays(-1); QCOMPARE(format.formatRelativeDate(testDate, QLocale::LongFormat), QStringLiteral("Yesterday")); QCOMPARE(format.formatRelativeDate(testDate, QLocale::ShortFormat), QStringLiteral("Yesterday")); QCOMPARE(format.formatRelativeDate(testDate, QLocale::NarrowFormat), QStringLiteral("Yesterday")); // Relative dates within a week are up to translators but there's no // expectation that day names are shortened -- per the API docs, the date // format is only used when the date is outside the relative window testDate = QDate::currentDate().addDays(-7); QCOMPARE(format.formatRelativeDate(testDate, QLocale::LongFormat), QStringLiteral("Last %1").arg(QLocale::c().dayName(testDate.dayOfWeek(), QLocale::LongFormat))); QCOMPARE(format.formatRelativeDate(testDate, QLocale::ShortFormat), QStringLiteral("Last %1").arg(QLocale::c().dayName(testDate.dayOfWeek(), QLocale::LongFormat))); QCOMPARE(format.formatRelativeDate(testDate, QLocale::NarrowFormat), QStringLiteral("Last %1").arg(QLocale::c().dayName(testDate.dayOfWeek(), QLocale::LongFormat))); testDate = QDate::currentDate().addDays(7); QCOMPARE(format.formatRelativeDate(testDate, QLocale::LongFormat), QStringLiteral("Next %1").arg(QLocale::c().dayName(testDate.dayOfWeek(), QLocale::LongFormat))); QCOMPARE(format.formatRelativeDate(testDate, QLocale::ShortFormat), QStringLiteral("Next %1").arg(QLocale::c().dayName(testDate.dayOfWeek(), QLocale::LongFormat))); QCOMPARE(format.formatRelativeDate(testDate, QLocale::NarrowFormat), QStringLiteral("Next %1").arg(QLocale::c().dayName(testDate.dayOfWeek(), QLocale::LongFormat))); testDate = QDate::currentDate().addDays(-8); QCOMPARE(format.formatRelativeDate(testDate, QLocale::LongFormat), QLocale::c().toString(testDate, QLocale::LongFormat)); QCOMPARE(format.formatRelativeDate(testDate, QLocale::ShortFormat), QLocale::c().toString(testDate, QLocale::ShortFormat)); QCOMPARE(format.formatRelativeDate(testDate, QLocale::NarrowFormat), QLocale::c().toString(testDate, QLocale::NarrowFormat)); testDate = QDate::currentDate().addDays(8); QCOMPARE(format.formatRelativeDate(testDate, QLocale::LongFormat), QLocale::c().toString(testDate, QLocale::LongFormat)); QCOMPARE(format.formatRelativeDate(testDate, QLocale::ShortFormat), QLocale::c().toString(testDate, QLocale::ShortFormat)); QCOMPARE(format.formatRelativeDate(testDate, QLocale::NarrowFormat), QLocale::c().toString(testDate, QLocale::NarrowFormat)); testDate = QDate(); // invalid date QCOMPARE(format.formatRelativeDate(testDate, QLocale::LongFormat), QStringLiteral("Invalid date")); QDateTime testDateTime = QDateTime(QDate::currentDate(), QTime(3, 0, 0)); QCOMPARE(format.formatRelativeDateTime(testDateTime, QLocale::ShortFormat), QStringLiteral("Today, 03:00:00")); testDateTime = QDateTime(QDate::currentDate().addDays(8), QTime(3, 0, 0)); QCOMPARE(format.formatRelativeDateTime(testDateTime, QLocale::LongFormat), QLocale::c().toString(testDateTime, QLocale::LongFormat)); } QTEST_MAIN(KFormatTest) diff --git a/src/lib/util/kformat.h b/src/lib/util/kformat.h index 637315c..4cbaba3 100644 --- a/src/lib/util/kformat.h +++ b/src/lib/util/kformat.h @@ -1,289 +1,295 @@ /* This file is part of the KDE Frameworks Copyright (C) 2013 Alex Merry Copyright (C) 2013 John Layt Copyright (C) 2010 Michael Leupold Copyright (C) 2009 Michael Pyne Copyright (C) 2008 Albert Astals Cid This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KFORMAT_H #define KFORMAT_H #include #include #include #include class QDate; class QDateTime; class KFormatPrivate; /** * \file kformat.h */ /* The code in this class was copied from the old KLocale and modified by John Layt (and also Alex Merry) in the KDELIBS 4 to KDE Frameworks 5 transition in 2013. Albert Astals Cid is the original author of formatSpelloutDuration() originally named KLocale::prettyFormatDuration(). Michael Pyne is the original author of formatByteSize(). Michael Leupold is the original author of formatRelativeDate(() originally part of KFormat::formatDate(). */ /** * @class KFormat kformat.h KFormat * * KFormat provides support for formatting numbers and datetimes in * formats that are not supported by QLocale. * * @author John Layt , * Michael Pyne , * Albert Astals Cid , * * @short Class for formatting numbers and datetimes. * @since 5.0 */ class KCOREADDONS_EXPORT KFormat Q_DECL_FINAL { Q_GADGET public: /** * These binary units are used in KDE by the formatByteSize() * function. * * NOTE: There are several different units standards: * 1) SI (i.e. metric), powers-of-10. * 2) IEC, powers-of-2, with specific units KiB, MiB, etc. * 3) JEDEC, powers-of-2, used for solid state memory sizing which * is why you see flash cards labels as e.g. 4GB. These (ab)use * the metric units. Although JEDEC only defines KB, MB, GB, if * JEDEC is selected all units will be powers-of-2 with metric * prefixes for clarity in the event of sizes larger than 1024 GB. * * Although 3 different dialects are possible this enum only uses * metric names since adding all 3 different names of essentially the same * unit would be pointless. Use BinaryUnitDialect to control the exact * units returned. * * @see BinaryUnitDialect * @see formatByteSize */ enum BinarySizeUnits { /// Auto-choose a unit such that the result is in the range [0, 1000 or 1024) DefaultBinaryUnits = -1, // The first real unit must be 0 for the current implementation! UnitByte, ///< B 1 byte UnitKiloByte, ///< KiB/KB/kB 1024/1000 bytes. UnitMegaByte, ///< MiB/MB/MB 2^20/10^06 bytes. UnitGigaByte, ///< GiB/GB/GB 2^30/10^09 bytes. UnitTeraByte, ///< TiB/TB/TB 2^40/10^12 bytes. UnitPetaByte, ///< PiB/PB/PB 2^50/10^15 bytes. UnitExaByte, ///< EiB/EB/EB 2^60/10^18 bytes. UnitZettaByte, ///< ZiB/ZB/ZB 2^70/10^21 bytes. UnitYottaByte, ///< YiB/YB/YB 2^80/10^24 bytes. UnitLastUnit = UnitYottaByte }; /** * This enum chooses what dialect is used for binary units. * * Note: Although JEDEC abuses the metric prefixes and can therefore be * confusing, it has been used to describe *memory* sizes for quite some time * and programs should therefore use either Default, JEDEC, or IEC 60027-2 * for memory sizes. * * On the other hand network transmission rates are typically in metric so * Default, Metric, or IEC (which is unambiguous) should be chosen. * * Normally choosing DefaultBinaryDialect is the best option as that uses * the user's selection for units. If the user has not selected a preference, * IECBinaryDialect will typically be used. * * @see BinarySizeUnits * @see formatByteSize */ enum BinaryUnitDialect { DefaultBinaryDialect = -1, ///< Used if no specific preference IECBinaryDialect, ///< KiB, MiB, etc. 2^(10*n) JEDECBinaryDialect, ///< KB, MB, etc. 2^(10*n) MetricBinaryDialect, ///< SI Units, kB, MB, etc. 10^(3*n) LastBinaryDialect = MetricBinaryDialect }; /** * Format flags for formatDuration() */ enum DurationFormatOption { DefaultDuration = 0x0, ///< Default formatting in localized 1:23:45 format InitialDuration = 0x1, ///< Default formatting in localized 1h23m45s format ShowMilliseconds = 0x2, ///< Include milliseconds in format, e.g. 1:23:45.678 HideSeconds = 0x4, ///< Hide the seconds, e.g. 1:23 or 1h23m, overrides ShowMilliseconds FoldHours = 0x8 ///< Fold the hours into the minutes, e.g. 83:45 or 83m45s, overrides HideSeconds }; Q_DECLARE_FLAGS(DurationFormatOptions, DurationFormatOption) Q_FLAG(DurationFormatOption) /** * Constructs a KFormat. * * @param locale the locale to use, defaults to the system locale */ explicit KFormat(const QLocale &locale = QLocale()); /** * Copy constructor */ KFormat(const KFormat &other); KFormat& operator=(const KFormat &other); /** * Destructor */ ~KFormat(); /** * Converts @p size from bytes to the appropriate string representation - * using the binary unit dialect @p dialect and the specific units @p specificUnit. + * using the binary unit dialect @p dialect and the specific units @p units. * * Example: - * formatByteSize(1000, unit, KFormat::UnitKiloByte) returns: - * for KFormat::MetricBinaryDialect, "1.0 kB", - * for KFormat::IECBinaryDialect, "0.9 KiB", - * for KFormat::JEDECBinaryDialect, "0.9 KB". + * @code + * QString metric, iec, jedec, small; + * metric = formatByteSize(1000, 1, KFormat::MetricBinaryDialect, KFormat::UnitKiloByte); + * iec = formatByteSize(1000, 1, KFormat::IECBinaryDialect, KFormat::UnitKiloByte); + * jedec = formatByteSize(1000, 1, KFormat::JEDECBinaryDialect, KFormat::UnitKiloByte); + * small = formatByteSize(100); + * // metric == "1.0 kB", iec == "1.0 KiB", jedec == "1.0 KB", small == "100 B" + * @endcode * * @param size size in bytes * @param precision number of places after the decimal point to use. KDE uses - * 1 by default so when in doubt use 1. + * 1 by default so when in doubt use 1. Whenever KFormat::UnitByte is used + * (either explicitly or autoselected from KFormat::DefaultBinaryUnits), + * the fractional part is always omitted. * @param dialect binary unit standard to use. Use DefaultBinaryDialect to * use the localized user selection unless you need to use a specific * unit type (such as displaying a flash memory size in JEDEC). * @param units specific unit size to use in result. Use * DefaultBinaryUnits to automatically select a unit that will return * a sanely-sized number. * @return converted size as a translated string including the units. * E.g. "1.23 KiB", "2 GB" (JEDEC), "4.2 kB" (Metric). * @see BinarySizeUnits * @see BinaryUnitDialect */ QString formatByteSize(double size, int precision = 1, KFormat::BinaryUnitDialect dialect = KFormat::DefaultBinaryDialect, KFormat::BinarySizeUnits units = KFormat::DefaultBinaryUnits) const; /** * Given a number of milliseconds, converts that to a string containing * the localized equivalent, e.g. 1:23:45 * * @param msecs Time duration in milliseconds * @param options options to use in the duration format * @return converted duration as a string - e.g. "1:23:45" "1h23m" */ QString formatDuration(quint64 msecs, KFormat::DurationFormatOptions options = KFormat::DefaultDuration) const; /** * Given a number of milliseconds, converts that to a string containing * the localized equivalent to the requested decimal places. * * e.g. given formatDuration(60000), returns "1.0 minutes" * * @param msecs Time duration in milliseconds * @param decimalPlaces Deciaml places to round off to, defaults to 2 * @return converted duration as a string - e.g. "5.5 seconds" "23.0 minutes" */ QString formatDecimalDuration(quint64 msecs, int decimalPlaces = 2) const; /** * Given a number of milliseconds, converts that to a spell-out string containing * the localized equivalent. * * e.g. given formatSpelloutDuration(60001) returns "1 minute" * given formatSpelloutDuration(62005) returns "1 minute and 2 seconds" * given formatSpelloutDuration(90060000) returns "1 day and 1 hour" * * @param msecs Time duration in milliseconds * @return converted duration as a string. * Units not interesting to the user, for example seconds or minutes when the first * unit is day, are not returned because they are irrelevant. The same applies for * seconds when the first unit is hour. */ QString formatSpelloutDuration(quint64 msecs) const; /** * Returns a string formatted to a relative date style. * * If the @p date falls within one week before or after the current date * then a relative date string will be returned, such as: * * Yesterday * * Today * * Tomorrow * * Last Tuesday * * Next Wednesday * * If the @p date falls outside this period then the @p format is used. * * @param date the date to be formatted * @param format the date format to use * * @return the date as a string */ QString formatRelativeDate(const QDate &date, QLocale::FormatType format) const; /** * Returns a string formatted to a relative datetime style. * * If the @p dateTime falls within one week before or after the current date * then a relative date string will be returned, such as: * * Yesterday, 3:00pm * * Today, 3:00pm * * Tomorrow, 3:00pm * * Last Tuesday, 3:00pm * * Next Wednesday, 3:00pm * * If the @p dateTime falls outside this period then the @p format is used. * * @param dateTime the date to be formatted * @param format the date format to use * * @return the date as a string */ QString formatRelativeDateTime(const QDateTime &dateTime, QLocale::FormatType format) const; private: QSharedDataPointer d; }; #endif // KFORMAT_H