OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
date.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1993, 1997 by Borland International, All Rights Reserved
4//
5/// \file
6/// TDate class implementation
7//----------------------------------------------------------------------------
8#include <owl/pch.h>
9#include <owl/date.h>
10#include <owl/time.h>
11#include <owl/profile.h>
12#include <owl/wsyscls.h>
13
14#include <stdio.h>
15#include <time.h>
16#include <string.h>
17#include <ctype.h>
18#include <tchar.h>
19
20namespace owl {
21
22/****************************************************************
23 * *
24 * static constants *
25 * *
26 ****************************************************************/
27
28const uint32 SECONDS_IN_DAY = 86400L;
29
30
31static const _TUCHAR sDaysInMonth[12] =
32 { 31,28,31,30,31,30,31,31,30,31,30,31 };
33static const DayTy sFirstDayOfEachMonth[12] =
34 { 1,32,60,91,121,152,182,213,244,274,305,335 };
35
36// default names
37static const tchar* DefMonthNames[12] =
38 { _T("January"),_T("February"),_T("March"),_T("April"),_T("May"),_T("June"),
39 _T("July"),_T("August"),_T("September"),_T("October"),_T("November"),_T("December") };
40static const tchar* DefUCMonthNames[12] =
41 { _T("JANUARY"),_T("FEBRUARY"),_T("MARCH"),_T("APRIL"),_T("MAY"),_T("JUNE"),
42 _T("JULY"),_T("AUGUST"),_T("SEPTEMBER"),_T("OCTOBER"),_T("NOVEMBER"),_T("DECEMBER") };
43
44static const tchar* DefWeekDayNames[7] =
45 { _T("Monday"),_T("Tuesday"),_T("Wednesday"),
46 _T("Thursday"),_T("Friday"),_T("Saturday"),_T("Sunday") };
47static const tchar* DefUCWeekDayNames[7] =
48 { _T("MONDAY"),_T("TUESDAY"),_T("WEDNESDAY"),
49 _T("THURSDAY"),_T("FRIDAY"),_T("SATURDAY"),_T("SUNDAY") };
50
51
52static const tchar** MonthNames = DefMonthNames;
53static const tchar** UCMonthNames = DefUCMonthNames;
54static const tchar** WeekDayNames = DefWeekDayNames;
55static const tchar** UCWeekDayNames = DefUCWeekDayNames;
56
57_OWLSTATICFUNC(static int) FindMatch( const tchar *str, const tchar**candidates, int icand );
58
59/***************************************************************************/
60
61// constructors
62
63/***************************************************************************/
64
65//
66/// Constructs a TDate object with the current date.
67//
69{
70 //long clk = time(0);
71 //struct tm *now = localtime(&clk);
72 // We no longer need to default to adding 1900 - (GSF) ???????????
73 //long _Julnum = Jday(now->tm_mon+1, now->tm_mday, now->tm_year+1900);
75 Julnum = Jday( _clk.GetMonth(), _clk.GetDay(), _clk.GetYear());
76}
77
78//
79/// Constructs a TDate object with the given day and year. The base date for
80/// this computation is December 31 of the previous year. If year == 0, it
81/// constructs a TDate with January 1, 1901, as the "day zero." For example,
82/// TDate(-1,0) = December 31, 1900, and TDate(1,0) = January 2, 1901.
83//
85{
86 if( year )
87 Julnum = Jday( 12, 31, year-1 ) + static_cast<JulTy>(day);
88 else
89 Julnum = jul1901 + static_cast<JulTy>(day);
90}
91
92//
93/// Construct a TDate for the given day, monthName, and year.
94//
99
100//
101/// Construct a TDate for the given day, month, and year.
102//
104{
105 Julnum = Jday( month, day, year );
106}
107
108//
109/// Type conversion to date.
110//
111TDate::TDate( const TTime & t )
112{
113 Julnum = t.IsValid() ? jul1901 + static_cast<JulTy>(t.LocalSecs()/SECONDS_IN_DAY) : 0;
114}
115
116//
117/// Construct a TDate from a TSystemTime
118//
120{
121 Julnum = Jday( t.GetMonth(), t.GetDay(), t.GetYear());
122}
123
124//
125//
126//
129{
130 MonthTy m; DayTy d; YearTy y;
131 Mdy(m, d, y);
132 return TSystemTime(y, m, d, 0, 0, 0, WeekDay());
133}
134
135/***************************************************************************/
136
137// static member functions
138
139/***************************************************************************/
140
141//
142/// Returns a string name for the weekday number.
143/// Monday == 1, ... , Sunday == 7
144/// Return 0 for weekday number out of range
145//
147{
148 return AssertWeekDayNumber(weekDayNumber) ? WeekDayNames[weekDayNumber-1] : nullptr;
149}
150
151//
152/// Return the number, 1-7, of the day of the week named nameOfDay.
153/// Return 0 if name doesn't match.
154//
156{
157 return static_cast<DayTy>(FindMatch( nameOfDay.c_str(), UCWeekDayNames, 7 )+1);
158}
159
160// Return the number of days of a given month
161// Return 0 if "month" is outside of the range 1 through 12, inclusive.
163{
164 uint days = 0;
165
166 if (month == 0)
167 month = Month();
168
170 days = sDaysInMonth[month-1];
171 if(Leap() && month == 2)
172 days++;
173 }
174
175 return days;
176}
177
178//
179/// Returns 1 if the given day (1-31) is within the given month for the given year.
180//
182{
183 if( day <= 0 || !AssertIndexOfMonth(month) )
184 return 0;
185 unsigned d = sDaysInMonth[month-1];
186 if( LeapYear(year) && month == 2 )
187 d++;
188 return day <= d;
189}
190
191//
192/// Returns the number of days in the year specified (365 or 366).
193//
195{
196 return LeapYear(year) ? 366 : 365;
197}
198
199//
200/// Returns the number, 1-12, of the month named nameOfMonth.
201/// Return 0 for no match.
202//
204{
205 return static_cast<MonthTy>(FindMatch(nameOfMonth.c_str(), UCMonthNames, 12 )+1);
206}
207
208//
209/// Convert Gregorian calendar date to the corresponding Julian day
210/// number j. Algorithm 199 from Communications of the ACM, Volume 6, No.
211/// 8, (Aug. 1963), p. 444. Gregorian calendar started on Sep. 14, 1752.
212/// This function not valid before that.
213/// Returns 0 if the date is invalid.
214//
216{
217 uint32 c, ya;
218 // We now always default to adding 1900 like the TDate CTOR - (GSF)
219 // if( y <= 99 ).
220 if( y <= 137 ) // year 2037 problem (long overflow)
221 y += 1900;
222 if( !DayWithinMonth(m, d, y) )
223 return static_cast<JulTy>(0);
224
225 if( m > 2 )
226 m -= 3;
227 else{
228 m += 9;
229 y--;
230 }
231
232 c = y / 100;
233 ya = y - 100*c;
234 return ((146097L*c)>>2) + ((1461*ya)>>2) + (153*m + 2)/5 + d + 1721119L;
235}
236
237//
238// Algorithm from K & R, "The C Programming Language", 1st ed.
239//
241{
242 return ((year & 3) == 0 && (year % 100) != 0) || (year % 400) == 0;
243}
244
245//
246/// Returns the string name for the given monthNumber (1-12). Returns 0 for an
247/// invalid monthNumber.
248//
250{
251 return AssertIndexOfMonth(monthNumber) ? MonthNames[monthNumber-1] : nullptr;
252}
253
254//
255// Return index of case-insensitive match; -1 if no match.
256//
257_OWLSTATICFUNC(static int)
258FindMatch( const tchar* str, const tchar** candidates, int icand )
259{
260 unsigned len = static_cast<unsigned>(::_tcslen(str));
261
262 while(icand--){
263 if( _tcsnicmp(str, candidates[icand], len) == 0)
264 break;
265 }
266 return icand;
267}
268
269/****************************************************************
270 * *
271 * Member functions *
272 * *
273 ****************************************************************/
274
275//
276/// Returns 1 if the target TDate is greater than parameter TDate, -1 if the target
277/// is less than the parameter, and 0 if the dates are equal.
278//
279int TDate::CompareTo( const TDate &d ) const
280{
281 if( Julnum < d.Julnum )
282 return -1;
283 else if( Julnum > d.Julnum )
284 return 1;
285 else
286 return 0;
287}
288
289//
290/// Returns the day of the year (1-365).
291//
293{
294 return DayTy(Julnum - Jday( 12, 31, Year()-1 ));
295}
296
297//
298/// Returns the day (1-31) of the month of this TDate.
299//
301{
302 MonthTy m; DayTy d; YearTy y;
303 Mdy( m, d, y );
304 return d;
305}
306
307//
308/// Return the number of the first day of a given month
309/// Return 0 if "month" is outside of the range 1 through 12, inclusive.
310//
312{
314 return 0;
315 unsigned firstDay = sFirstDayOfEachMonth[month-1];
316 if (month > 2 && Leap())
317 firstDay++;
318 return firstDay;
319}
320
321/// Returns a hash value for the date.
322unsigned TDate::Hash() const
323{
324 return static_cast<unsigned>(Julnum);
325}
326
327//
328/// Convert a Julian day number to its corresponding Gregorian calendar
329/// date. Algorithm 199 from Communications of the ACM, Volume 6, No. 8,
330/// (Aug. 1963), p. 444. Gregorian calendar started on Sep. 14, 1752.
331/// This function not valid before that.
332//
333_OWLSTATICFUNC(void)
334TDate::Mdy( MonthTy & m, DayTy & d, YearTy & y ) const
335{
336 uint32 _d;
337 JulTy j = Julnum - 1721119L;
338 y = (YearTy) (((j<<2) - 1) / 146097L);
339 j = (j<<2) - 1 - 146097L*y;
340 _d = (j>>2);
341 j = ((_d<<2) + 3) / 1461;
342 _d = (_d<<2) + 3 - 1461*j;
343 _d = (_d + 4)>>2;
344 m = (MonthTy)(5*_d - 3)/153;
345 _d = 5*_d - 3 - 153*m;
346 d = (DayTy)((_d + 5)/5);
347 y = (YearTy)(100*y + j);
348
349 if( m < 10 )
350 m += 3;
351 else{
352 m -= 9;
353 y++;
354 }
355}
356
357//
358/// Compares this TDate with dt and returns the date with the greater Julian number.
359//
360TDate
361TDate::Max( const TDate & dt ) const
362{
363 return dt.Julnum > Julnum ? dt : *this;
364}
365
366//
367/// Compares this TDate with dt and returns the date with the lesser Julian number.
368//
369TDate
370TDate::Min( const TDate & dt ) const
371{
372 return dt.Julnum < Julnum ? dt : *this;
373}
374
375//
376/// Returns the month of this TDate.
377//
380{
381 MonthTy m; DayTy d; YearTy y;
382 Mdy(m, d, y);
383 return m;
384}
385
386//
387/// Returns the TDate of the previous dayName.
388//
389TDate
391{
392 return Previous( DayOfWeek(dayName) );
393}
394
395//
396/// Returns the TDate of the previous day.
397//
398TDate
400{
401 // Renumber the desired and current day of week to start at 0 (Monday)
402 // and end at 6 (Sunday).
403
406 JulTy j = Julnum;
407
408 // Have to determine how many days difference from current day back to
409 // desired, if any. Special calculation under the 'if' statement to
410 // effect the wraparound counting from Monday (0) back to Sunday (6).
413 else
415 j -= thisDayOfWeek; // Adjust j to set it at the desired day of week.
416 return TDate(j);
417}
418
419//
420/// Returns 1 (Monday) through 7 (Sunday).
421//
423{
424 JulTy julnum = (day == 0 ? Julnum : Jday(day, Month(), Year()));
425 return DayTy(((((julnum+1)%7)+6)%7)+1);
426}
427
428//
429/// Returns the year of this TDate.
430//
432{
433 MonthTy m; DayTy d; YearTy y;
434 Mdy(m, d, y);
435 return y;
436}
437
438namespace
439{
440
441 int accept_digits(LPCTSTR str)
442 {
443 int n = 0;
444 while (_istdigit(str[n]))
445 n++;
446 return n;
447 }
448
450 {
451 int n = 0;
452 while (_totlower(picture[n]) == c)
453 n++;
454 return n;
455 }
456
458 {
459 const int n = accept_digits(str);
460 int result = _ttoi(tstring(str, 0, n).c_str());
461 str += n;
463 return result;
464 }
465
466} // namespace
467
468//
469/// Convert a string to a date according to the [Intl] section in win.ini or the
470/// passed format specifier
471void TDate::ParseFrom(LPCTSTR str, LPCTSTR format)
472{
473 int day, month, year;
474 Julnum = day = month = year = 0;
475
476 TProfile p(_T("intl"));
477 tstring shortFmt = p.GetString(_T("sShortDate"), _T("MM/dd/yyyy"));
478 LPCTSTR picture = format ? format : shortFmt.c_str();
479
480 while (*picture && *str) {
481 tchar c = static_cast<tchar>(_totlower(*picture));
482 switch (c) {
483 case _T('d'): {
484 day = parse_number(str, picture, c);
485 break;
486 }
487 case _T('m'): {
488 month = parse_number(str, picture, c);
489 break;
490 }
491 case _T('y'): {
492 year = parse_number(str, picture, c);
493 break;
494 }
495 default: {
496 picture++;
497 str++;
498 }
499 }
500 }
501
502 Julnum = Jday(month, day, year);
503 if (Julnum < 1)
504 Julnum = 0;
505}
506
507//
508//
509//
510void
512{
513 const tchar*** Names[] = { &MonthNames, &UCMonthNames,
514 &WeekDayNames, &UCWeekDayNames,
515 };
516 const tchar*** DefNames[] = {
517 (const tchar***)&DefMonthNames, (const tchar***)&DefUCMonthNames,
518 (const tchar***)&DefWeekDayNames, (const tchar***)&DefUCWeekDayNames,
519 };
520 if(names)
521 *(Names[type]) = names;
522 else
523 *(Names[type]) = *(DefNames[type]);
524}
525
526//
527//
528//
529const tchar*
531{
532 const tchar** Names[] = { MonthNames, UCMonthNames,
533 WeekDayNames, UCWeekDayNames,
534 };
535 return Names[type][index];
536}
537
538//
539/// Returns a new TDate containing the sum of this TDate and dd.
540//
542{
543 return TDate(dt.Julnum + dd);
544}
545
546//
547/// Returns a new TDate containing the sum of this TDate and dd.
548//
550{
551 return TDate(dt.Julnum + dd);
552}
553
554//
555//
556//
558{
559 return TDate(dt.Julnum - dd);
560}
561
562//
563//
564//
565} // OWL namespace
566/* ========================================================================== */
The TDate class represents a date.
Definition date.h:48
YearTy Year() const
Returns the year of this TDate.
Definition date.cpp:431
static int LeapYear(YearTy year)
Definition date.cpp:240
unsigned Hash() const
Returns a hash value for the date.
Definition date.cpp:322
int DaysInMonth(MonthTy month=0) const
Definition date.cpp:162
TDate()
Construct a TDate with the current date.
Definition date.cpp:68
static LPCTSTR MonthName(MonthTy monthNumber)
Returns the string name for the given monthNumber (1-12).
Definition date.cpp:249
static int AssertIndexOfMonth(MonthTy m)
Returns 1 if m is between 1 and 12 inclusive, otherwise returns 0.
Definition date.h:308
int Leap() const
leap year?
Definition date.h:218
static DayTy DaysInYear(YearTy)
Returns the number of days in the year specified (365 or 366).
Definition date.cpp:194
TDate Max(const TDate &dt) const
Compares this TDate with dt and returns the date with the greater Julian number.
Definition date.cpp:361
int CompareTo(const TDate &) const
Returns 1 if the target TDate is greater than parameter TDate, -1 if the target is less than the para...
Definition date.cpp:279
static int AssertWeekDayNumber(DayTy d)
Returns 1 if d is between 1 and 7 inclusive, otherwise returns 0.
Definition date.h:302
static MonthTy IndexOfMonth(const tstring &monthName)
Returns the number, 1-12, of the month named nameOfMonth.
Definition date.cpp:203
static LPCTSTR DayName(DayTy weekDayNumber)
Returns a string name for the weekday number.
Definition date.cpp:146
DayTy FirstDayOfMonth() const
Returns the number of the first day of the month for this TDate.
Definition date.h:206
static void SetIntlNames(TDateType type, const tchar **names)
Definition date.cpp:511
static const tchar * GetIntlName(TDateType type, int index)
Definition date.cpp:530
MonthTy Month() const
Returns the month of this TDate.
Definition date.cpp:379
TSystemTime GetSystemTime() const
Definition date.cpp:128
static int DayWithinMonth(MonthTy, DayTy, YearTy)
Returns 1 if the given day (1-31) is within the given month for the given year.
Definition date.cpp:181
DayTy WeekDay(DayTy day=0) const
Returns 1 (Monday) through 7 (Sunday).
Definition date.cpp:422
TDate Min(const TDate &dt) const
Compares this TDate with dt and returns the date with the lesser Julian number.
Definition date.cpp:370
static DayTy DayOfWeek(const tstring &dayName)
Return the number, 1-7, of the day of the week named nameOfDay.
Definition date.cpp:155
DayTy Day() const
Returns the day of the year (1-365).
Definition date.cpp:292
static JulTy Jday(MonthTy, DayTy, YearTy)
Convert Gregorian calendar date to the corresponding Julian day number j.
Definition date.cpp:215
TDate Previous(const tstring &dayName) const
Return date of previous dayName.
Definition date.cpp:390
DayTy DayOfMonth() const
Returns the day (1-31) of the month of this TDate.
Definition date.cpp:300
TSystemTime is a class derived from the structure SYSTEMTIME.
Definition wsyscls.h:420
uint16 GetDay()
Definition wsyscls.h:447
uint16 GetMonth()
Definition wsyscls.h:439
static TSystemTime LocalTime()
Definition wsyscls.h:468
uint16 GetYear()
Definition wsyscls.h:435
The TTime class encapsulates time functions and characteristics.
Definition time.h:38
int IsValid() const
Returns 1 if this TTime object contains a valid time, 0 otherwise.
Definition time.h:126
#define _istdigit
Definition cygwin.h:70
#define _ttoi
Definition cygwin.h:64
#define _tcsnicmp
Definition cygwin.h:77
#define _tcslen
Definition cygwin.h:74
unsigned char _TUCHAR
Definition cygwin.h:44
#define _T(x)
Definition cygwin.h:51
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
const uint32 SECONDS_IN_DAY
Definition date.cpp:28
unsigned long uint32
Definition number.h:34
unsigned YearTy
Year type.
Definition date.h:32
char tchar
Definition defs.h:77
TTime operator+(const TTime &t, long s)
Adds s seconds to time t.
Definition time.h:180
TTime operator-(const TTime &t, long s)
Performs subtraction, in seconds, between s and t.
Definition time.h:192
unsigned long JulTy
Julian calendar type.
Definition date.h:35
FindMatch(const tchar *str, const tchar **candidates, int icand)
Definition date.cpp:258
std::string tstring
Definition defs.h:79
unsigned DayTy
Day type.
Definition date.h:26
const tchar ** candidates
Definition date.cpp:57
unsigned MonthTy
Month type.
Definition date.h:29
const tchar int icand
Definition date.cpp:57
#define _OWLSTATICFUNC(p)
Definition defs.h:308
#define _OWLFUNC(p)
Definition defs.h:341
Definition of TProfile class.
Definition of class TString, a flexible universal string envelope class.
Classes for window system structure and type encapsulation.