File indexing completed on 2024-04-21 16:06:16
0001 /* 0002 kmime_dateformatter.cpp 0003 0004 KMime, the KDE Internet mail/usenet news message library. 0005 SPDX-FileCopyrightText: 2001 the KMime authors. 0006 See file AUTHORS for details 0007 0008 SPDX-License-Identifier: LGPL-2.0-or-later 0009 */ 0010 /** 0011 @file 0012 This file is part of the API for handling @ref MIME data and 0013 defines the DateFormatter class. 0014 0015 @brief 0016 Defines the DateFormatter class. 0017 0018 @authors the KMime authors (see AUTHORS file) 0019 */ 0020 0021 #include "kmime_dateformatter.h" 0022 0023 #include <KLocalizedString> 0024 0025 using namespace KMime; 0026 0027 namespace KMime { 0028 0029 class DateFormatterPrivate { 0030 public: 0031 DateFormatterPrivate() 0032 {} 0033 0034 /** 0035 Returns a QString containing the specified time @p t formatted 0036 using the #Fancy #FormatType. 0037 0038 @param t is the time to use for formatting. 0039 */ 0040 QString fancy(const QDateTime &t); 0041 0042 /** 0043 Returns a QString containing the specified time @p t formatted 0044 using the #Localized #FormatType. 0045 0046 @param t is the time to use for formatting. 0047 @param shortFormat if true, create the short version of the date string. 0048 @param lang is a QString containing the language to use. 0049 */ 0050 static QString localized(const QDateTime &t, bool shortFormat = true, const QString &lang = QString()); 0051 0052 /** 0053 Returns a QString containing the specified time @p t formatted 0054 with the ctime() function. 0055 0056 @param t is the time to use for formatting. 0057 */ 0058 static QString cTime(const QDateTime &t); 0059 0060 /** 0061 Returns a QString containing the specified time @p t formatted 0062 with a previously specified custom format. 0063 0064 @param t time used for formatting 0065 */ 0066 QString custom(const QDateTime &t) const; 0067 0068 /** 0069 Returns a QString that identifies the timezone (eg."-0500") 0070 of the specified time @p t. 0071 0072 @param t time to compute timezone from. 0073 */ 0074 static QByteArray zone(const QDateTime &t); 0075 0076 DateFormatter::FormatType mFormat; 0077 QDateTime mTodayOneSecondBeforeMidnight; 0078 QString mCustomFormat; 0079 }; 0080 0081 } 0082 0083 DateFormatter::DateFormatter(FormatType ftype) : 0084 d(new DateFormatterPrivate) 0085 { 0086 d->mFormat = ftype; 0087 } 0088 0089 DateFormatter::~DateFormatter() = default; 0090 0091 DateFormatter::FormatType DateFormatter::format() const 0092 { 0093 return d->mFormat; 0094 } 0095 0096 void DateFormatter::setFormat(FormatType ftype) 0097 { 0098 d->mFormat = ftype; 0099 } 0100 0101 QString DateFormatter::dateString(const QDateTime &dt, const QString &lang, bool shortFormat) const 0102 { 0103 switch (d->mFormat) { 0104 case Fancy: 0105 return d->fancy(dt); 0106 case Localized: 0107 return d->localized(dt, shortFormat, lang); 0108 case CTime: 0109 return d->cTime(dt); 0110 case Custom: 0111 return d->custom(dt); 0112 } 0113 return {}; 0114 } 0115 0116 QString DateFormatterPrivate::custom(const QDateTime &t) const 0117 { 0118 if (mCustomFormat.isEmpty()) { 0119 return {}; 0120 } 0121 0122 int z = mCustomFormat.indexOf(QLatin1Char('Z')); 0123 QDateTime dt; 0124 QString ret = mCustomFormat; 0125 0126 if (z != -1) { 0127 ret.replace(z, 1, QLatin1StringView(zone(t))); 0128 } 0129 0130 ret = t.toString(ret); 0131 0132 return ret; 0133 } 0134 0135 void DateFormatter::setCustomFormat(const QString &format) 0136 { 0137 d->mCustomFormat = format; 0138 d->mFormat = Custom; 0139 } 0140 0141 QString DateFormatter::customFormat() const 0142 { 0143 return d->mCustomFormat; 0144 } 0145 0146 QByteArray DateFormatterPrivate::zone(const QDateTime &t) 0147 { 0148 const auto secs = t.offsetFromUtc(); 0149 const auto hours = std::abs(secs / 3600); 0150 const auto mins = std::abs((secs - hours * 3600) / 60); 0151 0152 QByteArray ret(6, 0); 0153 qsnprintf(ret.data(), ret.size(), "%c%.2d%.2d", (secs < 0) ? '-' : '+', hours, mins); 0154 ret.chop(1); 0155 return ret; 0156 } 0157 0158 QString DateFormatterPrivate::fancy(const QDateTime &t) 0159 { 0160 if (!t.isValid()) { 0161 return i18nc("invalid time specified", "unknown"); 0162 } 0163 0164 if (!mTodayOneSecondBeforeMidnight.isValid()) { 0165 // determine time of today 23:59:59 0166 mTodayOneSecondBeforeMidnight = QDateTime(QDate::currentDate(), QTime(23, 59, 59)); 0167 } 0168 0169 QDateTime old(t); 0170 0171 if (mTodayOneSecondBeforeMidnight >= t) { 0172 const auto diff = t.secsTo(mTodayOneSecondBeforeMidnight); 0173 if (diff < 7 * 24 * 60 * 60) { 0174 if (diff < 24 * 60 * 60) { 0175 return i18n("Today %1", 0176 QLocale().toString(old.time(), QLocale::ShortFormat)); 0177 } 0178 if (diff < 2 * 24 * 60 * 60) { 0179 return i18n("Yesterday %1", 0180 QLocale().toString(old.time(), QLocale::ShortFormat)); 0181 } 0182 for (int i = 3; i < 8; i++) { 0183 if (diff < i * 24 * 60 * 60) { 0184 return i18nc("1. weekday, 2. time", "%1 %2" , 0185 QLocale().dayName(old.date().dayOfWeek(), QLocale::LongFormat), 0186 QLocale().toString(old.time(), QLocale::ShortFormat)); 0187 } 0188 } 0189 } 0190 } 0191 0192 return QLocale().toString(old, QLocale::ShortFormat); 0193 } 0194 0195 QString DateFormatterPrivate::localized(const QDateTime &t, bool shortFormat, const QString &lang) 0196 { 0197 QString ret; 0198 0199 if (!lang.isEmpty()) { 0200 ret = QLocale(lang).toString(t, (shortFormat ? QLocale::ShortFormat : QLocale::LongFormat)); 0201 } else { 0202 ret = QLocale().toString(t, (shortFormat ? QLocale::ShortFormat : QLocale::LongFormat)); 0203 } 0204 0205 return ret; 0206 } 0207 0208 QString DateFormatterPrivate::cTime(const QDateTime &t) 0209 { 0210 return t.toString(QStringLiteral("ddd MMM dd hh:mm:ss yyyy")); 0211 } 0212 0213 QString DateFormatter::formatDate(FormatType ftype, const QDateTime &t, 0214 const QString &data, bool shortFormat) 0215 { 0216 DateFormatter f(ftype); 0217 if (ftype == Custom) { 0218 f.setCustomFormat(data); 0219 } 0220 return f.dateString(t, data, shortFormat); 0221 } 0222 0223 QString DateFormatter::formatCurrentDate(FormatType ftype, const QString &data, bool shortFormat) 0224 { 0225 DateFormatter f(ftype); 0226 if (ftype == Custom) { 0227 f.setCustomFormat(data); 0228 } 0229 return f.dateString(QDateTime::currentDateTime(), data, shortFormat); 0230 }