File indexing completed on 2024-05-12 03:54:59
0001 /* 0002 This file is part of the KDE Frameworks 0003 0004 SPDX-FileCopyrightText: 2013 Alex Merry <alex.merry@kdemail.net> 0005 SPDX-FileCopyrightText: 2013 John Layt <jlayt@kde.org> 0006 SPDX-FileCopyrightText: 2010 Michael Leupold <lemma@confuego.org> 0007 SPDX-FileCopyrightText: 2009 Michael Pyne <mpyne@kde.org> 0008 SPDX-FileCopyrightText: 2008 Albert Astals Cid <aacid@kde.org> 0009 0010 SPDX-License-Identifier: LGPL-2.0-or-later 0011 */ 0012 0013 #ifndef KFORMAT_H 0014 #define KFORMAT_H 0015 0016 #include <kcoreaddons_export.h> 0017 0018 #include <QLocale> 0019 #include <QSharedPointer> 0020 #include <QString> 0021 0022 class QDate; 0023 class QDateTime; 0024 0025 class KFormatPrivate; 0026 0027 /** 0028 * \file kformat.h 0029 */ 0030 0031 /* 0032 The code in this class was copied from the old KLocale and modified 0033 by John Layt (and also Alex Merry) in the KDELIBS 4 to KDE 0034 Frameworks 5 transition in 2013. 0035 0036 Albert Astals Cid is the original author of formatSpelloutDuration() 0037 originally named KLocale::prettyFormatDuration(). 0038 0039 Michael Pyne is the original author of formatByteSize(). 0040 0041 Michael Leupold is the original author of formatRelativeDate(() 0042 originally part of KFormat::formatDate(). 0043 */ 0044 0045 /** 0046 * @class KFormat kformat.h KFormat 0047 * 0048 * KFormat provides support for formatting numbers and datetimes in 0049 * formats that are not supported by QLocale. 0050 * 0051 * @author John Layt <jlayt@kde.org>, 0052 * Michael Pyne <mpyne@kde.org>, 0053 * Albert Astals Cid <aacid@kde.org>, 0054 * 0055 * @short Class for formatting numbers and datetimes. 0056 * @since 5.0 0057 */ 0058 class KCOREADDONS_EXPORT KFormat final 0059 { 0060 Q_GADGET 0061 0062 public: 0063 /** 0064 * These binary units are used in KDE by the formatByteSize() 0065 * function. 0066 * 0067 * NOTE: There are several different units standards: 0068 * 1) SI (i.e. metric), powers-of-10. 0069 * 2) IEC, powers-of-2, with specific units KiB, MiB, etc. 0070 * 3) JEDEC, powers-of-2, used for solid state memory sizing which 0071 * is why you see flash cards labels as e.g. 4GB. These (ab)use 0072 * the metric units. Although JEDEC only defines KB, MB, GB, if 0073 * JEDEC is selected all units will be powers-of-2 with metric 0074 * prefixes for clarity in the event of sizes larger than 1024 GB. 0075 * 0076 * Although 3 different dialects are possible this enum only uses 0077 * metric names since adding all 3 different names of essentially the same 0078 * unit would be pointless. Use BinaryUnitDialect to control the exact 0079 * units returned. 0080 * 0081 * @see BinaryUnitDialect 0082 * @see formatByteSize 0083 */ 0084 enum BinarySizeUnits { 0085 /// Auto-choose a unit such that the result is in the range [0, 1000 or 1024) 0086 DefaultBinaryUnits = -1, 0087 0088 // The first real unit must be 0 for the current implementation! 0089 UnitByte, ///< B 1 byte 0090 UnitKiloByte, ///< KiB/KB/kB 1024/1000 bytes. 0091 UnitMegaByte, ///< MiB/MB/MB 2^20/10^06 bytes. 0092 UnitGigaByte, ///< GiB/GB/GB 2^30/10^09 bytes. 0093 UnitTeraByte, ///< TiB/TB/TB 2^40/10^12 bytes. 0094 UnitPetaByte, ///< PiB/PB/PB 2^50/10^15 bytes. 0095 UnitExaByte, ///< EiB/EB/EB 2^60/10^18 bytes. 0096 UnitZettaByte, ///< ZiB/ZB/ZB 2^70/10^21 bytes. 0097 UnitYottaByte, ///< YiB/YB/YB 2^80/10^24 bytes. 0098 UnitLastUnit = UnitYottaByte, 0099 }; 0100 0101 /** 0102 * These units are used in KDE by the formatValue() function. 0103 * 0104 * @see formatValue 0105 * @since 5.49 0106 */ 0107 enum class Unit { 0108 Other, 0109 Bit, ///< "bit" 0110 Byte, ///< "B" 0111 Meter, ///< "m" 0112 Hertz, ///< "Hz" 0113 }; 0114 0115 /** 0116 * These prefixes are used in KDE by the formatValue() 0117 * function. 0118 * 0119 * IEC prefixes are only defined for integral units of information, e.g. 0120 * bits and bytes. 0121 * 0122 * @see BinarySizeUnits 0123 * @see formatValue 0124 * @since 5.49 0125 */ 0126 enum class UnitPrefix { 0127 /// Auto-choose a unit such that the result is in the range [0, 1000 or 1024) 0128 AutoAdjust = -128, 0129 0130 Yocto = 0, ///< --/-/y 10^-24 0131 Zepto, ///< --/-/z 10^-21 0132 Atto, ///< --/-/a 10^-18 0133 Femto, ///< --/-/f 10^-15 0134 Pico, ///< --/-/p 10^-12 0135 Nano, ///< --/-/n 10^-9 0136 Micro, ///< --/-/ยต 10^-6 0137 Milli, ///< --/-/m 10^-3 0138 Centi, ///< --/-/c 0.01 0139 Deci, ///< --/-/d 0.1 0140 Unity, ///< "" 1 0141 Deca, ///< --/-/da 10 0142 Hecto, ///< --/-/h 100 0143 Kilo, ///< Ki/K/k 1024/1000 0144 Mega, ///< Mi/M/M 2^20/10^06 0145 Giga, ///< Gi/G/G 2^30/10^09 0146 Tera, ///< Ti/T/T 2^40/10^12 0147 Peta, ///< Pi/P/P 2^50/10^15 0148 Exa, ///< Ei/E/E 2^60/10^18 0149 Zetta, ///< Zi/Z/Z 2^70/10^21 0150 Yotta, ///< Yi/Y/Y 2^80/10^24 0151 }; 0152 0153 /** 0154 * This enum chooses what dialect is used for binary units. 0155 * 0156 * Note: Although JEDEC abuses the metric prefixes and can therefore be 0157 * confusing, it has been used to describe *memory* sizes for quite some time 0158 * and programs should therefore use either Default, JEDEC, or IEC 60027-2 0159 * for memory sizes. 0160 * 0161 * On the other hand network transmission rates are typically in metric so 0162 * Default, Metric, or IEC (which is unambiguous) should be chosen. 0163 * 0164 * Normally choosing DefaultBinaryDialect is the best option as that uses 0165 * the user's selection for units. If the user has not selected a preference, 0166 * IECBinaryDialect will typically be used. 0167 * 0168 * @see BinarySizeUnits 0169 * @see formatByteSize 0170 */ 0171 enum BinaryUnitDialect { 0172 DefaultBinaryDialect = -1, ///< Used if no specific preference 0173 IECBinaryDialect, ///< KiB, MiB, etc. 2^(10*n) 0174 JEDECBinaryDialect, ///< KB, MB, etc. 2^(10*n) 0175 MetricBinaryDialect, ///< SI Units, kB, MB, etc. 10^(3*n) 0176 LastBinaryDialect = MetricBinaryDialect, 0177 }; 0178 0179 /** 0180 * Format flags for formatDuration() 0181 * @see DurationFormatOptions 0182 */ 0183 enum DurationFormatOption { 0184 DefaultDuration = 0x0, ///< Default formatting in localized 1:23:45 format 0185 InitialDuration = 0x1, ///< Default formatting in localized 1h23m45s format 0186 ShowMilliseconds = 0x2, ///< Include milliseconds in format, e.g. 1:23:45.678 0187 HideSeconds = 0x4, ///< Hide the seconds, e.g. 1:23 or 1h23m, overrides ShowMilliseconds 0188 FoldHours = 0x8, ///< Fold the hours into the minutes, e.g. 83:45 or 83m45s, overrides HideSeconds 0189 }; 0190 /** 0191 * Stores a combination of #DurationFormatOption values. 0192 */ 0193 Q_DECLARE_FLAGS(DurationFormatOptions, DurationFormatOption) 0194 Q_FLAG(DurationFormatOption) 0195 0196 /** 0197 * Constructs a KFormat. 0198 * 0199 * @param locale the locale to use, defaults to the system locale 0200 */ 0201 explicit KFormat(const QLocale &locale = QLocale()); 0202 0203 /** 0204 * Copy constructor 0205 */ 0206 KFormat(const KFormat &other); 0207 0208 KFormat &operator=(const KFormat &other); 0209 0210 /** 0211 * Destructor 0212 */ 0213 ~KFormat(); 0214 0215 /** 0216 * Converts @p size from bytes to the appropriate string representation 0217 * using the binary unit dialect @p dialect and the specific units @p units. 0218 * 0219 * Example: 0220 * @code 0221 * QString metric, iec, jedec, small; 0222 * metric = formatByteSize(1000, 1, KFormat::MetricBinaryDialect, KFormat::UnitKiloByte); 0223 * iec = formatByteSize(1024, 1, KFormat::IECBinaryDialect, KFormat::UnitKiloByte); 0224 * jedec = formatByteSize(1024, 1, KFormat::JEDECBinaryDialect, KFormat::UnitKiloByte); 0225 * small = formatByteSize(100); 0226 * // metric == "1.0 kB", iec == "1.0 KiB", jedec == "1.0 KB", small == "100 B" 0227 * @endcode 0228 * 0229 * @param size size in bytes 0230 * @param precision number of places after the decimal point to use. KDE uses 0231 * 1 by default so when in doubt use 1. Whenever KFormat::UnitByte is used 0232 * (either explicitly or autoselected from KFormat::DefaultBinaryUnits), 0233 * the fractional part is always omitted. 0234 * @param dialect binary unit standard to use. Use DefaultBinaryDialect to 0235 * use the localized user selection unless you need to use a specific 0236 * unit type (such as displaying a flash memory size in JEDEC). 0237 * @param units specific unit size to use in result. Use 0238 * DefaultBinaryUnits to automatically select a unit that will return 0239 * a sanely-sized number. 0240 * @return converted size as a translated string including the units. 0241 * E.g. "1.23 KiB", "2 GB" (JEDEC), "4.2 kB" (Metric). 0242 * @see BinarySizeUnits 0243 * @see BinaryUnitDialect 0244 */ 0245 0246 QString formatByteSize(double size, 0247 int precision = 1, 0248 KFormat::BinaryUnitDialect dialect = KFormat::DefaultBinaryDialect, 0249 KFormat::BinarySizeUnits units = KFormat::DefaultBinaryUnits) const; 0250 0251 /** 0252 * Given a number of milliseconds, converts that to a string containing 0253 * the localized equivalent, e.g. 1:23:45 0254 * 0255 * @param msecs Time duration in milliseconds 0256 * @param options options to use in the duration format 0257 * @return converted duration as a string - e.g. "1:23:45" "1h23m" 0258 */ 0259 0260 QString formatDuration(quint64 msecs, KFormat::DurationFormatOptions options = KFormat::DefaultDuration) const; 0261 0262 /** 0263 * Given a number of milliseconds, converts that to a string containing 0264 * the localized equivalent to the requested decimal places. 0265 * 0266 * e.g. given formatDuration(60000), returns "1.0 minutes" 0267 * 0268 * @param msecs Time duration in milliseconds 0269 * @param decimalPlaces Decimal places to round off to, defaults to 2 0270 * @return converted duration as a string - e.g. "5.5 seconds" "23.0 minutes" 0271 */ 0272 0273 QString formatDecimalDuration(quint64 msecs, int decimalPlaces = 2) const; 0274 0275 /** 0276 * Given a number of milliseconds, converts that to a spell-out string containing 0277 * the localized equivalent. 0278 * 0279 * e.g. given formatSpelloutDuration(60001) returns "1 minute" 0280 * given formatSpelloutDuration(62005) returns "1 minute and 2 seconds" 0281 * given formatSpelloutDuration(90060000) returns "1 day and 1 hour" 0282 * 0283 * @param msecs Time duration in milliseconds 0284 * @return converted duration as a string. 0285 * Units not interesting to the user, for example seconds or minutes when the first 0286 * unit is day, are not returned because they are irrelevant. The same applies for 0287 * seconds when the first unit is hour. 0288 */ 0289 QString formatSpelloutDuration(quint64 msecs) const; 0290 0291 /** 0292 * Returns a string formatted to a relative date style. 0293 * 0294 * If the @p date falls within one week before or after the current date 0295 * then a relative date string will be returned, such as: 0296 * * Yesterday 0297 * * Today 0298 * * Tomorrow 0299 * * Last Tuesday 0300 * * Next Wednesday 0301 * 0302 * If the @p date falls outside this period then the @p format is used. 0303 * 0304 * @param date the date to be formatted 0305 * @param format the date format to use 0306 * 0307 * @return the date as a string 0308 */ 0309 QString formatRelativeDate(const QDate &date, QLocale::FormatType format) const; 0310 0311 /** 0312 * Returns a string formatted to a relative datetime style. 0313 * 0314 * If the @p dateTime falls within one week before or after the current date 0315 * then a relative date string will be returned, such as: 0316 * * Yesterday at 3:00pm 0317 * * Today at 3:00pm 0318 * * Tomorrow at 3:00pm 0319 * * Last Tuesday at 3:00pm 0320 * * Next Wednesday at 3:00pm 0321 * 0322 * If the @p dateTime falls within one hour of the current time. 0323 * Then a shorter version is displayed: 0324 * * Just a moment ago (for within the same minute) 0325 * * 15 minutes ago 0326 * 0327 * If the @p dateTime falls outside this period then the date is rendered as: 0328 * * Monday, 7 September, 2021 at 7:00 PM : date formatted @p format + " at " + time formatted with @p format 0329 * 0330 * With @p format LongFormat, time format used is set to ShortFormat (to omit timezone and seconds). 0331 * 0332 * First character is capitalized. 0333 * 0334 * @param dateTime the date to be formatted 0335 * @param format the date format to use 0336 * 0337 * @return the date as a string 0338 */ 0339 QString formatRelativeDateTime(const QDateTime &dateTime, QLocale::FormatType format) const; 0340 0341 /** 0342 * Converts @p value to the appropriate string representation 0343 * 0344 * Example: 0345 * @code 0346 * // sets formatted to "1.0 kbit" 0347 * auto formatted = format.formatValue(1000, KFormat::Unit::Bit, 1, KFormat::UnitPrefix::Kilo); 0348 * @endcode 0349 * 0350 * @param value value to be formatted 0351 * @param precision number of places after the decimal point to use. KDE uses 0352 * 1 by default so when in doubt use 1. 0353 * @param unit unit to use in result. 0354 * @param prefix specific prefix to use in result. Use UnitPrefix::AutoAdjust 0355 * to automatically select an appropriate prefix. 0356 * @param dialect prefix standard to use. Use DefaultBinaryDialect to 0357 * use the localized user selection unless you need to use a specific 0358 * unit type. Only meaningful for KFormat::Unit::Byte, and ignored for 0359 * all other units. 0360 * @return converted size as a translated string including prefix and unit. 0361 * E.g. "1.23 KiB", "2 GB" (JEDEC), "4.2 kB" (Metric), "1.2 kbit". 0362 * @see Unit 0363 * @see UnitPrefix 0364 * @see BinaryUnitDialect 0365 * @since 5.49 0366 */ 0367 QString formatValue(double value, 0368 KFormat::Unit unit, 0369 int precision = 1, 0370 KFormat::UnitPrefix prefix = KFormat::UnitPrefix::AutoAdjust, 0371 KFormat::BinaryUnitDialect dialect = KFormat::DefaultBinaryDialect) const; 0372 0373 /** 0374 * Converts @p value to the appropriate string representation 0375 * 0376 * Example: 0377 * @code 0378 * QString bits, slow, fast; 0379 * // sets bits to "1.0 kbit", slow to "1.0 kbit/s" and fast to "12.3 Mbit/s". 0380 * bits = format.formatValue(1000, QStringLiteral("bit"), 1, KFormat::UnitPrefix::Kilo); 0381 * slow = format.formatValue(1000, QStringLiteral("bit/s"); 0382 * fast = format.formatValue(12.3e6, QStringLiteral("bit/s"); 0383 * @endcode 0384 * 0385 * @param value value to be formatted 0386 * @param precision number of places after the decimal point to use. KDE uses 0387 * 1 by default so when in doubt use 1. 0388 * @param unit unit to use in result. 0389 * @param prefix specific prefix to use in result. Use UnitPrefix::AutoAdjust 0390 * to automatically select an appropriate prefix. 0391 * @return converted size as a translated string including prefix and unit. 0392 * E.g. "1.2 kbit", "2.4 kB", "12.3 Mbit/s" 0393 * @see UnitPrefix 0394 * @since 5.49 0395 */ 0396 QString formatValue(double value, const QString &unit, int precision = 1, KFormat::UnitPrefix prefix = KFormat::UnitPrefix::AutoAdjust) const; 0397 /** 0398 * Converts @p value to the appropriate string representation. 0399 * 0400 * Example: 0401 * @code 0402 * QString iec, jedec, metric; 0403 * // Sets iec to "1.0 KiB/s", jedec to "1.0 KB/s" and metric to "1.0 kB/s" 0404 * iec = format.formatValue(1024, QStringLiteral("B/s"), 1, KFormat::UnitPrefix::AutoAdjust, KFormat::IECBinaryDialect); 0405 * jedec = format.formatValue(1024, QStringLiteral("B/s"), 1, KFormat::UnitPrefix::AutoAdjust, KFormat::JEDECBinaryDialect); 0406 * metric = format.formatValue(1000, QStringLiteral("B/s"), 1, KFormat::UnitPrefix::AutoAdjust, KFormat::MetricBinaryDialect); 0407 * @endcode 0408 * 0409 * @param value value to be formatted 0410 * @param precision number of places after the decimal point to use. 1 is used by default; when 0411 * in doubt use 1 0412 * @param unit unit to use in result 0413 * @param prefix specific prefix to use in result. Use UnitPrefix::AutoAdjust 0414 * to automatically select an appropriate prefix 0415 * @param dialect prefix standard to use. Use DefaultBinaryDialect to 0416 * use the localized user selection unless you need to use a specific 0417 * unit type 0418 * @return converted size as a translated string including prefix and unit. 0419 * E.g. "1.2 kbit", "2.4 kB", "12.3 Mbit/s" 0420 * @see UnitPrefix 0421 * @since 5.74 0422 */ 0423 QString formatValue(double value, const QString &unit, int precision, KFormat::UnitPrefix prefix, KFormat::BinaryUnitDialect dialect) const; 0424 0425 private: 0426 QSharedDataPointer<KFormatPrivate> d; 0427 }; 0428 0429 #endif // KFORMAT_H