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 
7 #include "mythcorecontext.h"
8 #include "mythdate.h"
9 #include "stringutil.h"
10 
11 namespace MythDate
12 {
13 
14 QDateTime current(bool stripped)
15 {
16  QDateTime rettime = QDateTime::currentDateTimeUtc();
17  if (stripped)
18  rettime = rettime.addMSecs(-rettime.time().msec());
19  return rettime;
20 }
21 
22 QString current_iso_string(bool stripped)
23 {
24  return MythDate::current(stripped).toString(Qt::ISODate);
25 }
26 
27 QDateTime as_utc(const QDateTime &old_dt)
28 {
29  QDateTime dt(old_dt);
30  dt.setTimeSpec(Qt::UTC);
31  return dt;
32 }
33 
34 QDateTime fromString(const QString &dtstr)
35 {
36  QDateTime dt;
37  if (dtstr.isEmpty())
38  return as_utc(dt);
39 
40  if (!dtstr.contains("-") && dtstr.length() == 14)
41  {
42  // must be in yyyyMMddhhmmss format
43  dt = QDateTime::fromString(dtstr, "yyyyMMddhhmmss");
44  }
45  else
46  {
48  }
49 
50  return as_utc(dt);
51 }
52 
53 MBASE_PUBLIC QDateTime fromString(const QString &str, const QString &format)
54 {
55  QDateTime dt = QDateTime::fromString(str, format);
56  dt.setTimeSpec(Qt::UTC);
57  return dt;
58 }
59 
72 MBASE_PUBLIC QDateTime fromSecsSinceEpoch(int64_t seconds)
73 {
74  QDateTime dt = QDateTime::fromSecsSinceEpoch(seconds);
75  return dt.toUTC();
76 }
77 
84 QString toString(const QDateTime &raw_dt, uint format)
85 {
86  QString result;
87 
88  if (!raw_dt.isValid())
89  return result;
90 
91  // if no format is set default to UTC for ISO/file/DB dates.
92  if (!((format & kOverrideUTC) || (format & kOverrideLocal)))
93  {
94  format |= ((ISODate|kFilename|kDatabase) & format) ?
96  }
97 
98  QDateTime datetime =
99  (format & kOverrideUTC) ? raw_dt.toUTC() : raw_dt.toLocalTime();
100 
101  if (format & kDatabase)
102  return datetime.toString("yyyy-MM-dd hh:mm:ss");
103 
104  if (format & MythDate::ISODate)
105  return datetime.toString(Qt::ISODate);
106 
107  if (format & MythDate::kRFC822) // RFC 822 - RFC 7231 Sect 7.1.1.1 - HTTP Date
108  return datetime.toUTC().toString("ddd, dd MMM yyyy hh:mm:ss").append(" GMT");
109 
110  if (format & kFilename)
111  return datetime.toString("yyyyMMddhhmmss");
112 
113  if (format & kScreenShotFilename)
114  return datetime.toString("yyyy-MM-ddThh-mm-ss.zzz");
115 
116  if (format & kDateEither)
117  result += toString(datetime.date(), format);
118 
119  if (format & kTime)
120  {
121  if (!result.isEmpty())
122  result.append(", ");
123 
124  QString timeformat = gCoreContext->GetSetting("TimeFormat", "h:mm AP");
125  result += datetime.time().toString(timeformat);
126  }
127 
128  return result;
129 }
130 
136 QString toString(const QDate date, uint format)
137 {
138  QString result;
139 
140  if (!date.isValid())
141  return result;
142 
143  if (format & kDateEither)
144  {
145  QString stringformat;
146  if (format & kDateShort)
147  stringformat = gCoreContext->GetSetting("ShortDateFormat", "ddd d");
148  else
149  stringformat = gCoreContext->GetSetting("DateFormat", "ddd d MMMM");
150 
151  if (format & kAddYear)
152  {
153  if (!stringformat.contains("yy")) // Matches both 2 or 4 digit year
154  stringformat.append(" yyyy");
155  }
156 
157  if (format & kAutoYear)
158  {
159  if (!stringformat.contains("yy") // Matches both 2 or 4 digit year
160  && date.year() != QDateTime::currentDateTime().date().year())
161  stringformat.append(" yyyy");
162  }
163 
164  if (format & ~kDateShort)
165  {
166  QDate now = current().toLocalTime().date();
167  if ((format & kSimplify) && (now == date))
168  result = QCoreApplication::translate("(Common)", "Today");
169  else if (((format & kSimplify) != 0U) && (now.addDays(-1) == date))
170  result = QCoreApplication::translate("(Common)", "Yesterday");
171  else if (((format & kSimplify) != 0U) && (now.addDays(1) == date))
172  result = QCoreApplication::translate("(Common)", "Tomorrow");
173  }
174 
175  if (result.isEmpty())
176  result = gCoreContext->GetQLocale().toString(date, stringformat);
177  }
178 
179  return result;
180 }
181 
186 std::chrono::seconds toSeconds(QTime time)
187 {
188  if (!time.isValid())
189  return 0s;
190 
191  std::chrono::seconds nSecs = std::chrono::hours(time.hour());
192  nSecs += std::chrono::minutes(time.minute());
193  nSecs += std::chrono::seconds(time.second());
194 
195  return nSecs;
196 }
197 
198 std::chrono::milliseconds currentMSecsSinceEpochAsDuration(void)
199 {
200  return std::chrono::milliseconds(QDateTime::currentMSecsSinceEpoch());
201 };
202 
203 std::chrono::seconds secsInPast (const QDateTime& past)
204 {
205  return std::chrono::seconds(past.secsTo(MythDate::current()));
206 }
207 
208 std::chrono::seconds secsInFuture (const QDateTime& future)
209 {
210  return std::chrono::seconds(MythDate::current().secsTo(future));
211 }
212 
233 QString formatTime(std::chrono::milliseconds msecs, QString fmt)
234 {
235  static const QRegularExpression hRe("H+");
236  static const QRegularExpression mRe("m+");
237  static const QRegularExpression sRe("s+");
238  static const QRegularExpression zRe("z+");
239 
240  QRegularExpressionMatch match = hRe.match(fmt);
241  if (match.hasMatch())
242  {
243  int width = match.capturedLength();
244  QString text = StringUtil::intToPaddedString(msecs / 1h, width);
245  fmt.replace(match.capturedStart(), width, text);
246  msecs = msecs % 1h;
247  }
248 
249  match = mRe.match(fmt);
250  if (match.hasMatch())
251  {
252  int width = match.capturedLength();
253  QString text = StringUtil::intToPaddedString(msecs / 1min, width);
254  fmt.replace(match.capturedStart(), width, text);
255  msecs = msecs % 1min;
256  }
257 
258  match = sRe.match(fmt);
259  if (match.hasMatch())
260  {
261  int width = match.capturedLength();
262  QString text = StringUtil::intToPaddedString(msecs / 1s, width);
263  fmt.replace(match.capturedStart(), width, text);
264  }
265 
266  match = zRe.match(fmt);
267  if (match.hasMatch())
268  {
269  static constexpr std::array<int,4> divisor = {1000, 100, 10, 1};
270  int width = std::min(3, static_cast<int>(match.capturedLength()));
271  int value = (msecs % 1s).count() / divisor[width];
272  QString text = StringUtil::intToPaddedString(value, width);
273  fmt.replace(match.capturedStart(), match.capturedLength(), text);
274  }
275  return fmt;
276 }
277 
278 }; // namespace MythDate
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:84
MythDate::as_utc
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
Definition: mythdate.cpp:27
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:233
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
MythDate::secsInFuture
std::chrono::seconds secsInFuture(const QDateTime &future)
Definition: mythdate.cpp:208
MythDate::fromString
MBASE_PUBLIC QDateTime fromString(const QString &str, const QString &format)
Converts dy in format to QDateTime.
Definition: mythdate.cpp:53
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:72
MythCoreContext::GetQLocale
QLocale GetQLocale(void)
Definition: mythcorecontext.cpp:1844
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:24
uint
unsigned int uint
Definition: compat.h:79
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:54
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:34
MythDate::kSimplify
@ kSimplify
Do Today/Yesterday/Tomorrow transform.
Definition: mythdate.h:26
MythDate::currentMSecsSinceEpochAsDuration
std::chrono::milliseconds currentMSecsSinceEpochAsDuration(void)
Definition: mythdate.cpp:198
MythDate::secsInPast
std::chrono::seconds secsInPast(const QDateTime &past)
Definition: mythdate.cpp:203
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:11
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:22
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:186
MythDate::kTime
@ kTime
Default local time.
Definition: mythdate.h:22
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:896