• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kalarm

  • sources
  • kde-4.14
  • kdepim
  • kalarm
alarmtime.cpp
Go to the documentation of this file.
1 /*
2  * alarmtime.cpp - conversion functions for alarm times
3  * Program: kalarm
4  * Copyright © 2007-2012 by David Jarvie <djarvie@kde.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 #include "alarmtime.h"
22 #include "preferences.h"
23 
24 #include <kalarmcal/datetime.h>
25 
26 #include <ksystemtimezone.h>
27 #include <kglobal.h>
28 #include <klocale.h>
29 #include <kdebug.h>
30 #include <qapplication.h>
31 
32 using namespace KAlarmCal;
33 
34 int AlarmTime::mTimeHourPos = -2;
35 
36 /******************************************************************************
37 * Return the alarm time text in the form "date time".
38 */
39 QString AlarmTime::alarmTimeText(const DateTime& dateTime)
40 {
41  if (!dateTime.isValid())
42  return i18nc("@info/plain Alarm never occurs", "Never");
43  KLocale* locale = KGlobal::locale();
44  KDateTime kdt = dateTime.effectiveKDateTime().toTimeSpec(Preferences::timeZone());
45  QString dateTimeText = locale->formatDate(kdt.date(), KLocale::ShortDate);
46  if (!dateTime.isDateOnly()
47  || (!dateTime.isClockTime() && kdt.utcOffset() != dateTime.utcOffset()))
48  {
49  // Display the time of day if it's a date/time value, or if it's
50  // a date-only value but it's in a different time zone
51  dateTimeText += QLatin1Char(' ');
52  QString time = locale->formatTime(kdt.time());
53  if (mTimeHourPos == -2)
54  {
55  // Initialise the position of the hour within the time string, if leading
56  // zeroes are omitted, so that displayed times can be aligned with each other.
57  mTimeHourPos = -1; // default = alignment isn't possible/sensible
58  if (QApplication::isLeftToRight()) // don't try to align right-to-left languages
59  {
60  QString fmt = locale->timeFormat();
61  int i = fmt.indexOf(QRegExp(QLatin1String("%[kl]"))); // check if leading zeroes are omitted
62  if (i >= 0 && i == fmt.indexOf(QLatin1Char('%'))) // and whether the hour is first
63  mTimeHourPos = i; // yes, so need to align
64  }
65  }
66  if (mTimeHourPos >= 0 && (int)time.length() > mTimeHourPos + 1
67  && time[mTimeHourPos].isDigit() && !time[mTimeHourPos + 1].isDigit())
68  dateTimeText += QLatin1Char('~'); // improve alignment of times with no leading zeroes
69  dateTimeText += time;
70  }
71  return dateTimeText + QLatin1Char(' ');
72 }
73 
74 /******************************************************************************
75 * Return the time-to-alarm text.
76 */
77 QString AlarmTime::timeToAlarmText(const DateTime& dateTime)
78 {
79  if (!dateTime.isValid())
80  return i18nc("@info/plain Alarm never occurs", "Never");
81  KDateTime now = KDateTime::currentUtcDateTime();
82  if (dateTime.isDateOnly())
83  {
84  int days = now.date().daysTo(dateTime.date());
85  // xgettext: no-c-format
86  return i18nc("@info/plain n days", "%1d", days);
87  }
88  int mins = (now.secsTo(dateTime.effectiveKDateTime()) + 59) / 60;
89  if (mins < 0)
90  return QString();
91  char minutes[3] = "00";
92  minutes[0] = (mins%60) / 10 + '0';
93  minutes[1] = (mins%60) % 10 + '0';
94  if (mins < 24*60)
95  return i18nc("@info/plain hours:minutes", "%1:%2", mins/60, QLatin1String(minutes));
96  int days = mins / (24*60);
97  mins = mins % (24*60);
98  return i18nc("@info/plain days hours:minutes", "%1d %2:%3", days, mins/60, QLatin1String(minutes));
99 }
100 
101 /******************************************************************************
102 * Convert a date/time specification string into a local date/time or date value.
103 * Parameters:
104 * timeString = in the form [[[yyyy-]mm-]dd-]hh:mm [TZ] or yyyy-mm-dd [TZ].
105 * dateTime = receives converted date/time value.
106 * defaultDt = default date/time used for missing parts of timeString, or null
107 * to use current date/time.
108 * allowTZ = whether to allow a time zone specifier in timeString.
109 * Reply = true if successful.
110 */
111 bool AlarmTime::convertTimeString(const QByteArray& timeString, KDateTime& dateTime, const KDateTime& defaultDt, bool allowTZ)
112 {
113 #define MAX_DT_LEN 19
114  int i = timeString.indexOf(' ');
115  if (i > MAX_DT_LEN || (i >= 0 && !allowTZ))
116  return false;
117  QString zone = (i >= 0) ? QString::fromLatin1(timeString.mid(i)) : QString();
118  char timeStr[MAX_DT_LEN+1];
119  strcpy(timeStr, timeString.left(i >= 0 ? i : MAX_DT_LEN));
120  int dt[5] = { -1, -1, -1, -1, -1 };
121  char* s;
122  char* end;
123  bool noTime;
124  // Get the minute value
125  if ((s = strchr(timeStr, ':')) == 0)
126  noTime = true;
127  else
128  {
129  noTime = false;
130  *s++ = 0;
131  dt[4] = strtoul(s, &end, 10);
132  if (end == s || *end || dt[4] >= 60)
133  return false;
134  // Get the hour value
135  if ((s = strrchr(timeStr, '-')) == 0)
136  s = timeStr;
137  else
138  *s++ = 0;
139  dt[3] = strtoul(s, &end, 10);
140  if (end == s || *end || dt[3] >= 24)
141  return false;
142  }
143  bool noDate = true;
144  if (s != timeStr)
145  {
146  noDate = false;
147  // Get the day value
148  if ((s = strrchr(timeStr, '-')) == 0)
149  s = timeStr;
150  else
151  *s++ = 0;
152  dt[2] = strtoul(s, &end, 10);
153  if (end == s || *end || dt[2] == 0 || dt[2] > 31)
154  return false;
155  if (s != timeStr)
156  {
157  // Get the month value
158  if ((s = strrchr(timeStr, '-')) == 0)
159  s = timeStr;
160  else
161  *s++ = 0;
162  dt[1] = strtoul(s, &end, 10);
163  if (end == s || *end || dt[1] == 0 || dt[1] > 12)
164  return false;
165  if (s != timeStr)
166  {
167  // Get the year value
168  dt[0] = strtoul(timeStr, &end, 10);
169  if (end == timeStr || *end)
170  return false;
171  }
172  }
173  }
174 
175  QDate date;
176  if (dt[0] >= 0)
177  date = QDate(dt[0], dt[1], dt[2]);
178  QTime time(0, 0, 0);
179  if (noTime)
180  {
181  // No time was specified, so the full date must have been specified
182  if (dt[0] < 0 || !date.isValid())
183  return false;
184  dateTime = applyTimeZone(zone, date, time, false, defaultDt);
185  }
186  else
187  {
188  // Compile the values into a date/time structure
189  time.setHMS(dt[3], dt[4], 0);
190  if (dt[0] < 0)
191  {
192  // Some or all of the date was omitted.
193  // Use the default date/time if provided.
194  if (defaultDt.isValid())
195  {
196  dt[0] = defaultDt.date().year();
197  date.setYMD(dt[0],
198  (dt[1] < 0 ? defaultDt.date().month() : dt[1]),
199  (dt[2] < 0 ? defaultDt.date().day() : dt[2]));
200  }
201  else
202  date.setYMD(2000, 1, 1); // temporary substitute for date
203  }
204  dateTime = applyTimeZone(zone, date, time, true, defaultDt);
205  if (!dateTime.isValid())
206  return false;
207  if (dt[0] < 0)
208  {
209  // Some or all of the date was omitted.
210  // Use the current date in the specified time zone as default.
211  KDateTime now = KDateTime::currentDateTime(dateTime.timeSpec());
212  date = dateTime.date();
213  date.setYMD(now.date().year(),
214  (dt[1] < 0 ? now.date().month() : dt[1]),
215  (dt[2] < 0 ? now.date().day() : dt[2]));
216  if (!date.isValid())
217  return false;
218  if (noDate && time < now.time())
219  date = date.addDays(1);
220  dateTime.setDate(date);
221  }
222  }
223  return dateTime.isValid();
224 }
225 
226 /******************************************************************************
227 * Convert a time zone specifier string and apply it to a given date and/or time.
228 * The time zone specifier is a system time zone name, e.g. "Europe/London",
229 * "UTC" or "Clock". If no time zone is specified, it defaults to the local time
230 * zone.
231 * If 'defaultDt' is valid, it supplies the time spec and default date.
232 */
233 KDateTime AlarmTime::applyTimeZone(const QString& tzstring, const QDate& date, const QTime& time,
234  bool haveTime, const KDateTime& defaultDt)
235 {
236  bool error = false;
237  KDateTime::Spec spec = KDateTime::LocalZone;
238  QString zone = tzstring.trimmed();
239  if (!zone.isEmpty())
240  {
241  if (zone == QLatin1String("Clock"))
242  spec = KDateTime::ClockTime;
243  else if (zone == QLatin1String("UTC"))
244  spec = KDateTime::UTC;
245  else
246  {
247  KTimeZone tz = KSystemTimeZones::zone(zone);
248  error = !tz.isValid();
249  if (!error)
250  spec = tz;
251  }
252  }
253  else if (defaultDt.isValid())
254  spec = defaultDt.timeSpec();
255 
256  KDateTime result;
257  if (!error)
258  {
259  if (!date.isValid())
260  {
261  // It's a time without a date
262  if (defaultDt.isValid())
263  result = KDateTime(defaultDt.date(), time, spec);
264  else if (spec == KDateTime::LocalZone || spec == KDateTime::ClockTime)
265  result = KDateTime(KDateTime::currentLocalDate(), time, spec);
266  }
267  else if (haveTime)
268  {
269  // It's a date and time
270  result = KDateTime(date, time, spec);
271  }
272  else
273  {
274  // It's a date without a time
275  result = KDateTime(date, spec);
276  }
277  }
278  return result;
279 }
280 
281 // vim: et sw=4:
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QTime::setHMS
bool setHMS(int h, int m, int s, int ms)
QByteArray
date
time_t date() const
alarmtime.h
AlarmTime::applyTimeZone
static KDateTime applyTimeZone(const QString &tzstring, const QDate &date, const QTime &time, bool haveTime, const KDateTime &defaultDt=KDateTime())
Definition: alarmtime.cpp:233
QTime
QRegExp
AlarmTime::convertTimeString
static bool convertTimeString(const QByteArray &timeString, KDateTime &dateTime, const KDateTime &defaultDt=KDateTime(), bool allowTZ=true)
Definition: alarmtime.cpp:111
QByteArray::indexOf
int indexOf(char ch, int from) const
Preferences::timeZone
static KTimeZone timeZone(bool reload=false)
Definition: preferences.cpp:199
QDate::setYMD
bool setYMD(int y, int m, int d)
QString::isEmpty
bool isEmpty() const
QString::trimmed
QString trimmed() const
AlarmTime::timeToAlarmText
static QString timeToAlarmText(const KAlarmCal::DateTime &dateTime)
Definition: alarmtime.cpp:77
QDate::isValid
bool isValid() const
QDate
QString
QByteArray::mid
QByteArray mid(int pos, int len) const
QLatin1Char
preferences.h
AlarmTime::alarmTimeText
static QString alarmTimeText(const KAlarmCal::DateTime &dateTime)
Definition: alarmtime.cpp:39
QByteArray::left
QByteArray left(int len) const
MAX_DT_LEN
#define MAX_DT_LEN
QLatin1String
QString::length
int length() const
QApplication::isLeftToRight
bool isLeftToRight()
QString::fromLatin1
QString fromLatin1(const char *str, int size)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:34:51 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kalarm

Skip menu "kalarm"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal