Cutelee  6.2.0
datetime.cpp
1 /*
2  This file is part of the Cutelee template system.
3 
4  Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either version
9  2.1 of the Licence, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library. If not, see <http://www.gnu.org/licenses/>.
18 
19 */
20 
21 #include "datetime.h"
22 
23 #include "util.h"
24 
25 #include <QtCore/QDateTime>
26 
27 QVariant timeSince(const QDateTime &early, const QDateTime &late)
28 {
29  Q_ASSERT(early.isValid());
30  Q_ASSERT(late.isValid());
31 
32  auto secsSince = early.secsTo(late);
33 
34  if (secsSince < 0)
35  return SafeString(QStringLiteral("0 minutes"));
36 
37  // TODO: i18n
38  QStringList singularNames;
39  singularNames << QStringLiteral("year") << QStringLiteral("month")
40  << QStringLiteral("week") << QStringLiteral("day")
41  << QStringLiteral("hour") << QStringLiteral("minute");
42 
43  QStringList pluralNames;
44  pluralNames << QStringLiteral("years") << QStringLiteral("months")
45  << QStringLiteral("weeks") << QStringLiteral("days")
46  << QStringLiteral("hours") << QStringLiteral("minutes");
47 
48  QList<int> seconds;
49  seconds << (60 * 60 * 24 * 365) // year
50  << (60 * 60 * 24 * 30) // month
51  << (60 * 60 * 24 * 7) // week
52  << (60 * 60 * 24) // day
53  << (60 * 60) // hour
54  << (60); // minute
55 
56  auto count = secsSince;
57  auto i = 0;
58  while (i < seconds.size()) {
59  count = (secsSince / seconds.at(i));
60  ++i;
61  if (count != 0)
62  break;
63  }
64  QString firstChunk;
65 
66  if (count != 1)
67  firstChunk.append(
68  QStringLiteral("%1 %2").arg(count).arg(pluralNames.at(i - 1)));
69  else {
70  firstChunk.append(
71  QStringLiteral("%1 %2").arg(count).arg(singularNames.at(i - 1)));
72  }
73  if (seconds.size() > i) {
74  auto count2 = (secsSince - (seconds.at(i - 1) * count)) / seconds.at(i);
75  if (count2 != 0) {
76  if (count2 > 1)
77  firstChunk.append(
78  QStringLiteral(", %1 %2").arg(count2).arg(pluralNames.at(i)));
79  else
80  firstChunk.append(
81  QStringLiteral(", %1 %2").arg(count2).arg(singularNames.at(i)));
82  }
83  }
84  return firstChunk;
85 }
86 
87 QVariant DateFilter::doFilter(const QVariant &input, const QVariant &argument,
88  bool autoescape) const
89 {
90  Q_UNUSED(autoescape)
91  QDateTime d;
92  if (input.userType() == QMetaType::QDateTime) {
93  d = input.toDateTime();
94  } else if (input.userType() == QMetaType::QDate) {
95  d.setDate(input.toDate());
96  } else if (input.userType() == QMetaType::QTime) {
97  d.setTime(input.toTime());
98  } else {
99  d = QDateTime::fromString(getSafeString(input), u"yyyy-MM-ddThh:mm:ss.zzz");
100  }
101 
102  auto argString = getSafeString(argument);
103 
104  if (!argString.get().isEmpty())
105  return d.toString(argString);
106 
107  return d.toString(u"MMM. d, yyyy");
108 }
109 
110 QVariant TimeFilter::doFilter(const QVariant &input, const QVariant &argument,
111  bool autoescape) const
112 {
113  Q_UNUSED(autoescape)
114  QDateTime d;
115  if (input.userType() == QMetaType::QDateTime) {
116  d = input.toDateTime();
117  } else if (input.userType() == QMetaType::QDate) {
118  d.setDate(input.toDate());
119  } else if (input.userType() == QMetaType::QTime) {
120  d.setTime(input.toTime());
121  } else {
122  d = QDateTime::fromString(getSafeString(input), u"yyyy-MM-ddThh:mm:ss.zzz");
123  }
124 
125  auto argString = getSafeString(argument);
126  return d.toString(argString);
127 }
128 
130  const QVariant &argument,
131  bool autoescape) const
132 {
133  Q_UNUSED(autoescape)
134  QDateTime late;
135  if (argument.userType() != qMetaTypeId<QDateTime>())
137  else
138  late = argument.toDateTime();
139 
140  auto early = input.toDateTime();
141  if (!early.isValid())
142  return QVariant();
143  return timeSince(early, late);
144 }
145 
147  const QVariant &argument,
148  bool autoescape) const
149 {
150  Q_UNUSED(autoescape)
151  QDateTime early;
152  if (argument.userType() != qMetaTypeId<QDateTime>())
153  early = QDateTime::currentDateTime();
154  else
155  early = argument.toDateTime();
156 
157  auto late = input.toDateTime();
158  if (!late.isValid())
159  return QVariant();
160  return timeSince(early, late);
161 }
QString toString(QStringView format, QCalendar cal) const const
QString & append(QChar ch)
QDateTime toDateTime() const const
const_reference at(qsizetype i) const const
QTime toTime() const const
void setTime(QTime time)
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
Definition: datetime.cpp:87
QDateTime fromString(QStringView string, QStringView format, QCalendar cal)
qsizetype size() const const
QDateTime currentDateTime()
void setDate(QDate date)
Utility functions used throughout Cutelee.
A QString wrapper class for containing whether a string is safe or needs to be escaped.
Definition: safestring.h:91
int userType() const const
bool isValid() const const
QDate toDate() const const
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
Definition: datetime.cpp:129
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
Definition: datetime.cpp:146
qint64 secsTo(const QDateTime &other) const const
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
Definition: datetime.cpp:110
Cutelee::SafeString getSafeString(const QVariant &input)
Definition: util.cpp:111