Cutelee  6.1.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 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
100  d = QDateTime::fromString(getSafeString(input), QStringLiteral("yyyy-MM-ddThh:mm:ss"));
101 #else
102  d = QDateTime::fromString(getSafeString(input), QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz"));
103 #endif
104  }
105 
106  auto argString = getSafeString(argument);
107 
108  if (!argString.get().isEmpty())
109  return d.toString(argString);
110 
111  return d.toString(QStringLiteral("MMM. d, yyyy"));
112 }
113 
114 QVariant TimeFilter::doFilter(const QVariant &input, const QVariant &argument,
115  bool autoescape) const
116 {
117  Q_UNUSED(autoescape)
118  QDateTime d;
119  if (input.userType() == QMetaType::QDateTime) {
120  d = input.toDateTime();
121  } else if (input.userType() == QMetaType::QDate) {
122  d.setDate(input.toDate());
123  } else if (input.userType() == QMetaType::QTime) {
124  d.setTime(input.toTime());
125  } else {
126 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
127  d = QDateTime::fromString(getSafeString(input), QStringLiteral("yyyy-MM-ddThh:mm:ss"));
128 #else
129  d = QDateTime::fromString(getSafeString(input), QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz"));
130 #endif
131  }
132 
133  auto argString = getSafeString(argument);
134  return d.toString(argString);
135 }
136 
138  const QVariant &argument,
139  bool autoescape) const
140 {
141  Q_UNUSED(autoescape)
142  QDateTime late;
143  if (argument.userType() != qMetaTypeId<QDateTime>())
144  late = QDateTime::currentDateTime();
145  else
146  late = argument.toDateTime();
147 
148  auto early = input.toDateTime();
149  if (!early.isValid())
150  return QVariant();
151  return timeSince(early, late);
152 }
153 
155  const QVariant &argument,
156  bool autoescape) const
157 {
158  Q_UNUSED(autoescape)
159  QDateTime early;
160  if (argument.userType() != qMetaTypeId<QDateTime>())
161  early = QDateTime::currentDateTime();
162  else
163  early = argument.toDateTime();
164 
165  auto late = input.toDateTime();
166  if (!late.isValid())
167  return QVariant();
168  return timeSince(early, late);
169 }
A QString wrapper class for containing whether a string is safe or needs to be escaped.
Definition: safestring.h:92
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
Definition: datetime.cpp:87
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
Definition: datetime.cpp:114
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
Definition: datetime.cpp:137
QVariant doFilter(const QVariant &input, const QVariant &argument={}, bool autoescape={}) const override
Definition: datetime.cpp:154
Cutelee::SafeString getSafeString(const QVariant &input)
Definition: util.cpp:108
Utility functions used throughout Cutelee.