The Date type encodes a date/time as J.D. - 2,400,000.5,
 where J.D. = 0 represents Jan 1, 4713 B.C. at Greenwich noon.
 For example, Greenwich 00:00 Jan 1, 1970 is M.J.D. 40587.0.
 
    struct Date
    {
        double dateValue;
    };
    
This type provides millsecond resolution for dates at least 10,000 years either side of the base value (MJD = 0.0).
Note: a struct is used because it allows overloaded methods to be defined in C++ and Java for date manipulation.
 The Time type encodes a time with nanosecond
 resolution. The encoded value timeValue is equivalent
 to Date's dateValue, but only the fractional part of
 timeValue is understood to have significance.
 The integral part should be zero, since any significant digits in
 the integral part reduce the precision of the time value.
 
    struct Time
    {
        double timeValue;
    };
    
Note: a struct is used because it allows overloaded methods to be defined in C++ and Java for time manipulation.
 The Timestamp type encodes a date/time with nanosecond
 resolution. The encoded value dateValue + timeValue is equivalent
 to Date's dateValue, but allows for nanosecond resolution.
 To ensure no loss of significance, dateValue must be
 integral (may be negative) and 0 <= timeValue < 1.
 
    struct Timestamp
    {
        double dateValue;
        double timeValue;
    };
    
This type provides nanosecond resolution for dates at least 100,000,000,000 years either side of the base value (MJD = 0.0).