summaryrefslogtreecommitdiffstats
path: root/kalarm/lib/datetime.h
blob: 976bada9009bd10fc11fb79ed13a04e38e7c316f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/*
 *  datetime.h  -  date/time representation with optional date-only value
 *  Program:  kalarm
 *  Copyright © 2003,2005,2007 by David Jarvie <software@astrojar.org.uk>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
#ifndef DATETIME_H
#define DATETIME_H

#include <tqdatetime.h>


/**
 *  @short A TQDateTime with date-only option.
 *
 *  The DateTime class holds a date, with or without a time.
 *
 *  DateTime is very similar to the TQDateTime class, with the additional option to
 *  hold a date-only value. This allows a single date-time representation to be used
 *  for both an event having a specific date and time, and an all-day event.
 *
 *  The time assumed for date-only values is the start-of-day time set by setStartOfDay().
 *
 *  @author David Jarvie <software@astrojar.org.uk>
*/
class DateTime
{
	public:
		/** Default constructor.
		 *  Constructs an invalid date-time.
		 */
		DateTime()                     : mDateOnly(false), mTimeValid(false) { }
		/** Constructor for a date-only value. */
		DateTime(const TQDate& d)       : mDateTime(d), mDateOnly(true) { }
		/** Constructor for a date-time value. */
		DateTime(const TQDate& d, const TQTime& t)
		                               : mDateTime(d, t), mDateOnly(false), mTimeValid(true) { }
		/** Constructor for a date-time or date-only value.
		 *  @param dt the date and time to use.
		 *  @param dateOnly True to construct a date-only value; false to construct a date-time value.
		 */
		DateTime(const TQDateTime& dt, bool dateOnly = false)
		                               : mDateTime(dt), mDateOnly(dateOnly), mTimeValid(true)
		                               { if (dateOnly) mDateTime.setTime(TQTime()); }
		/** Assignment operator.
		 *  Sets the value to a specified date-time or date-only value.
		 */
		DateTime& operator=(const DateTime& dt)
		                               { mDateTime = dt.mDateTime;  mDateOnly = dt.mDateOnly;  mTimeValid = dt.mTimeValid;  return *this; }
		/** Assignment operator.
		 *  Sets the value to a specified date-time.
		 */
		DateTime& operator=(const TQDateTime& dt)
		                               { mDateTime = dt;  mDateOnly = false;  mTimeValid = true;  return *this; }
		/** Assignment operator.
		 *  Sets the value to a specified date-only value.
		 */
		DateTime& operator=(const TQDate& d)
		                               { mDateTime.setDate(d); mDateTime.setTime(TQTime());  mDateOnly = true;  return *this; }
		/** Returns true if the date is null and, if it is a date-time value, the time is also null. */
		bool      isNull() const       { return mDateTime.date().isNull()  &&  (mDateOnly || mDateTime.time().isNull()); }
		/** Returns true if the date is valid and, if it is a date-time value, the time is also valid. */
		bool      isValid() const      { return mDateTime.date().isValid()  &&  (mDateOnly || mTimeValid && mDateTime.time().isValid()); }
		/** Returns true if it is date-only value. */
		bool      isDateOnly() const   { return mDateOnly; }
		/** Sets the value to be either date-only or date-time.
		 *  @param d True to set the value to be date-only; false to set it to a date-time value.
		 */
		void      setDateOnly(bool d)  { if (d) mDateTime.setTime(TQTime());
		                                 else if (mDateOnly) mTimeValid = false;
		                                 mDateOnly = d;
		                               }
		/** Returns the date part of the value. */
		TQDate     date() const         { return mDateTime.date(); }
		/** Returns the time part of the value.
		 *  If the value is date-only, the time returned is the start-of-day time set by setStartOfDay().
		 */
		TQTime     time() const;
		/** Returns the date and time of the value.
		 *  If the value is date-only, the time part returned is equal to the start-of-day time set
		 *  by setStartOfDay().
		 */
		TQDateTime dateTime() const;
		/** Returns the date and time of the value.
		 *  if the value is date-only, the time part returned is 00:00:00.
		 */
		TQDateTime rawDateTime() const     { return mDateTime; }
		/** Sets a date-time or date-only value.
		 *  @param dt the date-time to use.
		 *  @param dateOnly True to set a date-only value; false to set a date-time value.
		 */
		void      set(const TQDateTime& dt, bool dateOnly = false)
				{
					mDateTime = dt;
					mDateOnly = dateOnly;
					if (dateOnly)
						mDateTime.setTime(TQTime());
					mTimeValid = true;
				}
		/** Sets a date-time value. */
		void      set(const TQDate& d, const TQTime& t)
		                               { mDateTime.setDate(d);  mDateTime.setTime(t);  mDateOnly = false;  mTimeValid = true; }
		/** Sets the time component of the value.
		 *  The value is converted if necessary to be a date-time value.
		 */
		void      setTime(const TQTime& t)  { mDateTime.setTime(t);  mDateOnly = false;  mTimeValid = true; }
		/** Sets the value to a specified date-time value.
		 *  @param secs The time_t date-time value, expressed as the number of seconds elapsed
		 *              since 1970-01-01 00:00:00 UTC.
		 */
		void      setTime_t(uint secs)     { mDateTime.setTime_t(secs);  mDateOnly = false;  mTimeValid = true; }
		/** Returns a DateTime value @p secs seconds later than the value of this object.
		 *  If this object is date-only, @p secs is first rounded down to a whole number of days
		 *  before adding the value.
		 */
		DateTime  addSecs(int n) const
				{
					if (mDateOnly)
						return DateTime(mDateTime.date().addDays(n / (3600*24)), true);
					else
						return DateTime(mDateTime.addSecs(n), false);
				}
		/** Returns a DateTime value @p mins minutes later than the value of this object.
		 *  If this object is date-only, @p mins is first rounded down to a whole number of days
		 *  before adding the value.
		 */
		DateTime  addMins(int n) const
				{
					if (mDateOnly)
						return DateTime(mDateTime.addDays(n / (60*24)), true);
					else
						return DateTime(mDateTime.addSecs(n * 60), false);
				}
		/** Returns a DateTime value @p n days later than the value of this object. */
		DateTime  addDays(int n) const    { return DateTime(mDateTime.addDays(n), mDateOnly); }
		/** Returns a DateTime value @p n months later than the value of this object. */
		DateTime  addMonths(int n) const  { return DateTime(mDateTime.addMonths(n), mDateOnly); }
		/** Returns a DateTime value @p n years later than the value of this object. */
		DateTime  addYears(int n) const   { return DateTime(mDateTime.addYears(n), mDateOnly); }
		/** Returns the number of days from this date or date-time to @p dt. */
		int       daysTo(const DateTime& dt) const
		                                  { return (mDateOnly || dt.mDateOnly) ? mDateTime.date().daysTo(dt.date()) : mDateTime.daysTo(dt.mDateTime); }
		/** Returns the number of minutes from this date or date-time to @p dt.
		 *  If either of the values is date-only, the result is calculated by simply
		 *  taking the difference in dates and ignoring the times.
		 */
		int       minsTo(const DateTime& dt) const
		                                  { return (mDateOnly || dt.mDateOnly) ? mDateTime.date().daysTo(dt.date()) * 24*60 : mDateTime.secsTo(dt.mDateTime) / 60; }
		/** Returns the number of seconds from this date or date-time to @p dt.
		 *  If either of the values is date-only, the result is calculated by simply
		 *  taking the difference in dates and ignoring the times.
		 */
		int       secsTo(const DateTime& dt) const
		                                  { return (mDateOnly || dt.mDateOnly) ? mDateTime.date().daysTo(dt.date()) * 24*3600 : mDateTime.secsTo(dt.mDateTime); }
		/** Returns the value as a string.
		 *  If it is a date-time, both time and date are included in the output.
		 *  If it is date-only, only the date is included in the output.
		 */
		TQString   toString(TQt::DateFormat f = TQt::TextDate) const
				{
					if (mDateOnly)
						return mDateTime.date().toString(f);
					else if (mTimeValid)
						return mDateTime.toString(f);
					else
						return TQString();
				}
		/** Returns the value as a string.
		 *  If it is a date-time, both time and date are included in the output.
		 *  If it is date-only, only the date is included in the output.
		 */
		TQString   toString(const TQString& format) const
				{
					if (mDateOnly)
						return mDateTime.date().toString(format);
					else if (mTimeValid)
						return mDateTime.toString(format);
					else
						return TQString();
				}
		/** Returns the value as a string, formatted according to the user's locale.
		 *  If it is a date-time, both time and date are included in the output.
		 *  If it is date-only, only the date is included in the output.
		 */
		TQString   formatLocale(bool shortFormat = true) const;
		/** Sets the start-of-day time.
		 *  The default value is midnight (0000 hrs).
		 */
		static void setStartOfDay(const TQTime& sod)  { mStartOfDay = sod; }
		/** Returns the start-of-day time. */
		static TQTime startOfDay()   { return mStartOfDay; }

