Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cTimeUnits.h
Go to the documentation of this file.
1 //
5 //
6 
7 #ifndef _INC_cTimeUnits_H
8 #define _INC_cTimeUnits_H
9 #ifndef NO_PRAGMA_ONCE
10 #pragma once
11 #endif
12 
13 #include "StrConst.h"
14 #include "StrArg.h"
15 #include "cUnitTestDecl.h"
16 #include "cDebugAssert.h"
17 #include "HResult.h"
18 #include <time.h> // system time_t for count of seconds. int32 or int64.
19 
20 namespace Gray
21 {
22  // Base type used for cTimeInt Might be 64 bits ?? or _USE_32BIT_TIME_T
23  typedef time_t TIMESEC_t;
24  typedef int TIMESECD_t;
25 
26  typedef short TIMEUNIT_t;
27 
28  enum TZ_TYPE
29  {
34 
35  TZ_UTC = 0,
36  TZ_GMT = 0,
37  TZ_AST = (4 * 60),
38  TZ_EDT = (4 * 60),
39  TZ_EST = (5 * 60),
40  TZ_CST = (6 * 60),
41  TZ_MST = (7 * 60),
42  TZ_PST = (8 * 60),
43  TZ_MAX = (24 * 60),
44  TZ_LOCAL = 0x7FFF,
45  };
46 
48  {
53 
54  // enum cdtdate_format_type {cdtMDY, cdtDAY, cdtMONTH, cdtFULL, cdtEUROPEAN};
55 
59 
63 
67 
72 
74  };
75 
77  {
88  };
89 
91  {
107  };
108 
109  struct CTimeUnit
110  {
118  WORD m_uSubRatio;
120  double m_dUnitDays;
121  };
122 
124  {
138  // used for parsing only.
143  };
144 
146  {
152 
153  public:
162 
164 
165  static const TIMESECD_t k_nSecondsPerDay = (24 * 60 * 60);
166  static const TIMESECD_t k_nSecondsPerHour = (60 * 60);
167  static const int k_nMinutesPerDay = (24 * 60);
168  static const int k_nMicroSeconds = 1000000;
169 
170  static const CTimeUnit k_Units[TIMEUNIT_QTY];
171  static const GChar_t* k_StrFormats[TIME_FORMAT_QTY + 1];
172 
173  static const BYTE k_MonthDays[2][TIMEMONTH_QTY];
174  static const WORD k_MonthDaySums[2][TIMEMONTH_QTY + 1];
175 
176  // may change for language ?
177  static const GChar_t* const k_MonthName[TIMEMONTH_QTY + 1];
178  static const GChar_t* const k_MonthAbbrev[TIMEMONTH_QTY + 1];
179 
180  static const GChar_t* const k_DayName[TIMEDOW_QTY + 1];
181  static const GChar_t* const k_DayAbbrev[TIMEDOW_QTY + 1];
182 
183  static const GChar_t k_TimeSeparator = ':';
184  static const GChar_t k_Seps[3]; // Normal valid string separators. "/:" = all sm_DateSeparator or sm_TimeSeparator
185  static const GChar_t k_SepsAll[8]; // All/Any separator that might occur in k_StrFormats.
186 
187  // May change for regional preferences ?
189  static bool sm_time24Mode;
190 
191  public:
192 #ifdef _WIN32
193  cTimeUnits(const SYSTEMTIME& sysTime);
194  bool GetSys(SYSTEMTIME& sysTime) const noexcept;
195  void SetSys(const SYSTEMTIME& sysTime);
196 #endif
197  void SetZeros();
198  bool InitTimeNow(TZ_TYPE nTimeZoneOffset = TZ_LOCAL);
199 
200  COMPARE_TYPE Compare(cTimeUnits& b) const;
201  bool isTimeFuture() const;
202  bool isTimePast() const
203  {
205  return !isTimeFuture();
206  }
207 
209  {
212  return GetDOW(m_wYear, m_wMonth, m_wDay);
213  }
214  int get_DOY() const
215  {
217  return GetDOY(m_wYear, m_wMonth, m_wDay);
218  }
220  {
221  return (TIMEMONTH_TYPE)(m_wMonth - 1);
222  }
223 
224  bool IsValidUnit(TIMEUNIT_TYPE i) const;
225  bool isValidTimeUnits() const;
226  bool isReasonableTimeUnits() const;
227 
229  {
232  return (&m_wYear)[i];
233  }
235  {
236  // Zero based units.
237  return GetUnit(i) - k_Units[i].m_uMin;
238  }
240  {
242  (&m_wYear)[i] = wVal;
243  }
244 
245  bool operator == (const cTimeUnits& rTu) const
246  {
247  return(!::memcmp(this, &rTu, sizeof(rTu))); // All of it ?
248  }
249 
250  void put_DosDate(UINT32 ulDosDate);
251  UINT32 get_DosDate() const;
252 
253  void AddMonths(int iMonths);
254  void AddDays(int iDays);
255  void AddSeconds(TIMESECD_t nSeconds);
256  void AddTZ(TZ_TYPE nTimeZoneOffset);
257 
258  bool isInDST() const;
259 
260  StrLen_t GetFormStr(GChar_t* pszOut, StrLen_t iOutSizeMax, const GChar_t* pszFormat) const;
262  {
263  return GetFormStr(pszOut, iOutSizeMax, (const GChar_t*)eFormat);
264  }
265  HRESULT SetTimeStr(const GChar_t* pszDateTime, TZ_TYPE nTimeZoneOffset);
266  StrLen_t GetTimeSpanStr(GChar_t* pszOut, StrLen_t iOutSizeMax, TIMEUNIT_TYPE eUnitHigh = TIMEUNIT_Day, int iUnitsDesired = 2, bool bShortText = false) const;
267 
268  static int GRAYCALL IsLeapYear(TIMEUNIT_t wYear);
269  static int GRAYCALL GetLeapYearsSince2K(TIMEUNIT_t wYear);
270  static TIMEDOW_TYPE GRAYCALL GetDOW(TIMEUNIT_t wYear, TIMEUNIT_t wMonth, TIMEUNIT_t wDay);
271  static int GRAYCALL GetDOY(TIMEUNIT_t wYear, TIMEUNIT_t wMonth, TIMEUNIT_t wDay);
272 
274  {
275  return m_wSecond + (m_wMinute * 60) + (TIMESECD_t)(m_wHour * 60 * 60);
276  }
277  bool isValidMonth() const
278  {
279  return m_wMonth >= 1 && m_wMonth <= 12;
280  }
282  {
283  // How many days in m_wMonth ?
284  ASSERT_THROW(isValidMonth());
285  int iLeapYear = IsLeapYear(m_wYear);
286  return k_MonthDays[iLeapYear][m_wMonth - 1];
287  }
289  {
290  // What day of m_wYear is this ?
291  ASSERT_THROW(isValidMonth());
292  int iLeapYear = IsLeapYear(m_wYear);
293  return k_MonthDaySums[iLeapYear][m_wMonth - 1] + (m_wDay - 1);
294  }
296  {
297  // How many days in m_wYear ?
298  return (IsLeapYear(m_wYear) == 0) ? 365 : 366;
299  }
300 
302  {
303  SetZeros(); // a valid time?
304  }
305  cTimeUnits(TIMEUNIT_t wYear, TIMEUNIT_t wMonth, TIMEUNIT_t wDay, TIMEUNIT_t wHour = 0, TIMEUNIT_t wMinute = 0, TIMEUNIT_t wSecond = 0, TIMEUNIT_t wMilliseconds = 0, TIMEUNIT_t wMicroseconds = 0, TZ_TYPE nTZ = TZ_UTC)
306  : m_wYear(wYear)
307  , m_wMonth(wMonth)
308  , m_wDay(wDay)
309  , m_wHour(wHour)
310  , m_wMinute(wMinute)
311  , m_wSecond(wSecond)
312  , m_wMillisecond(wMilliseconds)
313  , m_wMicrosecond(wMicroseconds)
314  , m_nTZ((TIMEUNIT_t)nTZ)
315  {
316  }
317 
319  };
320 
321  //*******************************************************
323  {
326 
331 
332  void Init()
333  {
335  m_nValue = -1; // not set yet.
336  m_iOffsetSep = -1;
337  m_Separator = -1; // not set yet.
338  }
339  TIMEUNIT_TYPE get_HashCode() const noexcept // should be only one of each type.
340  {
341  return m_Type;
342  }
343  TIMEUNIT_t get_SortValue() const noexcept
344  {
345  return m_nValue;
346  }
347  };
348 
350  {
354 
355  public:
359 
360  public:
361  static bool GRAYCALL TestMatchUnit(const cTimeParserUnit& u, TIMEUNIT_TYPE t);
362  static TIMEUNIT_TYPE GRAYCALL GetTypeFromFormatCode(GChar_t ch);
363  int FindType(TIMEUNIT_TYPE t) const;
364  void SetUnitFormats(const GChar_t* pszFormat);
365 
366  StrLen_t ParseNamedUnit(const GChar_t* pszName);
367  HRESULT ParseString(const GChar_t* pszTimeString, const GChar_t* pszSeparators = nullptr);
368  bool isMatched() const
369  {
370  return m_iUnitsMatched > 0;
371  }
373  {
375  ASSERT(m_iUnitsMatched <= m_iUnitsParsed);
376  if (m_iUnitsMatched <= 0)
377  return 0;
378  int i = m_iUnitsMatched - 1;
379  ASSERT(IS_INDEX_GOOD_ARRAY(i, m_Unit));
380  return m_Unit[i].m_iOffsetSep;
381  }
382 
383  bool TestMatchFormat(const cTimeParser& parserFormat, bool bTrimJunk = false);
384  bool TestMatch(const GChar_t* pszFormat);
385  bool TestMatches(const GChar_t** ppStrFormats = nullptr);
386 
387  HRESULT GetTimeUnits(OUT cTimeUnits& tu) const;
388 
390  : m_iUnitsParsed(0)
391  , m_iUnitsMatched(0)
392  {
393  m_Unit[0].Init();
394  }
395  cTimeParser(const GChar_t* pszTimeString)
396  : m_iUnitsParsed(0)
397  , m_iUnitsMatched(0)
398  {
399  ParseString(pszTimeString);
400  }
401  cTimeParser(const GChar_t* pszTimeString, const GChar_t** ppStrFormats)
402  : m_iUnitsParsed(0)
403  , m_iUnitsMatched(0)
404  {
405  // Matches
406  ParseString(pszTimeString);
407  TestMatches(ppStrFormats);
408  }
409  };
410 }
411 #endif
#define GRAYCORE_LINK
Definition: GrayCore.h:47
#define GRAYCALL
declare calling convention for static functions so everyone knows the arg passing scheme....
Definition: GrayCore.h:36
#define IS_INDEX_GOOD_ARRAY(i, a)
Definition: Index.h:38
#define IS_INDEX_GOOD(i, q)
cast the (likely) int to unsigned to check for negatives.
Definition: Index.h:35
INT32 HRESULT
_WIN32 style error codes. INT32
Definition: SysTypes.h:465
#define ASSERT(exp)
Definition: cDebugAssert.h:87
#define ASSERT_THROW(exp)
Definition: cDebugAssert.h:68
#define UNITTEST_FRIEND(n)
Define this in the class body to be unit tested. Allow the unit test to access private/protected stuf...
Definition: cUnitTestDecl.h:17
Definition: cTimeUnits.h:350
int m_iUnitsMatched
m_iUnitsMatched <= m_iUnitsParsed and all m_Type are set. No use of TIMEUNIT_Numeric
Definition: cTimeUnits.h:358
bool isMatched() const
Definition: cTimeUnits.h:368
StrLen_t GetMatchedLength() const
Definition: cTimeUnits.h:372
cTimeParser(const GChar_t *pszTimeString)
Definition: cTimeUnits.h:395
cTimeParser(const GChar_t *pszTimeString, const GChar_t **ppStrFormats)
Definition: cTimeUnits.h:401
cTimeParser()
Definition: cTimeUnits.h:389
int m_iUnitsParsed
m_Unit used. <TIMEUNIT_QTY2
Definition: cTimeUnits.h:357
Definition: cTimeUnits.h:146
static GChar_t sm_DateSeparator
date separator to use for string creation = '\', '-', '.', but Time is always ':'
Definition: cTimeUnits.h:188
TIMEMONTH_TYPE get_Month() const
Definition: cTimeUnits.h:219
TIMEUNIT_t m_wMonth
1 based month of year. Jan=1, to 12=Dec, NOT TIMEMONTH_TYPE. TIMEUNIT_Month
Definition: cTimeUnits.h:155
bool isTimePast() const
Definition: cTimeUnits.h:202
TIMEUNIT_t GetUnit0(TIMEUNIT_TYPE i) const
Definition: cTimeUnits.h:234
TIMEUNIT_t m_wMillisecond
1000th = thousandth. 0 to 1000
Definition: cTimeUnits.h:160
TIMEUNIT_t get_DayOfYear() const
Definition: cTimeUnits.h:288
TIMEDOW_TYPE get_DOW() const
Definition: cTimeUnits.h:208
TIMEUNIT_t GetUnit(TIMEUNIT_TYPE i) const
Definition: cTimeUnits.h:228
TIMEUNIT_t m_wDay
1 based day of month. 1 to 31. TIMEUNIT_Day
Definition: cTimeUnits.h:156
TIMEUNIT_t get_DaysInMonth() const
Definition: cTimeUnits.h:281
TIMEUNIT_t m_wMinute
0 to 59
Definition: cTimeUnits.h:158
cTimeUnits(void)
Definition: cTimeUnits.h:301
TIMEUNIT_t m_nTZ
TZ_TYPE where m_wHour has NOT yet been adjusted. TIMEUNIT_TZ.
Definition: cTimeUnits.h:163
TIMEUNIT_t m_wMicrosecond
1000000th = millionth. 0 to 1000. TIMEUNIT_Microsecond
Definition: cTimeUnits.h:161
TIMEUNIT_t m_wSecond
0 to 59
Definition: cTimeUnits.h:159
bool isValidMonth() const
Definition: cTimeUnits.h:277
void SetUnit(TIMEUNIT_TYPE i, TIMEUNIT_t wVal)
Definition: cTimeUnits.h:239
TIMEUNIT_t get_DaysInYear() const
Definition: cTimeUnits.h:295
TIMEUNIT_t m_wHour
0 to 23 for hour of day.
Definition: cTimeUnits.h:157
static bool sm_time24Mode
Display time in 24 hour format. default = false.
Definition: cTimeUnits.h:189
cTimeUnits(TIMEUNIT_t wYear, TIMEUNIT_t wMonth, TIMEUNIT_t wDay, TIMEUNIT_t wHour=0, TIMEUNIT_t wMinute=0, TIMEUNIT_t wSecond=0, TIMEUNIT_t wMilliseconds=0, TIMEUNIT_t wMicroseconds=0, TZ_TYPE nTZ=TZ_UTC)
Definition: cTimeUnits.h:305
TIMEUNIT_t m_wYear
Year valid for 1980 to 2043 at least. TIMEUNIT_Year.
Definition: cTimeUnits.h:154
StrLen_t GetFormStr(GChar_t *pszOut, StrLen_t iOutSizeMax, TIME_FORMAT_TYPE eFormat=TIME_FORMAT_DEFAULT) const
Definition: cTimeUnits.h:261
TIMESECD_t get_SecondOfDay() const
Definition: cTimeUnits.h:273
int get_DOY() const
Definition: cTimeUnits.h:214
< The main namespace for all Core functions.
Definition: GrayCore.cpp:14
TZ_TYPE
Definition: cTimeUnits.h:29
@ TZ_EST
Eastern Standard Time Zone. LocalTime+offset=GMT, GMT-offset=Local (seconds)
Definition: cTimeUnits.h:39
@ TZ_LOCAL
just use local time zone. might include DST ??
Definition: cTimeUnits.h:44
@ TZ_PST
Pacific Standard Time Zone. Default for Windows.
Definition: cTimeUnits.h:42
@ TZ_GMT
Greenwich mean time. similar to UTC.
Definition: cTimeUnits.h:36
@ TZ_AST
Definition: cTimeUnits.h:37
@ TZ_MST
Definition: cTimeUnits.h:41
@ TZ_UTC
UTC = never use DST or any TZ offset.
Definition: cTimeUnits.h:35
@ TZ_EDT
Eastern Daylight time.
Definition: cTimeUnits.h:38
@ TZ_CST
Definition: cTimeUnits.h:40
@ TZ_MAX
Max offset. over this is special mapped cTimeZone.
Definition: cTimeUnits.h:43
int StrLen_t
the length of a string in chars (bytes for UTF8, wchar_t for UNICODE). or offset in characters....
Definition: StrConst.h:32
int TIMESECD_t
signed delta seconds. like TIMESEC_t. redefined in TimeUnits.h.
Definition: cTimeSys.h:19
TIMEUNIT_TYPE
Definition: cTimeUnits.h:124
@ TIMEUNIT_Day
day of month. base 1. (1<=x<=31)
Definition: cTimeUnits.h:130
@ TIMEUNIT_TZ
TZ + DST.
Definition: cTimeUnits.h:136
@ TIMEUNIT_QTY
END of cTimeUnits.
Definition: cTimeUnits.h:137
@ TIMEUNIT_Second
base 0. (0<=x<=59)
Definition: cTimeUnits.h:133
@ TIMEUNIT_Minute
base 0. (0<=x<=59)
Definition: cTimeUnits.h:132
@ TIMEUNIT_Millisecond
1/1000 = thousandth of a second. (0<=x<=999)
Definition: cTimeUnits.h:134
@ TIMEUNIT_QTY2
END of cTimeParser.
Definition: cTimeUnits.h:142
@ TIMEUNIT_Numeric
A numeric value of unknown type (parsing).
Definition: cTimeUnits.h:141
@ TIMEUNIT_Microsecond
millionth of a second. (0<=x<=999)
Definition: cTimeUnits.h:135
@ TIMEUNIT_Hour
hour of day. 24 hour scale. base 0. (0<=x<=23)
Definition: cTimeUnits.h:131
@ TIMEUNIT_DOW
Ignore this for units storage. its redundant.
Definition: cTimeUnits.h:139
@ TIMEUNIT_UNUSED
Marks end.
Definition: cTimeUnits.h:127
@ TIMEUNIT_Ignore
Just ignore this duplicate. We have already dealt with it.
Definition: cTimeUnits.h:140
@ TIMEUNIT_Month
base 1, NOT Base 0 like = TIMEMONTH_Jan. (1<=x<=12)
Definition: cTimeUnits.h:129
@ TIMEUNIT_Year
e.g. 2008. (1<=x<=3000)
Definition: cTimeUnits.h:128
TIMEDOW_TYPE
Definition: cTimeUnits.h:77
@ TIMEDOW_Sun
0 based as in SYSTEMTIME.wDayOfWeek, and struct tm.tm_wday
Definition: cTimeUnits.h:80
@ TIMEDOW_Mon
Definition: cTimeUnits.h:81
@ TIMEDOW_Thu
Definition: cTimeUnits.h:84
@ TIMEDOW_Fri
Definition: cTimeUnits.h:85
@ TIMEDOW_Sat
Definition: cTimeUnits.h:86
@ TIMEDOW_Tue
Definition: cTimeUnits.h:82
@ TIMEDOW_Wed
Definition: cTimeUnits.h:83
@ TIMEDOW_QTY
7
Definition: cTimeUnits.h:87
time_t TIMESEC_t
absolute seconds since January 1, 1970. (GMT?)(signed) NOTE: Changing to __time64_t just adds more ra...
Definition: cTimeUnits.h:23
char GChar_t
My version of TCHAR, _TCHAR.
Definition: StrConst.h:26
short TIMEUNIT_t
Arbitrary time unit. (e.g. number of minutes or seconds). Allow negative for null ?...
Definition: cTimeUnits.h:26
TIMEMONTH_TYPE
Definition: cTimeUnits.h:91
@ TIMEMONTH_Jun
Definition: cTimeUnits.h:99
@ TIMEMONTH_Mar
Definition: cTimeUnits.h:96
@ TIMEMONTH_QTY
Definition: cTimeUnits.h:106
@ TIMEMONTH_Sep
Definition: cTimeUnits.h:102
@ TIMEMONTH_Apr
Definition: cTimeUnits.h:97
@ TIMEMONTH_Aug
Definition: cTimeUnits.h:101
@ TIMEMONTH_Jan
tm.tm_mon, NOT SYSTEMTIME (which is 1 based)
Definition: cTimeUnits.h:94
@ TIMEMONTH_Nov
Definition: cTimeUnits.h:104
@ TIMEMONTH_Jul
Definition: cTimeUnits.h:100
@ TIMEMONTH_May
Definition: cTimeUnits.h:98
@ TIMEMONTH_Dec
Definition: cTimeUnits.h:105
@ TIMEMONTH_Feb
Definition: cTimeUnits.h:95
@ TIMEMONTH_Oct
Definition: cTimeUnits.h:103
bool operator==(const cTimeDouble &dt1, const cTimeDouble &dt2)
Definition: cTimeDouble.h:250
COMPARE_TYPE
Definition: cValT.h:19
TIME_FORMAT_TYPE
Definition: cTimeUnits.h:48
@ TIME_FORMAT_ASN
No punctuation. e.g. "20150102140303Z".
Definition: cTimeUnits.h:66
@ TIME_FORMAT_AMERICAN
Typical American style of "07/19/2008 13:47:10".
Definition: cTimeUnits.h:60
@ TIME_FORMAT_QTY
Definition: cTimeUnits.h:73
@ TIME_FORMAT_DEFAULT
Default Sortable/linear/readable format. "2008/07/09 13:47:10".
Definition: cTimeUnits.h:56
@ TIME_FORMAT_HTTP
HTTP RFC1123 format "Tue, 03 Oct 2000 22:44:56 GMT".
Definition: cTimeUnits.h:61
@ TIME_FORMAT_TZ
Sortable Universal/GMT time = "2008-04-10 13:30:00Z".
Definition: cTimeUnits.h:58
@ TIME_FORMAT_ISO
ISO8601 with no TZ but including the 'T' "2015/01/02T14:03:03".
Definition: cTimeUnits.h:64
@ TIME_FORMAT_DB
Database default but with no TZ. "%04d-%02d-%02d %02d:%02d:%02d".
Definition: cTimeUnits.h:57
@ TIME_FORMAT_SMTP
SMTP wants this format. "7 Aug 2001 10:12:12 GMT".
Definition: cTimeUnits.h:62
@ TIME_FORMAT_ISO_TZ
ISO8601 plus TZ. "2015/01/02T14:03:03EST" or "2015-11-28T10:16:42+00:00".
Definition: cTimeUnits.h:65
Definition: cTimeUnits.h:110
double m_dUnitDays
Total days or fractions of a day for the unit. (for absolute units)
Definition: cTimeUnits.h:120
TIMESECD_t m_nUnitSeconds
Total seconds for a unit. (for absolute units)
Definition: cTimeUnits.h:119
TIMEUNIT_t m_uMax
Definition: cTimeUnits.h:117
const GChar_t * m_pszUnitNameS
short abbreviated unit name
Definition: cTimeUnits.h:115
const GChar_t * m_pszUnitNameL
long unit name
Definition: cTimeUnits.h:114
TIMEUNIT_t m_uMin
Definition: cTimeUnits.h:116
WORD m_uSubRatio
How many sub units in this unit. (for absolute units. e.g. not months or years)
Definition: cTimeUnits.h:118
Definition: cTimeUnits.h:323
TIMEUNIT_TYPE m_Type
What type of field does this look like. best guess. TIMEUNIT_Sec.
Definition: cTimeUnits.h:327
TIMEUNIT_t m_nValue
Value we read from the field. <0 = null/omitted.
Definition: cTimeUnits.h:328
TIMEUNIT_TYPE get_HashCode() const noexcept
Definition: cTimeUnits.h:339
StrLen_t m_iOffsetSep
End of the type info and start of the separator.
Definition: cTimeUnits.h:329
GChar_t m_Separator
What sort of separator follows ? ":T /.,-".
Definition: cTimeUnits.h:330
void Init()
Definition: cTimeUnits.h:332
TIMEUNIT_t get_SortValue() const noexcept
Definition: cTimeUnits.h:343