Data conversions solving time limitations of object-oriented software programs6643664Abstract A method, apparatus, and article of manufacture for converting dates in object-oriented software programs utilizing time classes covering limited periods of time is provided. A conversion object identifies a target year in which an application program should execute. If the target year falls outside of the limited period of time, the conversion object converts the target year into a base year which falls within the limited time period and a corresponding offset. The application program is then executed with the target year, and if the target year is needed by the application program, it can be reconstructed by adding the base year and corresponding offset. Claims What is claimed is: Description BACKGROUND OF THE INVENTION
class DKDate
{
public:
DKDate (int nYear, int mm, int nDay);
DKDate ( );
virtual .about.DKDate ( );
int getYear ( ) const;
int getMonth ( ) const;
int getDay ( ) const;
private:
int_diff;
CTime_t;
};
The DKDate class defines an object with a specified year (nYear), month (mm), and day (nDay) or alternatively, the current system time. DKDate is also defined with both public methods and private data. Public methods are available to both the conversion program 39 and the application program 37. The public methods include getYear, getMonth, and getDay. Private data is available to the conversion program 39 but not to any application program 37. Private data includes an integer representing the value of an offset or differential ("_diff") and an object ("_t") generated from the CTime class 38. The variables _diff and _t are designated as private such that the application program 37 does not utilize any date data generated by CTime 38 since these dates may be before 1970 or after 2037 causing the application program 37 to fail. 1.B. Definition of DKTimestamp Conversion Class DKTimestamp is another conversion class 39 provided by the IBM DB2 Digital Library that encapsulates a CTime class (block 110). DKTimestamp is an object-oriented representation of a timestamp including year, month, day, hour, minute, second, and nanosecond data and is defined as follows:
class DKTimestamp
{
public:
DKTimestamp (int nYear, int nMonth, int nDay,
int nHour=0, int nMin=0, int nSec=0,
int nNano = 0, int DST = -1);
DKTimestamp( );
virtual .about.DKTimestamp( );
int getYear ( ) const;
int getMonth ( ) const;
int getDay ( ) const;
int getHours ( ) const;
int getMinutes ( ) const;
int getSeconds ( ) const;
int getNanos ( ) const;
private:
int_nanos;
int_diff;
CTime_t;
};
The DKTimestamp class defines an object similar to a DKDate object with a specified year (nYear), month (mm), day (nDay) or current system time. In addition, DKTimestamp provides for hour (nHour), second (nSec), and nanosecond (nNanos) time parameters. Further, DKTimestamp allows a user to designate daylight savings time (DST). As a default, DKTimestamp assigns nHour, nMin, nSec, and nNano a value of 0. In addition, DKTimestamp assigns a default value of (-1) to DST to designate that this class does not utilize DST. Ths DST value, however, may be modified by the user. DKTimestamp is also defined with public methods and private data. DKTimestamp public methods include getYear, getMonth, getDay, getHours, getMinutes, getSeconds, and getNanos. However, the number of nanoseconds (_nano), an integer representing the value of an offset or differential (_diff) and an object generated from the CTime class (_t) are designated as private data. Similar to DKDate, DKTimestamp also designates the _diff and _t variables as private data such that the application program 37 will not utilize any date data generated by the CTime 38. In addition, DKTimestamp designates the _nanos variable as private data. CTime 38 can read the number of seconds, but not the number of nanoseconds. Designating nanos as private data ensures that application programs 37 will not fail if they attempt to read the number of nanoseconds generated from DKTimestamp. 2. Generating a Conversion Object From Conversion Classes Referring to FIG. 2, after a DKDate or DKTimestamp conversion class 39 has encapsulated the CTime class 38, a conversion object is generated (block 120). 2.A. DKDate Constructors When a DKDate wrapper class is instantiated, a DKDate object will be generated. DKDate objects may be generated from two different DKDate constructors. One DKDate constructor implements a DKDate class with year, month, and day data whereas the second DKDate constructor implements a DKDate class with current system time. 2.A.1. DKDate Constructor With Year, Month and Day The first DKDate constructor provides a DKDate object with year, month, and day parameters. This DKDate constructor is defined as follows:
DKDate::DKDate (int nYear, int mm, int nDay)
{
_diff = 0;
if(nYear > 2037)
{
_diff = (nYear - 2037);
_t = CTime (2037, mm, nDay, 0, 0, 0,-1);
}
else if(nYear < 1970)
{
_diff = (nYear - 1970);
_t = CTime (1970, mm, nDay, 0, 0, 0,-1);
}
else
{
_diff = (0);
_t = CTime (nYear, mm, nDay, 0, 0, 0, -1);
}
}
2.A.2. DKDate Constructor With Current Svstem Time The second type of DKDate constructor used to generate DKDate objects from the DKDate class is a constructor utilizing current system time. Current system time may be identified in a parameter that is retrieved from the computer 10, system clock 22, a program 33, or some other source. This constructor is implemented by the following:
DKDate: :DKDate ( )
{
time_t _time;
time_t* = pTime &_time;
struct tm temp;
struct tm* pTemp = &temp;
_time = time ((time_t*)NULL);
pTemp = localtime (pTime);
int nSec = pTemp->tm_sec;
int nMin = pTemp->tm_min;
int nHour pTemp->tm_hour;
int nDay = pTemp->tm_mday;
int nMon = pTemp->tm_mon+1;
int nYear = pTemp->tm_year + 1900;
_diff =0;
if(nYear > 2037)
{
_diff = (nYear - 2037);
_t = CTime(2037, nMon, nDay, nHour, nMin, nSec, -1);
}
else if (nYear < 1970)
{
_diff = (nYear - 1970);
_t = CTime(1970, nMon, aDay, nHour, nMin, nSec, -1);
}
else
{
_diff = (0);
_t = CTime(nYear, nMon, NDay, nHour, nMin, nSec, -1);
}
}
The DKDate constructor based on current system time does not require a user to input year, month, and day parameters. As the first line "DKDate::DKDate( )" illustrates, there are no input parameters. Rather, time data is retrieved by the "localtime" fuinction which queries a local system or server. The DKDate constructor utilizing current system time generates a DKDate object with year, month, day, hour, minute, and second data. Second, minute, hour and day variables (nSec, nMin, nHour, and nDay) are assigned the same values as provided for by the local system (tm_sec, tm_min, tm_hour, and tm_mday). The month variable (nMon), however, is not assigned the same value as the month value provided by the local system. Rather, nMon is assigned the local system month value (tm_mon) offset by +1 to account for the ANSI system of designating January=0, February=1, . . . December=11. Thus, with the +1 offset, January is the first month (i.e., January=1), February is the second month, (i.e., February=2), etc. Similarly, year variable (nYear) is not assigned the value provided for by the local system. Rather, nYear is assigned the local system year variable (tm_year) offset by +1900 to account for the computer system 10 designating year 1900 as year 0, 1901 as year 1, and so on. For example, representing the year 1945 requires the system output (tm_year=45) to be offset by 1900 such that nYear=1945. The DKDate constructor based on current system time utilizes a number of definitions and functions which will be described in further programming detail including time_t and struct tm definitions (and related CRTIMP definition) and the localtime function (and related_cdecl and MSC_VER and definitions). 2.A.2.a DKDate Constructor With Current System Time-time_t Definition The definition time_t is a long, signed integer representation of time data and is defined by the following:
/* Define the implementation defined time type */
#ifndef_TIME_T_DEFINED
typedef long time_t; /* time value*/
*define_TIME_T_DEFINED /* avoid multiple definitions of time_t */
#endif
#ifndef_CLOCK_T_DEFINED
typedef long clock_t;
#define_CLOCK_T_DEFINED
#endif
#ifndef_SIZE_T_DEFINED
typedef unsigned int size_t;
#define_SIZE_T_DEFINED
#endif
2.A.2.b. DKDate Constructor With Current System Time-struct tm Definition The struct tm definition is the structural form of the time structure "tm" and is defined by the following:
#ifndef_TM_DEFINED
struct tm {
int tm_sec; /* seconds after the minute - [0, 59] */
int tm_min; /* minutes after the hour - [0, 59]*/
int tm_hour; /* hours since midnight - [0, 23]*/
int tm_mday; /* day of the month - [1, 31]*/
int tm_mon; /* months since January - [0, 11]*/
int tm_year; /* years since 1900*/
int tm_wday; /* days since Sunday [0, 6]*/
int tm_yday; /* days since January 1 - [0, 365]*/
int tm_isdst /* daylight savings time flag*/
}
#define_TM_DEFINED
#endif
/*Clock ticks macro - ANSI version */
#define CLOCKS_PER_SEC 1000
/* Extern declarations for the global variables used by the CTime family
of routines. */
/* non-zero it daylight savings time is used */
_CRTIMP extem int_daylight;
/* offset for Daylight Saving Time */
_CRTIMP extern long_dstbias;
/*difference in seconds between GMT and local time */
_CRTIMP extem long_timezone;
/* standard/daylight savings time zone names */
_CRTIMP extern char * _tzname[2];
2.A.2.c. DKDate Constructor With Current System Time-_CRTIMP Definition The_CRTIMP definition within the struct tm definition of the DKDate constructor based on current system time is implemented by the following:
#ifndef _CRTIMP
#ifdef _DLL
#define _CRTIMP_declspec (dllimport)
#else /* ndef_DLL */
#define _CRTIMP
#endif /* _DLL */
#endif /* _CRTIMP */
2.A.2.d. DKDate Constructor With Current System Time-localtime Function The localtime function of the current system DKDate constructor is implemented by the following:
/* Function prototypes */
_CRTIMP char * _cdecl asctime (const struct tm *);
_CRTIMP char * _cdecl ctime (const time_t *);
_CRTIMP clock_t_cdecl clock (void);
_CRTIMP double_cdecl difftime (time_t, time_t);
_CRTIMP struct tm * _cdecl gmtime (const time_t *);
_CRTIMP struct tm * _cdecl localtime (const time_t *);
_CRTIMP time_t_cdecl mktime (struct tm *);
_CRTIMP size_t_cdecl strftime (char * size_t const char *, const
struct tm *);
_CRTIMP char * _cdecl_strdate (char *);
_CRTIMP char * _cdecl_strtime (char *);
_CRTIMP time_t_cdecl time (time_t *);
#ifdef _POSIX_
_CRTIMP void_cdecl tzset (void);
#else
_CRTIMP void_cdecl_tzset(void);
#endif
/* --------- The following functions are OBSOLETE ---------*/
/* The Win32 API GetLocalTime, and SetLocalTime should be used
instead. */
unsigned_cdecl_getsystime (struct tm *);
unsigned_cdecl_setsystime (struct tm *, unsigned);
/* --------- The preceding functions are OBSOLETE ---------*/
#ifndef_SIZE_T_DEFINED
typedef unsigned int size_t;
#define_SIZE_T_DEFNED
#endif
#ifndef_MAC
#ifndef_WTIME_DEFINED
/* wide function prototypes, also declared in wchar.h */
_CRTIMP wchar_t * _cdecl_wasctime (const struct tm *);
_CRTIMP wchar_t * _cdecl_wctime (const time_t *);
_CRTIMP size_t_cdecl wcsftime (wchar_t *, size_t, const
wchar_t*, const struct tm *);
_CRTIMP wchar_t * _cdecl_wstrdate (wchar_t *);
_CRTIMP wchar_t* _cdecl_wstrtime(wchar_t *);
#define_WTIME_DEFINED
#endif
#endif /* ndef _MAC */
#if !_STDC_ .parallel.defined (_POSIX_)
/* Non-ANSI names for compatibility */
#define CLK_TCK CLOCKS_PER_SEC
_CRTIMP extern int daylight;
_CRTIMP extern long timezone;
_CRTIMP extern char * tzname [2];
_CRTIMP void _cdecl tzset (void);
#endif / * _STDC_ */
#ifdef_cplusplus
#ifdef _MSC_VER
}
#endif
#ifdef_MSC_VER
#pragma pack (pop)
#endif /* _MSC_VER */
#endif /* _INC_TIME */
2.A.2.e. DKDate Constructor With Current System Time-_cdecl Definition The localtime function of DKDate constructors based on current system time utilizes the _cdecl definition if non Microsoft compilers are used. The _cdecl definition is implemented by the following:
#if ( !defined (_MSC_VER) && !defined (_cdecl))
#define_cdecl
#endif
2.A.3. DKDate Get Methods In addition, the DKDate class provides three get methods for year, month, and day data which are utilized when generating objects from classes via the constructors. These get methods are defined as the following:
int DKDate::getYear ( ) const
{
return (_t.GetYear ( ) + _diff);
}
int DKDate::getMonth ( ) const { return_t.GetMonth ( ); }
int DKDate::getDay ( ) const { return_t.GetDay ( ); }
2.B. DKTimestamp Constructors Similarly, a DKTimestamp object is generated from the DKTimestamp class via a DKTimestamp constructor (block 120). When the DKTimestamp wrapper class is instantiated, a DKTimestamp object generated from the DKTimestamp wrapper class determines a base year corresponding to a target year. The CTime object_t represents the base year and the offset value _diff as the difference between the base year and the target year when the class is instantiated. DKTimestamp objects may be generated from two different DKDTimestamp constructors. The first DKTimestamp constructor implements a DKTimestamp object with year, month, day, minute, second, and nanosecond data whereas the second DKTimestamp constructor implements a DKTimestamp object with current system time. 2.B.1. DKTimestamp Constructor With Year Month, Day, Hour, Minute, Second, and Nanosecond The first DKTimestamp constructor provides a DKTimestamp object with year, month, day, hour, minute, second, and nanosecond data. Ths DKTimestamp constructor is implemented by the following:
DKTimestamp::DKTimestamp ( int nYear, int nMonth, int nDay,
int nHour, int nMin, int nSec, int nNano, int DST)
{
_diff = 0
if(nYear > 2037)
{
_diff = (nYear - 2037);
_t = CTime (2037, nMonth, nDay, nHour, nMin, nSec, DST);
}
else if (nYear < 1970)
{
_diff = (nYear - 1970);
_t = CTime (1970, nMonth, nDay, nHour, aMin, nSec, DST);
}
else
{
_diff = (0);
_t = CTime (nYear, nMonth, nDay, nHour, nMin, nSec, DST);
}
_nanos = nNano;
}
2.B.2. DKTimestamp Constructor With Current System Time The second type of DKTimestamp constructor generates DKTimestamp objects from the DKTimestamp class utilizing current system time. Current system time may be identified in a parameter that is retrieved from the computer 10, system clock 22, program 33, or some other source. This constructor is implemented by the following:
DKTimestamp::DKTimestamp ( )
{
time_t _time;
time_t* pTime = &_time;
struct tm temp;
struct tm * pTemp = &temp;
_time = time ((time_t*)NULL);
pTemp = localtime (pTime);
int nSec = pTemp->tm_sec;
int nMin = pTemp->tm_min;
int nHour = pTemp->tm_hour;
int nDay = pTemp->tm_mday;
int nMon = pTemp->tm_mon + 1;
int nYear = pTemp->tm_year + 1900;
_diff = 0;
if (nYear > 2037)
{
_diff = (nYear - 2037);
_t = CTime (2037, nMon, nDay, nHour, nMin, nSec, -1);
}
else if (nYear < 1970)
{
_diff = (nYear - 1970);
_t = CTime (1970, nMon, nDay, nHour, nMin, nSec, -1);
}
else
{
_diff = (0);
_t = CTime (nYear, nMon, nDay, nHour, nMin, nSec, -1);
}
_nanos = 0;
}
Similar to the DKDate constructor based on current system time, the DKTimestamp constructor based on current system time does not require a user to input year, month, and day parameters. Rather, as the first line "DKTimestamp::DKTimestamp( )" illustrates, there are no input parameters. The time data is retrieved from the localtime function which queries a local system or server. The time_t and struct tm definitions, localtime function, and related definitions described in paragraphs 2.A.2.A to 2.A.2.E. with respect to the DKDate constructor based on current system time are also utilized in the DKTimestamp constructor utilizing current system time. The DKTimestamp constructor utilizing current system time creates a DKTimestamp object with year, month, day, hour, minute, and second data. The second, minute, hour, and day variables (nSec, nMin, nHour, and nDay) are assigned the values provided for by the local system or server (tm_sec, tm_min, tm_hour, and tm_mday). Similar to the month and year offsets used with the current system time DKDate constructor, nMon is assigned the system month variable (tm_mon) offset by +1 such that the month variable nMon is based on January=1, February=2, and so on. Similarly, the year variable nYear is assigned local system year variable (tm_year) offset by +1900 to account for the computer system 10 designating year 1900 as year 0, 1901 as year 1, etc. Thus, the system output tm_year=45 offset by 1900 results in nYear=1945. 2.B.3. DKTitnesatrnp Get Methods DKTimestamp also provides seven get methods (getyear, getmonth, getfday, gethours, getMinutes, getSeconds, and getnanos) to retrieve values for the converted year, month, day, hour, minutes, second, and nanosecond for the DKTimestarnp object. These get methods are defmed as the following:
int DKTimestamp::getYear ( ) const
{
return (_t.GetYear ( ) + _diff);
}
int DKTimestamp::getMonth ( ) const { return_t.GetMonth ( );}
int DKTimestamp::getDay ( ) const { return_t.GetDay ( );}
int DKTimestamp::getHours ( ) const { return_t.GetHour ( );}
int DKTimestamp::getMinutes ( ) const { return_t.GetMinute ( );}
int DKTimestamp::getSeconds ( ) const { return_t.GetSecond ( );}
int DKTimestamp::getNanos ( ) const { return_nanos;}
3. Invoking Conversion Object Referring to FIG. 2, the conversion object is invoked (block 130) after the time class has been encapsulated by the wrapper class (block 110) and a conversion object has been generated (block 120). Invoking the conversion object (block 130) initiates the date conversion process. Both DKDate and DKTimnestamp conversion objects identify a target year (block 140), convert the target year to a base year and offset (block 150), store the base year and offset (block 160), execute the application program (block 170), and convert the base year and offset back to the target year (block 180). 4. Identifying Target Year Referring to FIGS. 2 and 3, the target year (i.e, the year in which the application program 37 should execute) is then identified (block 140). Referring to FIG. 3, the target year is read by wrapper object generated by the wrapper class 39 to determine whether the target year falls within the range of years 1 to 9999 (block 142). If the target year is outside of the range of years 1 to 9999, the conversion program 39 can not execute and the program 39 terninates. Ifthe target year is within the range of years 1 to 9999, then the target year is inputted into the conversion object (block 144). After the target year is inputted into the conversion object (block 144), the target year is converted to a base year and a resulting offset (block 150). 5. Converting Target Year to Base Year and Resulting Offset Referring to FIGS. 2 and 4, the target year may be converted to a base year and a resulting offset depending on whether the target year falls between the years 1 to 1969, 1970 to 2037 inclusively, or 2038 to 9999 (block 150). If the target year is less than 1970, i.e., from years 1 to 1969 (block 152a), then the base year is assigned a value of 1970 (block 154a). If the target year is between 1970 and 2037 inclusively (block 152b), then the base year is assigned the same value as the target year (block 154b). If the target year is greater than 2037, i.e., from 2038 to 9999 (152c) then the base year is assigned a value of 2037 (block 154c). The value of the offset depends on the base year and target year since the offset is calculated as (Target Year-Base Year). If the target year is less than 1970 (152a) such that the base year equals 1970 (block 154a) then the resulting offset is a negative number (block 156a). If the target year is between 1970 and 2037 inclusively (block 152b) such that the base year equals the target year (block 154b), then the resulting offset is zero (block 156b). If the target year is greater than 2037 (block 152c) such that the base year equals 2037 (block 154c) then the resulting offset is a positive number (block 156c). The following table summarizes the rules used in the wrapper class 39 to determine the values of base year and offset based on the target year:
Base Year
Target Year (TY) (BY) Offset Offset (+/-)
1 .ltoreq. TY < 1970 BY = 1970 Offset = TY - BY Negative
1970 .ltoreq. TY .ltoreq. 2037 BY = TY Offset = TY - BY = Zero
TY - TY
2037 < TY .ltoreq. 9999 BY = 2037 Offset = TY - BY Positive
For example, year 3000 is represented as base year 2037 plus an offset of 963 since 3000 is greater than 2037. Year 1930 is represented as base year 1970 plus an offset of -40 since 1930 is less than 1970. Year 1999 is represented as base year 1999 plus an offset of zero since 1999 is between 1970 and 2037. Further, it is apparent to one skilled in the art that other similar base plus offset approaches or similar mathematical operations may be performed to achieve the same results. Namely, a base year can be assigned a particular value and a series of mathematical operations can result in an offset, added to the base value, equals a target year. 6. Storing Base Year and Offset Values Referring to FIGS. 2 and 5, the base year and offset are stored in memory (block 160) after the target year has been converted to a base year and offset (block 150). More specifically, both the base year and offset values are read from the conversion object (block 162). The base year is then stored as part of a CTime object (block 164a) whereas the offset is cached as an integer or data member in the wrapper class (block 164b). 7. Executing Application Program With Target Year Referring to FIG. 2, the application program 37 receives the target year and is executed with the target year (block 170). The application program 37 invokes the wrapper class 39 and provides the target year to the wrapper class 39. The wrapper class 39 identifies the target year, determines a base year and resulting offset, and the application program 37 is executed with the target year. Only the wrapper class 39 has access to the base year and offset; the application program 37 and user are unaware that the wrapper class 39 has created a base year and offset. Rather, the wrapper class 39 returns the appropriate year data to the application program 37 to enable the application 37 to execute outside the range of 1970 to 2037 inclusively while the application 37 continues to generate output data to the user. In another example, the application program 37 does not receive the target year from user input. Rather, the application program 37 executes with a target year provided by a data file 34 managed by the application program 37. For example, the wrapper class 39 may receive the target year from files 34 retrieved from database or World Wide Web (WWW) searches. The following illustrates one use of the wrapper classes 39. If a user attempts to download a web page 34 retrieved from a WWW search and this web page 34 includes a timestamp outside of the range of 1970 to 2037 inclusively, the user will not be able to view the search results. While the actual search locating the particular web page 34 may be successfully executed, an application program 37 based on CTime 38 used to build or compile the web page 34 will crash because the timestamp is outside of the range of 1970 to 2037 inclusively. However, if the application program 37 calls the wrapper class 39 instead of CTime 38, the search will execute successfully and the user will be able to view the retrieved web page 34. The wrapper class 39 provides the application program 37 with the appropriate time-year data to enable the application 37 to compile database files and web pages 34 with timestamps ranging from years 1 to 9999 rather than within the limited range of years 1970 to 2037. 8. Converting Base Year and Offset Back to Target Year After executing, the application program 37 may need perform a process or generate a data file with the target year. In these situations, the target year can be correctly constructed from the base year and offset (block 180). The base year from the CTime object (block 182a), reading the offset from the DKDate or DKTimestamp conversion class (block 182b), and adding the base year and offset together (block 184). The target year may then be provided to the application for appropriate processing (block 186). 9. Example C++ Program Demonstrating Execution of Conversion Classes After the forgoing detailed description of how various C++ program elements, classes, objects and variables are created, stored, and utilized to convert dates within object-oriented applications, the following C++ program and resulting output illustrate how these elements work together to solve the year 2038 bug of MFC-based applications utilizing CTime 38:
// Test program for DKDate and DKTimestamp
/*
* Filename : Test cpp
* Description : Test the DKDate and DKTimestamp classes
*
*/
#include <iostream.h>
#include <stdio.h>
#include <DKConstant.h>
#include <DKDatastoreDL.hpp>
#include <DKAccessControlDL.hpp>
#include <DKException.hpp>
#include <DKString.hpp>
#include <DKEnvironment.hpp>
#include <DKDate.hpp>
void main(int argc, char *argv [ ])
{
cout << "begin . . . " << end;
DKEnvironment::setSubSystem(DK_SS_CONSOLE);
try {
cout << "testing . . . " << endl;
DKDate t = DKDate (2038, 1, 18);
cout << ">>>>> DKDate (2038, 1,
18)"<<endl;
cout << " Year = " << t.getYear ( )
<< " Month = " << t.getMonth ( )
<< " Day = " << t.getDay( )
<< " - - " << t.asString("%Y-%m-%d")
<< endl;
t = DKDate (2038, 1, 19);
cout << ">>>>> DKDate (2038, 1, 19)
"<< endl;
cout << " Year = " << t.getYear ( )
<< " Month = " << t.getMonth ( )
<< " Day = " << t.getDay ( )
<< " - - " << t.asString ("%Y-%m-%d")
<< endl;
t = DKDate (1970, 1, 1);
cout << ">>>>> DKDate (1970, 1,
1)"<< endl;
cout << " Year = " << t.getYear ( )
<< " Month = " << t.getMonth ( )
<< " Day = " << t.getDay ( )
<< " - - " << t.asString ("%Y-%m-%d")
<< endl;
t = DKDate (1969, 12, 31);
cout << ">>>>> DKDate (1969, 12,
31)"<< endl;
cout << "Year = " << t.getYear ( )
<< " Month = " << t.getMonth ( )
<< " Day = " << t.getDay ( )
<< " - - " << t.asString ("%Y-%m-%d")
<< endl;
t = DKDate(3999, 1, 1);
cout << ">>>>> DKDate (3999, 1,
1)"<< endl;
cout << " Year = " << t.getYear ( )
<< " Month = " << t.getMonth ( )
<< " Day = " << t.getDay ( )
<< " - - " <<t.asString ("%Y-%m-%d")
<< endl;
t = DKDate( )
cout << ">>>>> DKDate( )"<<endl;
cout << " Year = " << t.getYear ( )
<< " Month = " << t.getMonth ( )
<< " Day = " << t.getDay( ),
<< " - - " << t.asString ("%Y-%m-%d")
<< endl;
DKTimestamp ts = DKTimestamp (1900, 1, 1, 10, 30, 59, 200, -1);
cout << ">>>>> DKTimestamp (1900, 1, 1,
10, 30, 59, 200, -1)" <<
endl;
cout << " Year = " << ts.getYear ( )
<< " Month = " << ts.getMonth ( )
<< " Day = " << ts.getDay( )
<< " Hours = " << ts.getHours ( )
<< " Minutes = " << ts.getMinutes ( )
<< " Seconds = " << ts.getSeconds ( )
<< " Nanos = " << ts.getNanos ( )
<< endl;
ts = DKTimestamp (1960, 8, 27, 10, 30, 59, 200, -1);
cout << ">>>>> DKTimestamp (1960, 8, 27,
10, 30, 59, 200,-1)" <<
endl;
cout << "Year = " << ts.getYear ( )
<< " Month = " << ts.getMonth ( )
<< " Day = " << ts.getDay( )
<< " Hours = " << ts.getHours( )
<< " Minutes = " << ts.getMinutes ( )
<< " Seconds = " << ts.getSeconds ( )
<< " Nanos = " << ts.getNanos ( )
<< endl;
ts = DKTimestamp (1999, 8, 27, 10, 30, 59, 200, -1);
cout << ">>>>> DKTimestamp (1999, 8, 27,
10, 30, 59, 200, 1)"<<
endl;
cout << " Year = " << ts.getYear ( )
<< " Month = " << ts.getMonth ( )
<< " Day = " << ts.getDay ( )
<< " Hours = " << ts.getHours ( )
<< " Minutes = " << ts.getMinutes ( )
<< " Seconds = " << ts.getSeconds ( )
<< " Nanos = " << ts.getNanos ( )
<< endl;
ts DKTimestamp (2999, 8, 27, 10, 30, 59, 200, -1);
cout << ">>>>> DKTimestamp (2999, 8, 27,
10, 30, 59, 200, -1)" <<
endl;
cout << "Year = "<< ts.getYear ( )
<< " Month = "<< ts.getMonth ( )
<< " Day = " << ts.getDay ( )
<< " Hours = " << ts.getHours ( )
<< " Minutes = " << ts.getMinutes ( )
<< " Seconds = " << ts.getSeconds ( )
<< " Nanos = "<< ts.getNanos ( )
<< endl;
ts = DKTimestamp( );
cout << ">>>>> DKTimestamp( )" <<
endl;
cout << "Year = " << ts.getYear ( )
<< " Month = " << ts.getMonth ( )
<< " Day = " << ts.getDay ( )
<< " Hours = " << ts.getHours ( )
<< " Minutes = " << ts.getMinutes ( )
<< " Seconds = " << ts.getSeconds ( )
<< " Nanos = "<< ts.getNanos ( )
<< endl;
cout << "end of testing" << endl;
}
catch (DKException &exc)
{
cout << "Error id" << exc.errorId( ) << endl;
for (unsigned long i = 0; i< exc.textCount( );i++)
{
cout << "Error text: " << exc.text(i) <<
endl;
}
for (unsigned long g=0; g<exc.locationCount( );g++)
{
const DKExceptionLocation* p = exc.locationAtIndex(g);
cout << "Filename: " << p->fileName( ) <<
endl;
cout << "Function: " << p->functionName( )
<< endl;
cout << "LineNumber: " << p->lineNumber( )
<< endl;
}
cout << "Exception Class Name: " << exc.name( )
<< endl;
}
cout << "done . . . " << endl;
}
10. Output of Sample C++ Program The output of the sample C++ program demonstrates that the DKDate and DKTimestamp classes convert dates outside the range of Jan. 1, 1970 and Jan. 18, 2038 while utilizing classes with predefined time variables, current system time data, or user supplied data The output generated by the program is the following:
begin . . .
testing . . .
>>>>> DKDate (2038, 1, 18)
Year = 2038 Month = 1 Day = 18 - - 2038-01-18
>>>>> DKDate (2038, 1, 19)
Year = 2038 Month = 1 Day = 19 - - 2038-01-19
>>>>> DKDate (1970, 1, 1)
Year = 1970 Month = 1 Day = 1 - - 1970-01-01
>>>>> DKDate (1969, 12, 31)
Year = 1969 Month = 12 Day 31 - - 1969-12-31
>>>>> DKDate (3999, 1, 1)
Year 3999 Month = 1 Day = 1 - - 3999-01-01
>>>>> DKDate ( )
Year = 1999 Month = 9 Day = 1 - - 1999-09-01
>>>>> DKTimestamp (1900, 1, 1, 10, 30, 59, 200, -1)
Year = 1900 Month = 1 Day = 1 Hours = 10 Minutes = 30 Seconds 59 Nanos =
200
>>>>> DKTimestamp (1960, 8, 27, 10, 30, 59, 200, -1)
Year = 1960 Month = 8 Day = 27 Hours!= 10 Minutes = 30 Seconds 59 Nanos =
200
>>>>> DKTimestamp (1999, 8, 27, 10, 30, 59, 200, -1)
Year = 1999 Month = 8 Day = 27 Hours = 10 Minutes = 30 Seconds 59 Nanos =
200
>>>>> DKTimestamp (2999, 8, 27, 10, 30, 59, 200, -1)
Year = 2999 Month = 8 Day = 27 Hours 10 Minutes = 30 Seconds 59 Nanos = 200
>>>>> DKTimestamp ( )
Year = 1999 Month = 9 Day = 1 Hours = 11 Minutes = 46 Seconds 11 Nanos = 0
end of testing
done . . .
As the program output illustrates, the dates that would have caused the application program 37 to fail, namely, those before Jan. 1, 1970 and those after Jan. 18, 2038 are properly converted with the conversion classes 39 to enable the application 37 to execute. CONCLUSION This concludes the description of the preferred embodiment of the invention. The following describes some alternative embodiments for accomplishing the present invention. For example, any type of computer, such as a maintrame, minicomputer, or personal computer, or computer configuration, such as a timesharing mainframe, local area network, or standalone personal computer, could be used with the present invention. Additionally it will be understood that the object-oriented framework for providing access control can be used to provide access control to various types of multimedia datastores, and is not limited to a digital library. It will also be understood that the functions and methods described in the sample classes above can be varied and modified as necessary without departing from the present invention. The foregoing description of the preferred embodiment of the invention has been presented for the purposes of illustration and description. It is not intended to be exhaustive or to limit the invention to the precise form disclosed. Many modifications and variations are possible in light of the above teaching. It is intended that the scope of the invention be limited not by this detailed description, but rather by the claims appended hereto.
|
Same subclass Same class Consider this |
||||||||||