		friend bool operator==(const DateTime& dt1, const DateTime& dt2);
		friend bool operator<(const DateTime& dt1, const DateTime& dt2);

	private:
		static TQTime mStartOfDay;
		TQDateTime    mDateTime;
		bool         mDateOnly;
		bool         mTimeValid;    // whether the time is potentially valid - applicable only if mDateOnly false
};

/** Returns true if the two values are equal. */
bool operator==(const DateTime& dt1, const DateTime& dt2);
/** Returns true if the @p dt1 is earlier than @p dt2.
 *  If the two values have the same date, and one value is date-only while the other is a date-time, the
 *  time used for the date-only value is the start-of-day time set in the KAlarm Preferences dialogue.
 */
bool operator<(const DateTime& dt1, const DateTime& dt2);
/** Returns true if the two values are not equal. */
inline bool operator!=(const DateTime& dt1, const DateTime& dt2)   { return !operator==(dt1, dt2); }
/** Returns true if the @p dt1 is later than @p dt2.
 *  If the two values have the same date, and one value is date-only while the other is a date-time, the
 *  time used for the date-only value is the start-of-day time set in the KAlarm Preferences dialogue.
 */
inline bool operator>(const DateTime& dt1, const DateTime& dt2)    { return operator<(dt2, dt1); }
/** Returns true if the @p dt1 is later than or equal to @p dt2.
 *  If the two values have the same date, and one value is date-only while the other is a date-time, the
 *  time used for the date-only value is the start-of-day time set in the KAlarm Preferences dialogue.
 */
inline bool operator>=(const DateTime& dt1, const DateTime& dt2)   { return !operator<(dt1, dt2); }
/** Returns true if the @p dt1 is earlier than or equal to @p dt2.
 *  If the two values have the same date, and one value is date-only while the other is a date-time, the
 *  time used for the date-only value is the start-of-day time set in the KAlarm Preferences dialogue.
 */
inline bool operator<=(const DateTime& dt1, const DateTime& dt2)   { return !operator<(dt2, dt1); }

#endif // DATETIME_H