MythTV  master
mythdate.cpp
Go to the documentation of this file.
1 #include <array>
2 
3 #include <QtGlobal>
4 #include <QCoreApplication>
5 #include <QRegularExpression>
6 #include <QTimeZone>
7 
8 #include "mythcorecontext.h"
9 #include "mythdate.h"
10 #include "stringutil.h"
11 
12 namespace MythDate
13 {
14 
15 QDateTime current(bool stripped)
16 {
17  QDateTime rettime = QDateTime::currentDateTimeUtc();
18  if (stripped)
19  rettime = rettime.addMSecs(-rettime.time().msec());
20  return rettime;
21 }
22 
23 QString current_iso_string(bool stripped)
24 {
25  return MythDate::current(stripped).toString(Qt::ISODate);
26 }
27 
28 QDateTime as_utc(const QDateTime &old_dt)
29 {
30  QDateTime dt(old_dt);
31 #if QT_VERSION < QT_VERSION_CHECK(6,5,0)
32  dt.setTimeSpec(Qt::UTC);
33 #else
34  dt.setTimeZone(QTimeZone(QTimeZone::UTC));
35 #endif
36  return dt;
37 }
38 
39 QDateTime fromString(const QString &dtstr)
40 {
41  QDateTime dt;
42  if (dtstr.isEmpty())
43  return as_utc(dt);
44 
45  if (!dtstr.contains("-") && dtstr.length() == 14)
46  {
47  // must be in yyyyMMddhhmmss format
48  dt = QDateTime::fromString(dtstr, "yyyyMMddhhmmss");
49  }
50  else
51  {
53  }
54 
55  return as_utc(dt);
56 }
57 
58 MBASE_PUBLIC QDateTime fromString(const QString &str, const QString &format)
59 {
60  QDateTime dt = QDateTime::fromString(str, format);
61 #if QT_VERSION < QT_VERSION_CHECK(6,5,0)
62  dt.setTimeSpec(Qt::UTC);
63 #else
64  dt.setTimeZone(QTimeZone(QTimeZone::UTC));
65 #endif
66  return dt;
67 }
68 
81 MBASE_PUBLIC QDateTime fromSecsSinceEpoch(int64_t seconds)
82 {
83  QDateTime dt = QDateTime::fromSecsSinceEpoch(seconds);
84  return dt.toUTC();
85 }
86 
93 QString toString(const QDateTime &raw_dt, uint format)
94 {
95  QString result;
96 
97  if (!raw_dt.isValid())
98  return result;
99 
100  // if no format is set default to UTC for ISO/file/DB dates.
101  if (!((format & kOverrideUTC) || (format & kOverrideLocal)))
102  {
103  format |= ((ISODate|kFilename|kDatabase) & format) ?
105  }
106 
107  QDateTime datetime =
108  (format & kOverrideUTC) ? raw_dt.toUTC() : raw_dt.toLocalTime();
109 
110  if (format & kDatabase)
111  return datetime.toString("yyyy-MM-dd hh:mm:ss");
112 
113  if (format & MythDate::ISODate)
114  return datetime.toString(Qt::ISODate);
115 
116  if (format & MythDate::kRFC822) // RFC 822 - RFC 7231 Sect 7.1.1.1 - HTTP Date
117  return datetime.toUTC().toString("ddd, dd MMM yyyy hh:mm:ss").append(" GMT");
118 
119  if (format & kFilename)
120  return datetime.toString("yyyyMMddhhmmss");
121 
122  if (format & kScreenShotFilename)
123  return datetime.toString("yyyy-MM-ddThh-mm-ss.zzz");
124 
125  if (format & kDateEither)
126  result += toString(datetime.date(), format);
127 
128  if (format & kTime)
129  {
130  if (!result.isEmpty())
131  result.append(", ");
132 
133  QString timeformat = gCoreContext->GetSetting("TimeFormat", "h:mm AP");
134  result += datetime.time().toString(timeformat);
135  }
136 
137  return result;
138 }
139 
145 QString toString(const QDate date, uint format)
146 {
147  QString result;
148 
149  if (!date.isValid())
150  return result;
151 
152  if (format & kDateEither)
153  {
154  QString stringformat;
155  if (format & kDateShort)
156  stringformat = gCoreContext->GetSetting("ShortDateFormat", "ddd d");
157  else
158  stringformat = gCoreContext->GetSetting("DateFormat", "ddd d MMMM");
159 
160  if (format & kAddYear)
161  {
162  if (!stringformat.contains("yy")) // Matches both 2 or 4 digit year
163  stringformat.append(" yyyy");
164  }
165 
166  if (format & kAutoYear)
167  {
168  if (!stringformat.contains("yy") // Matches both 2 or 4 digit year
169  && date.year() != QDateTime::currentDateTime().date().year())
170  stringformat.append(" yyyy");
171  }
172 
173  if (format & ~kDateShort)
174  {
175  QDate now = current().toLocalTime().date();
176  if ((format & kSimplify) && (now == date))
177  result = QCoreApplication::translate("(Common)", "Today");
178  else if (((format & kSimplify) != 0U) && (now.addDays(-1) == date))
179  result = QCoreApplication::translate("(Common)", "Yesterday");
180  else if (((format & kSimplify) != 0U) && (now.addDays(1) == date))
181  result = QCoreApplication::translate("(Common)", "Tomorrow");
182  }
183 
184  if (result.isEmpty())
185  result = gCoreContext->GetQLocale().toString(date, stringformat);
186  }
187 
188  return result;
189 }
190 
195 std::chrono::seconds toSeconds(QTime time)
196 {
197  if (!time.isValid())
198  return 0s;
199 
200  std::chrono::seconds nSecs = std::chrono::hours(time.hour());
201  nSecs += std::chrono::minutes(time.minute());
202  nSecs += std::chrono::seconds(time.second());
203 
204  return nSecs;
205 }
206 
207 std::chrono::milliseconds currentMSecsSinceEpochAsDuration(void)
208 {
209  return std::chrono::milliseconds(QDateTime::currentMSecsSinceEpoch());
210 };
211 
212 std::chrono::seconds secsInPast (const QDateTime& past)
213 {
214  return std::chrono::seconds(past.secsTo(MythDate::current()));
215 }
216 
217 std::chrono::seconds secsInFuture (const QDateTime& future)
218 {
219  return std::chrono::seconds(MythDate::current().secsTo(future));
220 }
221 
242 QString formatTime(std::chrono::milliseconds msecs, QString fmt)
243 {
244  static const QRegularExpression hRe("H+");
245  static const QRegularExpression mRe("m+");
246  static const QRegularExpression sRe("s+");
247  static const QRegularExpression zRe("z+");
248 
249  bool negativeTime = msecs < 0ms;
250  msecs = std::chrono::milliseconds(std::abs(msecs.count()));
251 
252  QRegularExpressionMatch match = hRe.match(fmt);
253  if (match.hasMatch())
254  {
255  int width = match.capturedLength();
256  QString text = StringUtil::intToPaddedString(msecs / 1h, width);
257  fmt.replace(match.capturedStart(), width, text);
258  msecs = msecs % 1h;
259  }
260 
261  match = mRe.match(fmt);
262  if (match.hasMatch())
263  {
264  int width = match.capturedLength();
265  QString text = StringUtil::intToPaddedString(msecs / 1min, width);
266  fmt.replace(match.capturedStart(), width, text);
267  msecs = msecs % 1min;
268  }
269 
270  match = sRe.match(fmt);
271  if (match.hasMatch())
272  {
273  int width = match.capturedLength();
274  QString text = StringUtil::intToPaddedString(msecs / 1s, width);
275  fmt.replace(match.capturedStart(), width, text);
276  }
277 
278  match = zRe.match(fmt);
279  if (match.hasMatch())
280  {
281  static constexpr std::array<int,4> divisor = {1000, 100, 10, 1};
282 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
283  int width = std::min(3, match.capturedLength());
284 #else
285  int width = std::min(3LL, match.capturedLength());
286 #endif
287  int value = (msecs % 1s).count() / divisor[width];
288  QString text = StringUtil::intToPaddedString(value, width);
289  fmt.replace(match.capturedStart(), match.capturedLength(), text);
290  }
291 
292  if (negativeTime)
293  fmt.prepend("-");
294 
295  return fmt;
296 }
297 
298 }; // namespace MythDate
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:93
MythDate::as_utc
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
Definition: mythdate.cpp:28
MythDate::kScreenShotFilename
@ kScreenShotFilename
"yyyy-MM-ddThh-mm-ss.zzz"
Definition: mythdate.h:29
MythDate::kOverrideUTC
@ kOverrideUTC
Present date/time in UTC.
Definition: mythdate.h:31
MythDate::formatTime
QString formatTime(std::chrono::milliseconds msecs, QString fmt)
Format a milliseconds time value.
Definition: mythdate.cpp:242
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:15
MythDate::secsInFuture
std::chrono::seconds secsInFuture(const QDateTime &future)
Definition: mythdate.cpp:217
MythDate::fromString
MBASE_PUBLIC QDateTime fromString(const QString &str, const QString &format)
Converts dy in format to QDateTime.
Definition: mythdate.cpp:58
mythdate.h
MBASE_PUBLIC
#define MBASE_PUBLIC
Definition: mythbaseexp.h:15
MythDate::fromSecsSinceEpoch
MBASE_PUBLIC QDateTime fromSecsSinceEpoch(int64_t seconds)
This function takes the number of seconds since the start of the epoch and returns a QDateTime with t...
Definition: mythdate.cpp:81
MythCoreContext::GetQLocale
QLocale GetQLocale(void)
Definition: mythcorecontext.cpp:1882
MythDate::kFilename
@ kFilename
Default UTC, "yyyyMMddhhmmss".
Definition: mythdate.h:18
MythDate::kDateEither
@ kDateEither
Default local time.
Definition: mythdate.h:21
MythDate::kOverrideLocal
@ kOverrideLocal
Present date/time in localtime.
Definition: mythdate.h:32
mythburn.timeformat
string timeformat
Definition: mythburn.py:171
MythDate::kAutoYear
@ kAutoYear
Add year only if different from current year.
Definition: mythdate.h:28
stringutil.h
MythDate::kDateShort
@ kDateShort
Default local time.
Definition: mythdate.h:20
StringUtil::intToPaddedString
QString intToPaddedString(int n, int width=2)
Creates a zero padded string representation of an integer.
Definition: stringutil.h:27
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:39
MythDate::kSimplify
@ kSimplify
Do Today/Yesterday/Tomorrow transform.
Definition: mythdate.h:26
MythDate::currentMSecsSinceEpochAsDuration
std::chrono::milliseconds currentMSecsSinceEpochAsDuration(void)
Definition: mythdate.cpp:207
MythDate::secsInPast
std::chrono::seconds secsInPast(const QDateTime &past)
Definition: mythdate.cpp:212
MythDate::kAddYear
@ kAddYear
Add year to string if not included.
Definition: mythdate.h:25
mythcorecontext.h
MythDate::kRFC822
@ kRFC822
HTTP Date format.
Definition: mythdate.h:30
MythDate
Definition: mythdate.cpp:12
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:17
MythDate::current_iso_string
QString current_iso_string(bool stripped)
Returns current Date and Time in UTC as a string.
Definition: mythdate.cpp:23
MythDate::kDatabase
@ kDatabase
Default UTC, database format.
Definition: mythdate.h:27
MythDate::toSeconds
std::chrono::seconds toSeconds(QTime time)
Returns the total number of seconds since midnight of the supplied QTime.
Definition: mythdate.cpp:195
MythDate::kTime
@ kTime
Default local time.
Definition: mythdate.h:22
uint
unsigned int uint
Definition: freesurround.h:24
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:902