-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStdTime.cpp
326 lines (248 loc) · 9.39 KB
/
StdTime.cpp
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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
#include "StdFuncs.h"
#include "StdTime.h"
#include <time.h>
#ifndef WIN32
#include <sys/time.h>
#endif /* ! WIN32 */
/* Useful constants used for calculating the current date and time in microseconds */
#define MICROSECONDS_PER_MILLI_SECOND (TInt64) 1000
#define MICROSECONDS_PER_SECOND (TInt64) 1000000
#define MICROSECONDS_PER_MINUTE (MICROSECONDS_PER_SECOND * 60)
#define MICROSECONDS_PER_HOUR (MICROSECONDS_PER_MINUTE * 60)
#define MICROSECONDS_PER_DAY (MICROSECONDS_PER_HOUR * 24)
#define MICROSECONDS_PER_YEAR (MICROSECONDS_PER_DAY * 365)
/** List of names of days of the week */
const char *g_apccDays[] =
{
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
};
/** List of number of days in each month of the year */
const TInt g_aiDaysPerMonth[] =
{
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
/** List of names of months of the year */
const char *g_apccMonths[] =
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
/**
* TDateTime constructor.
* Initialises the components of the class based on a microseconds value passed in.
*
* @date Saturday 23-Jan-2021 3:31 pm, Code HQ Bergmannstrasse
* @param a_iTime The number of microseconds since 01.01.01
*/
// TODO: CAW - Neither this, nor the revert conversion, are leap year safe. But that doesn't matter for
// the moment as they cancel one another out
TDateTime::TDateTime(TInt64 a_iTime)
{
TInt Index;
TInt64 MicroSecondsPerMonth;
/* Break down the number of microseconds since 01.01.01 into year, month, day etc. components */
iYear = (TInt) (a_iTime / MICROSECONDS_PER_YEAR);
a_iTime = (a_iTime % MICROSECONDS_PER_YEAR);
for (Index = 0; Index < 12; ++Index)
{
MicroSecondsPerMonth = (g_aiDaysPerMonth[Index] * MICROSECONDS_PER_DAY);
if (a_iTime >= MicroSecondsPerMonth)
{
a_iTime -= MicroSecondsPerMonth;
}
else
{
break;
}
}
iMonth = (enum TMonth) Index;
iDay = (TInt) ((a_iTime / MICROSECONDS_PER_DAY) + 1);
a_iTime = (a_iTime % MICROSECONDS_PER_DAY);
iHour = (TInt) (a_iTime / MICROSECONDS_PER_HOUR);
a_iTime = (a_iTime % MICROSECONDS_PER_HOUR);
iMinute = (TInt) (a_iTime / MICROSECONDS_PER_MINUTE);
a_iTime = (a_iTime % MICROSECONDS_PER_MINUTE);
iSecond = (TInt) (a_iTime / MICROSECONDS_PER_SECOND);
a_iTime = (a_iTime % MICROSECONDS_PER_SECOND);
iMilliSecond = (TInt) (a_iTime / MICROSECONDS_PER_MILLI_SECOND);
}
/* Written: Wednesday 17-Jun-2009 7:30 am */
TDateTime::TDateTime(TInt a_iYear, TMonth a_iMonth, TInt a_iDay, TInt a_iHour, TInt a_iMinute, TInt a_iSecond, TInt a_iMilliSecond)
{
iYear = a_iYear;
iMonth = a_iMonth;
iDay = a_iDay;
iHour = a_iHour;
iMinute = a_iMinute;
iSecond = a_iSecond;
iMilliSecond = a_iMilliSecond;
}
/**
* Calculates the current day of the week.
* This function will calculate the day of the week specified by the current instance of the
* TDateTime structure, as an index starting from Sunday. ie. Sunday will return 0, Monday
* will return 1 etc. up until Saturday, which will return 6.
*
* Note that this is an expensive routine as the day of the week is only calculated when this
* is called and it must count the number of days that have passed since 01.01.01 in order to
* determine the answer.
*
* @date Wednesday 11-Mar-2015 06:16 am, Code HQ Ehinger Tor
* @return The day of the week, starting from 0
*/
TInt TDateTime::DayOfWeek() const
{
TInt Index, NumDays;
NumDays = 0;
/* Determine the number of days that have passed from 01.01.01 to the current year and month */
for (Index = 1; Index < iYear; ++Index)
{
NumDays += (TDateTime::IsLeapYear(Index)) ? 366 : 365;
}
for (Index = 0; Index < iMonth; ++Index)
{
NumDays += g_aiDaysPerMonth[Index];
}
/* Take into account whether the current year is a leap year. If it is and the current day is after */
/* February then we need to add 1 day */
if (TDateTime::IsLeapYear(iYear))
{
if (iMonth > EFebruary)
{
++NumDays;
}
}
/* And finally the current day of the month */
NumDays += iDay;
/* Divide by the number of days per week and take the remainder and we have the current day of the week */
return(NumDays % 7);
}
/**
* Returns whether the given year is a leap year.
* This function will calculate whether the year specified is a leap year.
*
* @date Thursday 05-Feb-2015 07:20 am, Code HQ Ehinger Tor
* @param a_iYear The year to be checked
* @return ETrue if the year is a leap year, else EFalse
*/
TBool TDateTime::IsLeapYear(TInt a_iYear)
{
TBool LeapYear = EFalse;
/* If the year specified is evenly divisible by four then it is a leap year */
if ((a_iYear % 4) == 0)
{
/* Unless it is the first year of a new century (ie. 1900). Then it is not a leap year */
if ((a_iYear % 100) == 0)
{
/* But there is the special case that the first year of a century that is divisible by 400 */
/* (ie. 2000) is a leap year */
if ((a_iYear % 400) == 0)
{
LeapYear = ETrue;
}
}
else
{
LeapYear = ETrue;
}
}
return(LeapYear);
}
/**
* Initialises the TTime to the current local time.
* Queries the operating system for the current local time and assigns it to this instance
* of the TTime class.
*
* @date Wednesday 04-Mar-2015 07:32 am, Code HQ Ehinger Tor
*/
void TTime::HomeTime()
{
#if defined(__amigaos__) || defined(__unix__)
TInt MilliSeconds;
time_t TimeInSeconds;
struct tm *LocalTime;
struct timeval tv;
/* Get the current time using the POSIX function and build up a TDateTime structure representing that time */
TimeInSeconds = time(NULL);
MilliSeconds = gettimeofday(&tv, NULL) ? 0 : (tv.tv_usec / 1000);
LocalTime = localtime(&TimeInSeconds);
ASSERTM((LocalTime != NULL), "TTime::HomeTime() => Unable to obtain current date and time");
TDateTime DateTime((LocalTime->tm_year + 1900), (TMonth) LocalTime->tm_mon, LocalTime->tm_mday, LocalTime->tm_hour,
LocalTime->tm_min, LocalTime->tm_sec, MilliSeconds);
#else /* ! defined(__amigaos__) || defined(__unix__) */
SYSTEMTIME SystemTime;
/* Get the current time from Windows and build up a TDateTime structure representing that time */
GetLocalTime(&SystemTime);
TDateTime DateTime(SystemTime.wYear, (TMonth) (SystemTime.wMonth - 1), SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds);
#endif /* ! defined(__amigaos__) || defined(__unix__) */
/* And assign it to both the human readable and internal representations of the date and time */
Set(DateTime);
}
/**
* Calculates the number of microseconds that have elapsed since 01.01.01.
* This function will convert the current date and time to a 64 bit count of the number
* of microseconds that have elapsed since the start of the 1st millenium. It is a
* relatively CPU intensive function due to the amount of calculation involved, but will
* result in an integer that can easily be used for fast comparison of dates and times.
*
* @date Wednesday 16-Jul-2014 6:40 am
* @return Number of microseconds that have elapsed since 01.01.01
*/
TInt64 TTime::Int64() const
{
return(iTime);
}
/**
* Initialises the human readable and internal representations of the date and time.
* This is an internal helper function that will save the human readable TDateTime structure
* passed in and will then calculate the number of microseconds that have elapsed since 01.01.01,
* saving the resulting value. This allows both the human and machine readable versions of
* the date and time to be accessed without requiring calculations. Note that this is a
* relatively expensive routine as it must perform conversion calculations.
*
* @date Thursday 05-Apr-2015 06:25 am, Code HQ Ehinger Tor
* @param a_roDateTime Reference to the structure containing the current date and time
*/
void TTime::Set(const TDateTime &a_roDateTime)
{
TInt Index;
/* Save the human readable TDateTime structure passed in */
iDateTime = a_roDateTime;
/* Calculate the number of microseconds representing seconds, minutes, hours and days */
iTime = (iDateTime.MilliSecond() * MICROSECONDS_PER_MILLI_SECOND);
iTime += (iDateTime.Second() * MICROSECONDS_PER_SECOND);
iTime += (iDateTime.Minute() * MICROSECONDS_PER_MINUTE);
iTime += (iDateTime.Hour() * MICROSECONDS_PER_HOUR);
iTime += ((iDateTime.Day() - 1) * MICROSECONDS_PER_DAY);
/* Each month has a different number of days in it so we must calculate the number of */
/* microseconds that represent each separate month */
for (Index = 0; Index < iDateTime.Month(); ++Index)
{
iTime += (g_aiDaysPerMonth[Index] * MICROSECONDS_PER_DAY);
}
/* And finally add on the number of microseconds that represent the given year */
iTime += ((iDateTime.Year()) * MICROSECONDS_PER_YEAR);
}
/* Written: Wednesday 17-Jun-2009 7:50 am */
TTime &TTime::operator=(const TDateTime &a_roDateTime)
{
Set(a_roDateTime);
return(*this);
}
/* Written: Monday 13-Jul-2009 6:28 am */
TBool TTime::operator==(const TTime &a_roTime) const
{
return(iTime == a_roTime.Int64());
}
/**
* Tests whether the given date and time is greater than that passed in.
* This function will compare the passed in date and time with that of the current instance of this
* class and will return whether the passed in date and time is greater.
*
* @date Wednesday 16-Jul-2014 6:29 am
* @param a_roTime Date and time with which to compare the current date and time
* @return ETrue if the current date and time is greater than that passed in, else EFalse
*/
TBool TTime::operator>(const TTime &a_roTime) const
{
return(iTime > a_roTime.Int64());
}