KMime

kmime_dateformatter.cpp
Go to the documentation of this file.
1 /*
2  kmime_dateformatter.cpp
3 
4  KMime, the KDE Internet mail/usenet news message library.
5  SPDX-FileCopyrightText: 2001 the KMime authors.
6  See file AUTHORS for details
7 
8  SPDX-License-Identifier: LGPL-2.0-or-later
9 */
10 /**
11  @file
12  This file is part of the API for handling @ref MIME data and
13  defines the DateFormatter class.
14 
15  @brief
16  Defines the DateFormatter class.
17 
18  @authors the KMime authors (see AUTHORS file)
19 */
20 
21 #include "kmime_dateformatter.h"
22 
23 #include <config-kmime.h>
24 
25 #include <QTextStream>
26 
27 #include <KLocalizedString>
28 
29 using namespace KMime;
30 
31 namespace KMime {
32 
33 class DateFormatterPrivate {
34 public:
35  DateFormatterPrivate()
36  {}
37 
38  /**
39  Returns a QString containing the specified time_t @p t formatted
40  using the #Fancy #FormatType.
41 
42  @param t is the time_t to use for formatting.
43  */
44  QString fancy(time_t t);
45 
46  /**
47  Returns a QString containing the specified time_t @p t formatted
48  using the #Localized #FormatType.
49 
50  @param t is the time_t to use for formatting.
51  @param shortFormat if true, create the short version of the date string.
52  @param lang is a QString containing the language to use.
53  */
54  static QString localized(time_t t, bool shortFormat = true, const QString &lang = QString());
55 
56  /**
57  Returns a QString containing the specified time_t @p t formatted
58  with the ctime() function.
59 
60  @param t is the time_t to use for formatting.
61  */
62  static QString cTime(time_t t);
63 
64  /**
65  Returns a QString containing the specified time_t @p t in the
66  "%Y-%m-%d %H:%M:%S" #Iso #FormatType.
67 
68  @param t is the time_t to use for formatting.
69  */
70  static QString isoDate(time_t t);
71 
72  /**
73  Returns a QString containing the specified time_t @p t in the
74  #Rfc #FormatType.
75 
76  @param t is the time_t to use for formatting.
77  */
78  static QString rfc2822(time_t t);
79 
80  /**
81  Returns a QString containing the specified time_t @p t formatted
82  with a previously specified custom format.
83 
84  @param t time used for formatting
85  */
86  QString custom(time_t t) const;
87 
88  /**
89  Returns a QString that identifies the timezone (eg."-0500")
90  of the specified time_t @p t.
91 
92  @param t time to compute timezone from.
93  */
94  static QByteArray zone(time_t t);
95 
97  time_t mTodayOneSecondBeforeMidnight = 0;
98  QString mCustomFormat;
99 };
100 
101 }
102 
104  d(new DateFormatterPrivate)
105 {
106  d->mFormat = ftype;
107 }
108 
110 {
111  delete d;
112 }
113 
115 {
116  return d->mFormat;
117 }
118 
120 {
121  d->mFormat = ftype;
122 }
123 
124 QString DateFormatter::dateString(time_t t, const QString &lang, bool shortFormat) const
125 {
126  switch (d->mFormat) {
127  case Fancy:
128  return d->fancy(t);
129  case Localized:
130  return d->localized(t, shortFormat, lang);
131  case CTime:
132  return d->cTime(t);
133  case Iso:
134  return d->isoDate(t);
135  case Rfc:
136  return d->rfc2822(t);
137  case Custom:
138  return d->custom(t);
139  }
140  return QString();
141 }
142 
143 QString DateFormatter::dateString(const QDateTime &dt, const QString &lang, bool shortFormat) const
144 {
145  return dateString(dt.toLocalTime().toSecsSinceEpoch(), lang, shortFormat);
146 }
147 
148 QString DateFormatterPrivate::rfc2822(time_t t)
149 {
150  QDateTime tmp;
151  QString ret;
152 
153  tmp.setSecsSinceEpoch(t);
154 
155  ret = tmp.toString(QStringLiteral("ddd, dd MMM yyyy hh:mm:ss "));
156  ret += QLatin1String(zone(t));
157 
158  return ret;
159 }
160 
161 QString DateFormatterPrivate::custom(time_t t) const
162 {
163  if (mCustomFormat.isEmpty()) {
164  return QString();
165  }
166 
167  int z = mCustomFormat.indexOf(QLatin1Char('Z'));
168  QDateTime dt;
169  QString ret = mCustomFormat;
170 
171  dt.setSecsSinceEpoch(t);
172  if (z != -1) {
173  ret.replace(z, 1, QLatin1String(zone(t)));
174  }
175 
176  ret = dt.toString(ret);
177 
178  return ret;
179 }
180 
182 {
183  d->mCustomFormat = format;
184  d->mFormat = Custom;
185 }
186 
188 {
189  return d->mCustomFormat;
190 }
191 
192 QByteArray DateFormatterPrivate::zone(time_t t)
193 {
194 #if defined(HAVE_TIMEZONE) || defined(HAVE_TM_GMTOFF)
195  struct tm *local = localtime(&t);
196 #endif
197 
198 #if defined(HAVE_TIMEZONE)
199 
200  //hmm, could make hours & mins static
201  int secs = qAbs(timezone);
202  int neg = (timezone > 0) ? 1 : 0;
203  int hours = secs / 3600;
204  int mins = (secs - hours * 3600) / 60;
205 
206  // adjust to daylight
207  if (local->tm_isdst > 0) {
208  if (neg) {
209  --hours;
210  } else {
211  ++hours;
212  }
213  }
214 
215 #elif defined(HAVE_TM_GMTOFF)
216 
217  int secs = qAbs(local->tm_gmtoff);
218  int neg = (local->tm_gmtoff < 0) ? 1 : 0;
219  int hours = secs / 3600;
220  int mins = (secs - hours * 3600) / 60;
221 
222 #else
223 
224  QDateTime d1 = QDateTime::fromString(QString::fromLatin1(asctime(gmtime(&t))));
225  QDateTime d2 = QDateTime::fromString(QString::fromLatin1(asctime(localtime(&t))));
226  int secs = d1.secsTo(d2);
227  int neg = (secs < 0) ? 1 : 0;
228  secs = qAbs(secs);
229  int hours = secs / 3600;
230  int mins = (secs - hours * 3600) / 60;
231 
232 #endif /* HAVE_TIMEZONE */
233 
234  QByteArray ret;
236  s << (neg ? '-' : '+')
237  << qSetFieldWidth(2) << qSetPadChar(QLatin1Char('0'))
238  << Qt::right
239  << hours << mins;
240  //old code: ret.sprintf( "%c%.2d%.2d", (neg) ? '-' : '+', hours, mins );
241 
242  return ret;
243 }
244 
245 QString DateFormatterPrivate::fancy(time_t t)
246 {
247  auto locale = QLocale::system();
248 
249  if (t <= 0) {
250  return i18nc("invalid time specified", "unknown");
251  }
252 
253  if (mTodayOneSecondBeforeMidnight < time(nullptr)) {
254  // determine time_t value of today 23:59:59
255  const QDateTime today(QDate::currentDate(), QTime(23, 59, 59));
256  mTodayOneSecondBeforeMidnight = today.toSecsSinceEpoch();
257  }
258 
259  QDateTime old;
260  old.setSecsSinceEpoch(t);
261 
262  if (mTodayOneSecondBeforeMidnight >= t) {
263  const time_t diff = mTodayOneSecondBeforeMidnight - t;
264  if (diff < 7 * 24 * 60 * 60) {
265  if (diff < 24 * 60 * 60) {
266  return i18n("Today %1",
267  locale.toString(old.time(), QLocale::ShortFormat));
268  }
269  if (diff < 2 * 24 * 60 * 60) {
270  return i18n("Yesterday %1",
271  locale.toString(old.time(), QLocale::ShortFormat));
272  }
273  for (int i = 3; i < 8; i++) {
274  if (diff < i * 24 * 60 * 60) {
275  return i18nc("1. weekday, 2. time", "%1 %2" ,
276  locale.dayName(old.date().dayOfWeek(), QLocale::LongFormat),
277  locale.toString(old.time(), QLocale::ShortFormat));
278  }
279  }
280  }
281  }
282 
283  return locale.toString(old, QLocale::ShortFormat);
284 }
285 
286 QString DateFormatterPrivate::localized(time_t t, bool shortFormat, const QString &lang)
287 {
288  QDateTime tmp;
289  QString ret;
290  auto locale = QLocale::system();
291 
292  tmp.setSecsSinceEpoch(t);
293 
294  if (!lang.isEmpty()) {
295  locale = QLocale(lang);
296  ret = locale.toString(tmp, (shortFormat ? QLocale::ShortFormat : QLocale::LongFormat));
297  } else {
298  ret = locale.toString(tmp, (shortFormat ? QLocale::ShortFormat : QLocale::LongFormat));
299  }
300 
301  return ret;
302 }
303 
304 QString DateFormatterPrivate::cTime(time_t t)
305 {
306  return QString::fromLatin1(ctime(&t)).trimmed();
307 }
308 
309 QString DateFormatterPrivate::isoDate(time_t t)
310 {
311  char cstr[64];
312  strftime(cstr, 63, "%Y-%m-%d %H:%M:%S", localtime(&t));
313  return QLatin1String(cstr);
314 }
315 
317  const QString &data, bool shortFormat)
318 {
319  DateFormatter f(ftype);
320  if (ftype == Custom) {
321  f.setCustomFormat(data);
322  }
323  return f.dateString(t, data, shortFormat);
324 }
325 
326 QString DateFormatter::formatCurrentDate(FormatType ftype, const QString &data, bool shortFormat)
327 {
328  DateFormatter f(ftype);
329  if (ftype == Custom) {
330  f.setCustomFormat(data);
331  }
332  return f.dateString(time(nullptr), data, shortFormat);
333 }
FormatType format() const
Returns the FormatType currently set.
QString toString(Qt::DateFormat format) const const
~DateFormatter()
Destroys the date formatter.
iso "2002-03-31 02:08:35"
This file is part of the API for handling MIME data and defines the DateFormatter class...
QString customFormat() const
Returns the custom format string.
A class for abstracting date formatting.
QTextStream & right(QTextStream &stream)
localized "2002-03-31 02:08"
QTime time() const const
ctime "Sun Mar 31 02:08:35 2002"
QLocale system()
int dayOfWeek() const const
rfc "Sun, 31 Mar 2002 02:08:35 -0500"
QString i18nc(const char *context, const char *text, const TYPE &arg...)
bool isEmpty() const const
QString trimmed() const const
custom "whatever you like"
static QString formatCurrentDate(DateFormatter::FormatType ftype, const QString &data=QString(), bool shortFormat=true)
Convenience function, same as formatDate() but returns the current time formatted.
void setSecsSinceEpoch(qint64 secs)
QDateTime fromString(const QString &string, Qt::DateFormat format)
QString i18n(const char *text, const TYPE &arg...)
QString & replace(int position, int n, QChar after)
FormatType
The different types of date formats.
QDate date() const const
qint64 secsTo(const QDateTime &other) const const
qint64 toSecsSinceEpoch() const const
QDate currentDate()
static QString formatDate(DateFormatter::FormatType ftype, time_t t, const QString &data=QString(), bool shortFormat=true)
Convenience function dateString.
QString fromLatin1(const char *str, int size)
QDateTime toLocalTime() const const
DateFormatter(FormatType ftype=DateFormatter::Fancy)
Constructs a date formatter with a default FormatType.
void setFormat(FormatType ftype)
Sets the date format to ftype.
QString dateString(time_t t, const QString &lang=QString(), bool shortFormat=true) const
Constructs a formatted date string from time_t t.
fancy "Today 02:08:35"
void setCustomFormat(const QString &format)
Sets the custom format for date to string conversions to format.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Sep 27 2021 23:15:57 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.